Введение в TestNG

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 .