Перейти к основному содержимому

Введение в TestNG

· 7 мин. чтения

1. Обзор

В этой статье мы представим среду тестирования TestNG.

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

2. Настройка

Начнем с добавления зависимости Maven в наш файл pom.xml :

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.1.0</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, используя maven-surefire-plugin :

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</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 в пути к классам и скомпилированный тестовый класс вместе с файлом конфигурации XML:

java org.testng.TestNG test_suite.xml

6. Групповые тесты

Тесты можно запускать группами, например, из 50 тестовых случаев 15 можно сгруппировать и выполнить, оставив остальные без изменений.

В TestNG групповые тесты в наборах выполняются с использованием XML-файла:

<suite name="suite">
<test name="test suite">
<classes>
<class name="com.foreach.RegistrationTest" />
<class name="com.foreach.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.foreach.SummationServiceTest" />
</classes>
</test>

Это выполнит тестовый метод, помеченный групповой регрессией, в классе SummationServiceTest .

7. Параметризованные тесты

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

В TestNG мы можем параметризовать тесты, используя аннотацию @Parameter или @DataProvider . При использовании XML-файла аннотируйте тестовый метод с помощью параметра @:

@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="foreach.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. Игнорирование тестовых случаев

Иногда мы хотим временно не выполнять определенный тестовый пример в процессе разработки. Это можно сделать, добавив enable = false в аннотацию @ Test :

@Test(enabled=false)
public void givenNumbers_sumEquals_thenCorrect() {
int sum = numbers.stream.reduce(0, Integer::sum);
assertEquals(6, sum);
}

9. Зависимые тесты

Давайте рассмотрим сценарий, в котором, если начальный тест-кейс не пройден, все последующие тест-кейсы должны быть выполнены и, скорее, помечены как пропущенные. TestNG предоставляет эту функцию с помощью параметра dependOnMethods аннотации @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 в теге набора в файле конфигурации XML со значениями классов:

<suite name="suite" parallel="classes" thread-count="2">
<test name="test suite">
<classes>
<class name="foreach.com.RegistrationTest" />
<class name="foreach.com.SignInTest" />
</classes>
</test>
</suite>

Обратите внимание, что если у нас есть несколько тестовых тегов в XML-файле, эти тесты также можно запускать параллельно, упомянув parallel = «тесты». Также для параллельного выполнения отдельных методов укажите parallel = «методы».

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 можно прочитать здесь . Также в этой статье есть еще кое-что по интеграционному тестированию .

12. Заключение

В этой статье мы кратко рассмотрели, как настроить TestNG и выполнить простой тестовый пример, создать отчеты, параллельное выполнение тестовых случаев, а также немного о функциональном программировании. Чтобы узнать о дополнительных функциях, таких как зависимые тесты, игнорирование тестовых случаев, тестовых групп и наборов, вы можете обратиться к нашей статье JUnit vs TestNG здесь .

Реализацию всех фрагментов кода можно найти на Github .