Статьи

Испытание на магическое тестирование: часть 2

Моя последняя статья вызвала интересную дискуссию о том, следует ли вам рассматривать тесты больше как документацию или больше как спецификацию Я согласен, что они могут помочь им обоим, но я все еще думаю, что тесты — это просто тесты …

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

Поэтому я поставил еще одну небольшую задачу, чтобы показать, как визуальный подход, предлагаемый MagicTest, помогает облегчить тестирование. Как вы знаете, традиционные тестовые среды, основанные на утверждениях, такие как TestNG или JUnit, заставляют нас включать ожидаемые результаты в код теста. Там, где это может быть более или менее подходящим для простых тестов (как в предыдущей статье), это быстро становится громоздким, если тест обрабатывает сложные объекты или объемные данные.

Задание

Мы должны протестировать метод createEvenOddTable () (см. Добавленный список ) со следующей функциональностью:

  • Создать таблицу HTML (таблица элементов, tr, td) с указанным количеством строк данных и столбцов.

  • Дополнительная строка будет добавлена ​​для хранения информации заголовка (элемент th).

  • Будет добавлен дополнительный столбец, который содержит номер строки (элемент th)

  • Строки будут иметь класс атрибута, установленный в «head», «even» или «odd» для легкого моделирования.

Как спецификация (4 строки выше), так и сам исходный код (25 строк) являются короткими и простыми для понимания, поэтому любой опытный разработчик напишет этот метод через несколько минут. Так в чем же проблема с тестированием этого метода? Посмотрим, посмотрим, как MagicTest справится с этим делом.

Волшебный тест

MagicTest для этого метода выглядит следующим образом:

public class HtmlTableTest {

	@Trace
	public void testCreateEvenOddTable() {
	    HtmlTable.createEvenOddTable(4, 3);
	}

	@Formatter(outputType=OutputType.TEXT)
	public static String formatElement(Element elem) {
	    XMLOutputter serializer = new XMLOutputter();
	    serializer.setFormat(Format.getPrettyFormat());
	    return serializer.outputString(elem);
	}
}

Некоторые детали:

  • Мы используем аннотацию @Trace для автоматического сбора информации о вызовах тестируемого метода.

  • Мы полагаемся на соглашения об именах, поэтому метод HtmlTable.createEvenOddTable () проверяется методом HtmlTableTest.testCreateEvenOddTable ().

  • По умолчанию MagicTest использует метод toString () для отчета о параметре и возвращаемых значениях. Поскольку метод Element toString () возвращает только его имя, мы должны определить пользовательский @Formatter, чтобы получить полное дерево XML.

Если мы запустим тест, мы получим следующий отчет:

Если мы посмотрим на дерево элементов XML в отчете, то увидим все детали, которые должен охватывать полный тест: правильное вложение элементов (таблица, tr, td), правильная строка заголовка, правильные номера строк, правильное количество строк, правильное количество ячеек для каждой строки, правильный атрибут класса для каждой строки и т. д.

Но даже если вы в конечном итоге получите кучу длинных утверждений типа

	    assert("head".equals(((Element) elem.getChildren("tr").get(0)).getAttributeValue("class")));

для проверки правильности атрибута класса этого будет недостаточно: вам также следует проверить отсутствие атрибута класса для всех ячеек, кроме первых в каждой строке. Так что да, для звукового теста вы должны фактически проверить все дерево XML - и это именно та информация, которую MagicTest показывает вам для подтверждения.

Пусть вызов начнется

Чтобы запустить тест самостоятельно, вам нужно скачать плагин MagicTest Eclipse . Скопируйте его в папку dropins Eclipse и перезапустите Eclipse. Затем загрузите прикрепленный проект Eclipse и импортируйте его в рабочее пространство. Запустите тестовый класс TagsTest, выполнив Run As / MagicTest.

После первого запуска появится отчет о тестировании, и все этапы теста будут красного цвета. Это MagicTest способ сообщить вам, что шаг не удалось. В нашем случае шаги просто не выполняются, потому что MagicTest просто ничего не знает об ожидаемом результате. Поэтому мы тщательно проверяем вывод и подтверждаем его правильность, нажимая на кнопку «Сохранить». Теперь все шаги зеленые - и тест пройден успешно.

Теперь вы видели, насколько эффективно этот тест можно реализовать с помощью MagicTest - он даже выглядел забавно. Ваш тестовый инструмент принимает вызов? Сколько минут и строк нужно, чтобы написать тест? Я с нетерпением жду вашего вклада!

Приложение: Листинг HtmlTable

	/**
	 * Create HTML table (elements table, tr, td) with specified number of data rows and columns.
	 * An additional row will be added to store header information (element th).
	 * An additional column will be added which contains the row number (element th)
	 * The rows will have attribute class set to "head", "even", or "odd" for easy styling.
	 *
	 * @param rows	number of rows
	 * @param cols	number of column
	 * @return		XML element containing the HTML table
	 */
	public static Element createEvenOddTable(int rows, int cols) {
		Element table = new Element("table");
		for (int r=0; r<rows+1; r++) {
			Element tr = new Element("tr");
			table.addContent(tr);
			String trClass;
			if (r == 0) {
				trClass = "head";
			} else {
				trClass = (r%2==1) ? "even" : "odd";
			}
			tr.setAttribute("class", trClass);
			for (int c=0; c<cols+1; c++) {
				String tdElem;
				if (r == 0) {
					tdElem = "th";
				} else {
					tdElem = (c==0) ? "th" : "tr";
				}
				Element td = new Element(tdElem);
				tr.addContent(td);
				if (c == 0 && r > 0) {
					td.setText(Integer.toString(r));
				}
			}
		}
		return table;
	}