Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сегодня все большую популярность приобретает.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
270.85 Кб
Скачать

Основные возможности

Итак, что же здесь есть? Как и в JUnit 4 тесты описываются с помощью аннотаций, также поддерживаются тесты, написанные на JUnit 3. Есть возможность вместо аннотаций использовать доклет. Для начала рассмотрим иерархию тестов. Все тесты принадлежат к какой-либо последовательности тестов(сюите), включают в себя некоторое количество классов, каждый из которых может состоять из нескольких тестовых методов. При этом классы и тестовые методы могут принадлежать к определенной группе. Наглядно это выглядит так:

+- suite/

+- test0/

| +- class0/

| | +- method0(integration group)/

| | +- method1(functional group)/

| | +- method2/

| +- class1

| +- method3(optional group)/

+- test1/

+- class3(optional group, integration group)/

+- method4/

У каждого участника этой иерархии могут иметься before и after конфигураторы. Запускается это все в таком порядке:

+- before suite/

+- before group/

+- before test/

+- before class/

+- before method/

+- test/

+- after method/

...

+- after class/

...

+- after test/

...

+- after group/

...

+- after suite/

Теперь поподробнее о самих тестах. Рассмотрим пример. Утилита для работы с локалями, умеет парсить из строки, а также искать кандидаты(en_US -> en_US, en, root):

public abstract class LocaleUtils {

/**

* Root locale fix for java 1.5

*/

public static final Locale ROOT_LOCALE = new Locale("");

private static final String LOCALE_SEPARATOR = "_";

public static Locale parseLocale(final String value) {

if (value != null) {

final StringTokenizer tokens = new StringTokenizer(value, LOCALE_SEPARATOR);

final String language = tokens.hasMoreTokens() ? tokens.nextToken() : "";

final String country = tokens.hasMoreTokens() ? tokens.nextToken() : "";

String variant = "";

String sep = "";

while (tokens.hasMoreTokens()) {

variant += sep + tokens.nextToken();

sep = LOCALE_SEPARATOR;

}

return new Locale(language, country, variant);

}

return null;

}

public static List<Locale> getCandidateLocales(final Locale locale) {

final List<Locale> locales = new ArrayList<Locale>();

if (locale != null) {

final String language = locale.getLanguage();

final String country = locale.getCountry();

final String variant = locale.getVariant();

if (variant.length() > 0) {

locales.add(locale);

}

if (country.length() > 0) {

locales.add((locales.size() == 0) ? locale : new Locale(language, country));

}

if (language.length() > 0) {

locales.add((locales.size() == 0) ? locale : new Locale(language));

}

}

locales.add(ROOT_LOCALE);

return locales;

}

}

Напишем к ней тест в стиле JUnit-a(не стоит рассматривать данный пример как руководство к написанию тестов на TestNG):

public class LocaleUtilsOldStyleTest extends Assert {

private final Map<String, Locale> parseLocaleData = new HashMap<String, Locale>();

@BeforeClass

private void setUp() {

parseLocaleData.put(null, null);

parseLocaleData.put("", LocaleUtils.ROOT_LOCALE);

parseLocaleData.put("en", Locale.ENGLISH);

parseLocaleData.put("en_US", Locale.US);

parseLocaleData.put("en_GB", Locale.UK);

parseLocaleData.put("ru", new Locale("ru"));

parseLocaleData.put("ru_RU_xxx", new Locale("ru", "RU", "xxx"));

}

@AfterTest

void tearDown() {

parseLocaleData.clear();

}

@Test

public void testParseLocale() {

for (Map.Entry<String, Locale> entry : parseLocaleData.entrySet()) {

final Locale actual = LocaleUtils.parseLocale(entry.getKey());

final Locale expected = entry.getValue();

assertEquals(actual, expected);

}

}

}

Что здесь есть?

  • Аннотации @BeforeSuite@AfterSuite обозначают методы, которые исполняются единожды до/после исполнения всех тестов. Здесь удобно располагать какие-либо тяжелые настройки общие для всех тестов, например, здесь можно создать пул соединений с базой данных.

  • Аннотации @BeforeTest@AfterTest обозначают методы, которые исполняются единожды до/после исполнения теста(тот, который включает в себя тестовые классы, не путать с тестовыми методами). Здесь можно хранить настройки какой-либо группы взаимосвязанных сервисов, либо одного сервиса, если он тестируется несколькими тест-классами.

  • Аннотации @BeforeClass@AfterClass обозначают методы, которые исполняются единожды до/после исполнения всех тестов в классе, идентичны предыдущим, но применимы к тест-классам. Наиболее применим для тестирования какого-то определенного сервиса, который не меняет свое состояние в результате теста.

  • Аннотации @BeforeMethod@AfterMethod обозначают методы, которые исполняются каждый раз до/после исполнения тестового метода. Здесь удобно хранить настройки для определенного бина или сервиса, если он не меняет свое состояние в результате теста.

  • Аннотации @BeforeGroups@AfterGroups обозначает методы, которые исполняются до/после первого/последнего теста принадлежащего к заданным группам.

  • Аннотация Test обозначает сами тесты. Здесь размещаются проверки. Также применима к классам

У всех этих аннотаций есть следующие параметры:

  • enabled — можно временно отключить, установив значение в false

  • groups — обозначает, для каких групп будет исполнен

  • inheritGroups — если true(а по умолчанию именно так), метод будет наследовать группы от тест-класса

  • timeOut — время, после которого метод «свалится» и потянет за собой все зависимые от него тесты

  • description — название, используемое в отчете

  • dependsOnMethods — методы, от которых зависит, сначала будут выполнены они, а затем данный метод

  • dependsOnGroups — группы, от которых зависит

  • alwaysRun — если установить в true, будет вызываться всегда независимо от того, к каким группам принадлежит, не применим к @BeforeGroups@AfterGroups

Как видно из примера тест практически ничем не отличается от такого же теста на JUnit. Если нет разницы, то зачем использовать TestNG?