Модульное тестирование, интеграционное тестирование, приоритетное тестирование с использованием TestNG в Java

Опубликовано: 22 Февраля, 2023

TestNG — это среда автоматизированного тестирования. В этом руководстве давайте подробнее рассмотрим, как его можно использовать в жизненном цикле программного обеспечения.

Модульное тестирование

Вместо тестирования всей программы тестирование кода на уровне класса, уровня метода и т. д. называется модульным тестированием. Код должен быть разделен на отдельные классы и методы, чтобы можно было легко проводить тестирование на уровне модуля.

Интеграционное тестирование

После завершения модульного тестирования всегда будет необходимость в интеграционном тестировании. Несколько модулей тестируются группами, и это поможет уменьшить дефекты, выявленные во время интеграции нескольких модулей.

Пример: мы можем запускать тесты вместе, указав «название набора», и можем вместе проводить разные классы.

Приоритетное тестирование

Используя такие аннотации, как @Test(priority=1/2/…), мы можем установить приоритет тестов. Если тестовый класс имеет только аннотацию @Test, он будет иметь высокий приоритет, и если указаны какие-либо конкретные номера тестов, он выполняется в соответствии с порядком. Таким образом, мы можем установить порядок выполнения, используя аннотации, как указано выше. Возьмем проект maven и оттуда охватим важные темы.

Пример проекта

Структура проекта:

Это проект типа maven, и поэтому зависимости должны быть упомянуты в

пом.xml

XML




<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.gfg.testng</groupId>
        <artifactId>testng</artifactId>
        <version>0.1.0-SNAPSHOT</version>  
      
    <name>testng</name>
    <packaging>jar</packaging
    <dependencies>
      <!-- This is the essential dependency required for testng -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
      <!-- As we are logging, below dependency is required -->
        <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.9</version>
</dependency>
    </dependencies>
  
    <build>
        <finalName>testng</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </testResource>
        </testResources>
    </build>
  
    <profiles>
        <profile>
            <id>default-second</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <suiteXmlFiles>
                                <suiteXmlFile>src est esourcesparametrized_testng.xml</suiteXmlFile>
  
                            </suiteXmlFiles>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>integration-lite-second</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <suiteXmlFiles>
                                <suiteXmlFile>src est esources est_int.xml</suiteXmlFile>
                            </suiteXmlFiles>
                        </configuration>
                    </plugin>                  
                      
                </plugins>
            </build>
        </profile>
    </profiles>
  
    <properties>
        <testng.version>7.1.0</testng.version>
                <!-- https://maven.apache.org/general.html#encoding-warning -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
  
    </properties>
  
</project>

В TestNG через файлы XML мы можем передавать параметры, как указано в приведенном ниже XML, используя тег <parameter> с именем и значением.

XML




<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="My test suite">
<listeners>
<listener class-name="com.gfg.reports.CustomisedListener"></listener>
</listeners>
    <test name="numbersXML">
        <!-- We can specify as much parameters and their values here -->
        <parameter name="value" value="1"/>
        <parameter name="isEven" value="false"/>
        <classes>
            <class name="com.gfg.ParametrizedUnitTest"/>
        </classes>
    </test>
</suite>

Эти параметры собираются через @DataProvider или @Parameter в файлах Java.

@DataProvider(name = "numbers")
public static Object[][] evenNumbers() {
        return new Object[][]{{11, false}, {2222, true}, {4882, true}};
    }

Мы можем запускать тесты вместе, указав «название набора», и можем вместе делать разные классы.

XML




<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="int">
    <test name="integration tests">
        <classes>
            <class name="com.gfg.MultiThreadedIntegrationTest" />
            <class name="com.gfg.TimeOutCheckTest" />
        </classes>
    </test>
</suite>

Это указывает, что « int » — это имя набора и 2 класса, а именно com.gfg.MultiThreadedIntegrationTest и com.gfg.TimeOutCheckTest вместе. Таким образом, мы можем сгруппировать классы в одном наборе. А также мы можем указать разные имена наборов и можем группировать классы в зависимости от того, что нам нужно. Тесты зависимости. т.е. зависит от конкретного теста и, следовательно, регистрации некоторой информации

