1. Обзор
В этой статье мы представим среду тестирования TestNG.
Мы сосредоточимся на: настройке фреймворка, написании простого тестового примера и конфигурации, выполнении теста, генерации отчетов о тестировании и одновременном выполнении теста.
2. Настроить
Давайте начнем с добавления зависимости Maven в наш файл pom.xml :
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.11</version>
<scope>test</scope>
</dependency>
Последнюю версию можно найти в Maven хранилище ,
При использовании Eclipse подключаемый модуль TestNG можно загрузить и установить с Eclipse Marketplace .
3. Написание теста
Чтобы написать тест с использованием TestNG, нам просто нужно аннотировать метод теста аннотацией org.testng.annotations.Test :
@Test
public void givenNumber__whenEven__thenTrue() {
assertTrue(number % 2 == 0);
}
4. Тестовые конфигурации
При написании тестовых случаев нам часто нужно выполнить некоторые инструкции по настройке или инициализации перед выполнением тестов, а также выполнить некоторую очистку после завершения тестов. TestNG предоставляет ряд функций инициализации и очистки на уровне методов, классов, групп и пакетов:
@BeforeClass
public void setup() {
number = 12;
}
@AfterClass
public void tearDown() {
number = 0;
}
Метод setup () , помеченный аннотациями @ BeforeClass , будет вызываться до выполнения любых методов этого тестового класса, а tearDown () - после выполнения всех методов тестового класса.
Аналогично, мы можем использовать аннотации @ BeforeMethod, @AfterMethod, @ Before/AfterGroup, @ Before/AfterTest и @ Before/AfterSuite для любой конфигурации на уровне метода, группы, теста и комплекта.
5. Выполнение теста
Мы можем запустить тестовые примеры с помощью команды Maven «test», она выполнит все тестовые примеры, помеченные @ Test , и поместит их в набор тестов по умолчанию. Мы также можем запускать тестовые случаи из файлов XML набора тестов TestNG, используя https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22% 20and% 20a% 3A% 22maven-безошибочный-плагин% 22[Maven-безошибочный-плагин]:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>
src\test\resources\test__suite.xml
</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
Обратите внимание, что если у нас есть несколько файлов XML, охватывающих все тестовые примеры, мы можем добавить их все в тег suiteXmlFiles :
<suiteXmlFiles>
<suiteXmlFile>
src/test/resources/parametrized__test.xml
</suiteXmlFile>
<suiteXmlFile>
src/test/resources/registration__test.xml
</suiteXmlFile>
</suiteXmlFiles>
Чтобы запустить тест самостоятельно, нам нужно иметь библиотеку TestNG в classpath и скомпилированный тестовый класс вместе с файлом конфигурации XML:
java org.testng.TestNG test__suite.xml
6. Группировка тестов
Тесты могут выполняться в группах, например, из 50 тестовых случаев 15 могут быть сгруппированы и выполнены, оставляя другие без изменений.
В TestNG групповые тесты в наборах выполняются с использованием файла XML:
<suite name="suite">
<test name="test suite">
<classes>
<class name="com.baeldung.RegistrationTest"/>
<class name="com.baeldung.SignInTest"/>
</classes>
</test>
</suite>
Обратите внимание, что оба тестовых класса RegistrationTest, SignInTest теперь принадлежат одному и тому же набору, и как только набор будет выполнен, будут выполнены тестовые примеры в этом классе.
Помимо тестовых наборов, мы также можем создавать тестовые группы в TestNG, где вместо тестовых классов методы группируются вместе. Для этого добавьте параметр groups в аннотацию @ Test :
@Test(groups = "regression")
public void givenNegativeNumber__sumLessthanZero__thenCorrect() {
int sum = numbers.stream().reduce(0, Integer::sum);
assertTrue(sum < 0);
}
Давайте использовать XML для выполнения групп:
<test name="test groups">
<groups>
<run>
<include name="regression"/>
</run>
</groups>
<classes>
<class
name="com.baeldung.SummationServiceTest"/>
</classes>
</test>
Это выполнит тестовый метод, помеченный группой regression, в классе SummationServiceTest .
7. Параметризованные тесты
Параметризованные модульные тесты используются для тестирования одного и того же кода при нескольких условиях. С помощью параметризованных модульных тестов мы можем настроить метод тестирования, который получает данные из некоторого источника данных. Основная идея состоит в том, чтобы сделать метод модульного тестирования многоразовым и проводить тестирование с другим набором входов.
В TestNG мы можем параметризовать тесты, используя аннотацию @ Parameter или @ DataProvider . При использовании файла XML аннотируйте метод теста с помощью @ Parameter:
@Test
@Parameters({"value", "isEven"})
public void
givenNumberFromXML__ifEvenCheckOK__thenCorrect(int value, boolean isEven) {
assertEquals(isEven, value % 2 == 0);
}
И предоставьте данные, используя файл XML:
<suite name="My test suite">
<test name="numbersXML">
<parameter name="value" value="1"/>
<parameter name="isEven" value="false"/>
<classes>
<class name="baeldung.com.ParametrizedTests"/>
</classes>
</test>
</suite>
Использование данных из XML-файла полезно, но нам часто нужны более сложные данные.
@ DataProvider аннотация используется для обработки этих сценариев, которые можно использовать для сопоставления сложных типов параметров для тестирования методов. @DataProvider для примитивных типов данных:
@DataProvider(name = "numbers")
public static Object[][]evenNumbers() {
return new Object[][]{{1, false}, {2, true}, {4, true}};
}
@Test(dataProvider = "numbers")
public void
givenNumberFromDataProvider__ifEvenCheckOK__thenCorrect(Integer number, boolean expected) {
assertEquals(expected, number % 2 == 0);
}
_ @ DataProvider _ для объектов:
@Test(dataProvider = "numbersObject")
public void
givenNumberObjectFromDataProvider__ifEvenCheckOK__thenCorrect(EvenNumber number) {
assertEquals(number.isEven(), number.getValue() % 2 == 0);
}
@DataProvider(name = "numbersObject")
public Object[][]parameterProvider() {
return new Object[][]{{new EvenNumber(1, false)},
{new EvenNumber(2, true)}, {new EvenNumber(4, true)}};
}
Используя это, любой объект, который должен быть проверен, может быть создан и использован в тесте. Это в основном полезно для интеграционных тестов.
8. Игнорирование тестовых случаев
Иногда мы хотим не выполнять определенный тестовый пример, временно в процессе разработки. Это можно сделать, добавив enabled = false, в аннотацию @ Test :
@Test(enabled=false)
public void givenNumbers__sumEquals__thenCorrect() {
int sum = numbers.stream.reduce(0, Integer::sum);
assertEquals(6, sum);
}
9. Зависимые тесты
Давайте рассмотрим сценарий, в котором, если первоначальный тестовый набор не пройден, все последующие тестовые примеры должны быть выполнены, а скорее помечены как пропущенные TestNG предоставляет эту функцию с параметром dependsOnMethods аннотации @ Test :
@Test
public void givenEmail__ifValid__thenTrue() {
boolean valid = email.contains("@");
assertEquals(valid, true);
}
@Test(dependsOnMethods = {"givenEmail__ifValid__thenTrue"})
public void givenValidEmail__whenLoggedIn__thenTrue() {
LOGGER.info("Email {} valid >> logging in", email);
}
Обратите внимание, что контрольный пример входа в систему зависит от контрольного теста проверки электронной почты. Таким образом, если проверка электронной почты не пройдена, проверка входа будет пропущена.
10. Параллельное выполнение теста
TestNG позволяет выполнять тесты в параллельном или многопоточном режиме, что позволяет тестировать эти многопоточные фрагменты кода.
Вы можете настроить методы, классы и наборы для запуска в своих собственных потоках, сократив общее время выполнения.
10.1. Классы и методы параллельно
Для параллельного запуска тестовых классов укажите атрибут parallel в теге suite в файле конфигурации XML со значением classes:
<suite name="suite" parallel="classes" thread-count="2">
<test name="test suite">
<classes>
<class name="baeldung.com.RegistrationTest"/>
<class name="baeldung.com.SignInTest"/>
</classes>
</test>
</suite>
Обратите внимание, что, если у нас есть несколько тегов test в файле XML, эти тесты также можно запускать параллельно, упоминая parallel = ”tests” . Также для параллельного выполнения отдельных методов упоминайте parallel = ”method” .
10.2. Многопоточное выполнение метода испытаний
Допустим, нам нужно проверить поведение кода при работе в нескольких потоках. TestNG позволяет запускать метод тестирования в нескольких потоках:
public class MultiThreadedTests {
@Test(threadPoolSize = 5, invocationCount = 10, timeOut = 1000)
public void givenMethod__whenRunInThreads__thenCorrect() {
int count = Thread.activeCount();
assertTrue(count > 1);
}
}
ThreadPoolSize указывает, что метод будет выполняться в количестве n потоков, как упомянуто. InvocationCount и timeOut указывают, что тест будет выполнен несколько раз, и не пройдут тест, если он займет больше времени.
11. Функциональное тестирование
TestNG поставляется с функциями, которые также можно использовать для функционального тестирования. В сочетании с Selenium его можно использовать для тестирования функциональных возможностей веб-приложения или для тестирования веб-служб с помощью HttpClient .
Более подробную информацию о функциональном тестировании с Selenium и TestNG можно найти по ссылке:/java-selenium-with-junit-and-testng[здесь]. Также по этой ссылке есть еще кое-что о тестировании интеграции:/gration-testing-a-rest-api[статья].
12. Вывод
В этой статье мы кратко рассмотрели, как настроить TestNG и выполнить простой контрольный пример, сгенерировать отчеты, одновременное выполнение контрольных примеров, а также немного о функциональном программировании. Чтобы узнать больше о таких функциях, как зависимые тесты, игнорирование тестовых случаев, групп тестов и комплектов, вы можете обратиться к нашей статье JUnit vs TestNG:/junit-vs-testng[здесь].
Реализацию всех фрагментов кода можно найти over на Github .