Управление циклами

Этот пример иллюстрирует управление циклами в тесте с помощью пользовательского кода. В коде показано, как управлять поведением циклов в тесте, чтобы анализировать и проверять результаты теста.

В этом примере используется запись транзакции покупки ресурса с помощью приложения IBM Trade. Иллюстрируемые концепции можно использовать в тестах других приложений.

Тест начинается с записи транзакции покупки ресурса, где ИД сеанса подставляется из пула данных.

Страницы помещены в цикл с пятью итерациями, как показано на рисунке:

Обратите внимание, что в тесте есть три фрагмента пользовательского кода (показаны зелеными кружками с буквой "C"). Следующий пример иллюстрирует эти фрагменты пользовательского кода.

Далее приведен первый фрагмент пользовательского кода, InitializeBuyTest:

package customcode;

import java.util.Random;

import com.ibm.rational.test.lt.kernel.IDataArea;
import com.ibm.rational.test.lt.kernel.services.ITestExecutionServices;
import com.ibm.rational.test.lt.kernel.services.IVirtualUserInfo;

/**
 * @author unknown
 */
public class InitializeBuyTest implements
		com.ibm.rational.test.lt.kernel.custom.ICustomCode2 {

	/**
	 * Экземпляры будут создаваться с помощью конструктора без аргументов.
	 */
	public InitializeBuyTest() {
	}

	/**
	 * Описание интерфейсов ICustomCode2 и ITestExecutionServices
	 * см. в Javadoc. */
	public String exec(ITestExecutionServices tes, String[] args) {
		// Получить область данных теста и установить флаг отсутствия
		// ошибки. Этот флаг используется далее для выхода из
		// цикла тестов в случае ошибки.
		IDataArea dataArea = tes.findDataArea(IDataArea.TEST);
		dataArea.put("failedYet", "false");

		// Получить область данных виртуальных пользователей
		IDataArea vda = tes.findDataArea(IDataArea.VIRTUALUSER);
		
		// Случайно выбрать ресурс для покупки из набора от s:0 до s:499.
	    IVirtualUserInfo vuInfo = (IVirtualUserInfo) vda.get(IVirtualUserInfo.KEY);
	    Random rand = vuInfo.getRandom();
		String stock = "s:" + Integer.toString(rand.nextInt(499));

		// Сохранить имя ресурса в области данных виртуального пользователя.
		vda.put("myStock", stock);

		return stock;
	}

Этот пользовательский код расположен в методе exec().

Сначала получается область данных для теста, в которой сохраняется флаг, в данном случае - строка, которая впоследствии позволяет остановить цикл при возникновении ошибки. Данные, сохраняемые таким способом, можно использовать в нескольких тестах.

Далее создается случайная строка ресурса. Ее значение сохраняется в переменной stock и используется как возвращаемое значение метода. Возвращаемое значение используется как подстановка для следующего запроса, как показано на рисунке:

Выделенный элемент использует подстановку (s%3A716), то есть значение, возвращенное фрагментом пользовательского кода InitializeBuyTest. Пользовательский код управляет выполнением теста.

В следующих строках кода в InitializeBuyTest используется область данных виртуального пользователя для сохранения имени ресурса на будущее. Опять же данные, сохраняемые таким способом, можно использовать в нескольких тестах.

Второй фрагмент пользовательского кода - это CheckStock. Его содержимое приведено ниже (только метод exec()):

public String exec(ITestExecutionServices tes, String[] args) {

		// Получить фактический и запрошенный приобретенный ресурс.
		String actualStock = args[0].replaceAll("<B>", "");
 		actualStock = actualStock.substring(0, actualStock.indexOf("<"));
		String requestedStock = args[1];

  		// Установить уровень протокола ALL.
 		IDataArea dataArea = tes.findDataArea(IDataArea.TEST);
 		ITestInfo testInfo = (ITestInfo)dataArea.get(ITestInfo.KEY);
 		testInfo.setTestLogLevel(ITestLogManager.ALL);

 		// Если уровень протокола равен ALL, Получить фактический и
		// запрошенный приобретенный ресурс.
 		ITestLogManager testLogManager = tes.getTestLogManager();
		if (testLogManager.wouldReport(ITestLogManager.ALL)) {
 			testLogManager.reportMessage("Actual stock purchased: "
 					+ actualStock + ". Requested stock: " + requestedStock
					+ ".");
 		}  		

		// Если фактический и запрошенный ресурс не совпадают, вернуть VERDICT_FAIL.
 		if (testLogManager.wouldReport(ITestLogManager.ALL)) {
			if (!actualStock.equalsIgnoreCase(requestedStock)) {
 				testLogManager.reportVerdict(
						"Actual and requested purchase stock do not match.",
 						VerdictEvent.VERDICT_FAIL);

 				// Записать в области данных сведения о том, что возникла
				// ошибка.
 				dataArea.put("failedYet", "true");
 			} 		
		}
  		return null;
	}

В начале кода извлекаются два аргумента, переданные в код. Часть ответа из исходной записи выделена и используется как ссылка, что показано на рисунке.

Для получения нужного текста строки обрабатываются, то есть получается имя фактически приобретенного ресурса. Затем созданная ссылка передается как аргумент в CheckStock, как показано на рисунке.

Обратите внимание, что возвращаемое значение InitializeBuyTest также передается как аргумент.

В фрагменте пользовательского кода CheckStock эти значения используются, чтобы проверить, что случайно выбранный ресурс, сгенерированный в InitializeBuyTest, фактически приобретен во время выполнения теста.

Далее CheckStock задает уровень протокола теста, сообщает о фактическом и запрошенном ресурсе и генерирует ошибку, если они не совпадают. CheckStock также сохраняет значение true, связанное с тегом failedYet, в области данных теста.

Далее приведен третий фрагмент пользовательского кода (только метод exec()):

public String exec(ITestExecutionServices tes, String[] args) {

		// Получить администратор протокола теста.
		ITestLogManager testLogManager = tes.getTestLogManager();
		
		// Получить область данных теста и проверить флаг
		// ошибки. Если он установлен, остановить цикл.
		IDataArea dataArea = tes.findDataArea(IDataArea.TEST);
		String failedYet = (String) dataArea.get("failedYet");

		// Прервать цикл, если возникла ошибка.
		if (failedYet.equalsIgnoreCase("true")) {
			tes.getLoopControl().breakLoop();

			if (testLogManager.wouldReport(ITestLogManager.ALL)) {
				testLogManager.reportMessage("Loop stopped.");
			}
		}

		return null;
	}

Этот код использует область данных теста, чтобы определить пользовательское значение, связанное с тегом failedYet. Если failedYet равен true, то StopLoopCheck прерывает цикл теста.


Комментарии