Usecase: Check whether an email is valid or not and if valid, proceed to the next set of steps

private String userEmail = "geek@gfg.com";

@Test
public void checkForValidMail() {
    boolean validEmail = userEmail.contains("@");
    Assert.assertEquals(validEmail, true);
}


// If first test is success, below test executes and logs the information
@Test(dependsOnMethods = {"checkForValidMail"})
public void logInWhenEmailValid() {
   LOGGER.info("Given Email {} valid >> and logging in", userEmail);
}

Порядок выполнения теста можно контролировать с помощью аннотации @Priority.

@Test(priority = 1) // This is executed first
public void stringToIntCheck() {
        String testString = "100";
        assertTrue(Integer.valueOf(testString) instanceof Integer);
    }

@Test(priority = 2) // This is second
public void intToStringCheck() {
        int testInt = 100;
        assertTrue(String.valueOf(testInt) instanceof String);
    }

Время ожидания теста можно указать с помощью @Test(timeout=<определенное значение>). TestNG поддерживает тесты с истекшим временем ожидания.

@Test(timeOut = 1000, enabled = false)
public void asNoStoppingPointItRunsTimeOut() {
     while (true) ;
}
  • На самом деле, в предыдущем тесте мы включили = false, то есть если мы хотим игнорировать тестовые случаи
  • Мы можем включить
    • @BeforeClass и @AfterClass на уровне класса в основном используются для инициализации и очистки кода.
    • Точно так же мы можем включить @BeforeMethod и @AfterMethod на уровне метода.
    • Аннотации @BeforeSuite, @AfterSuite, @BeforeGroup и @AfterGroup для конфигураций на уровне набора и группы соответственно.
 private int evenNumber, oddNumber;

    @BeforeClass
    public void setup() {
        evenNumber = 100;
        oddNumber = 59;
    }

    @AfterClass
    public void tearDown() {
        evenNumber = 0;
        oddNumber = 0;
    }

В целом давайте посмотрим на java-код с указанными выше функциями.

DependencyUnitTest.java

Java




import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
  
public class DependencyUnitTest {
  
    private static final Logger LOGGER = LoggerFactory.getLogger(DependencyUnitTest.class);
  
    private String userEmail = "geek@gfg.com";
  
    @Test
    public void checkForValidMail() {
        boolean validEmail = userEmail.contains("@");
        Assert.assertEquals(validEmail, true);
    }
  
    @Test(dependsOnMethods = {"checkForValidMail"})
    public void logInWhenEmailValid() {
        LOGGER.info("Given Email {} valid >> and logging in", userEmail);
    }
}

MultiThreadedIntegrationTest.java

Java




import org.testng.Assert;
import org.testng.annotations.Test;
  
public class MultiThreadedIntegrationTest {
  
    @Test(threadPoolSize = 5, invocationCount = 10, timeOut = 1000)
    public void checkForCount() {
        int count = Thread.activeCount();
        Assert.assertTrue(count > 2);
    }
  
}

OddOrEvenNumberCheck.java

Java




import org.testng.Assert;
import org.testng.TestNG;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
  
public class OddOrEvenNumberCheck extends TestNG {
    
    private int evenNumber, oddNumber;
  
    @BeforeClass
    public void setup() {
        evenNumber = 100;
        oddNumber = 59;
    }
  
    @AfterClass
    public void tearDown() {
        evenNumber = 0;
        oddNumber = 0;
    }
  
    @Test
    public void checkEven() {
        Assert.assertTrue(evenNumber % 2 == 0);
    }
    @Test
    public void checkOdd() {
        Assert.assertTrue(oddNumber % 2 == 1);
    }
  
}

ПараметризованныйUnitTest.java

Java




import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
  
import static org.testng.Assert.assertEquals;
  
public class ParametrizedUnitTest {
  
    @DataProvider(name = "numbers")
    public static Object[][] evenNumbers() {
        return new Object[][]{{11, false}, {2222, true}, {4882, true}};
    }
  
    @Test(dataProvider = "numbers")
    public void evenNumberCheck(Integer number, boolean expected) {
        assertEquals(expected, number % 2 == 0);
    }