Open In App

Unit Testing, Integration Testing, Priority Testing using TestNG in Java

Improve
Improve
Like Article
Like
Save
Share
Report

TestNG is an automated testing framework. In this tutorial, let us explore more about how it can be used in a software lifecycle. 

Unit Testing

Instead of testing the whole program, testing the code at the class level, method level, etc., is called Unit Testing The code has to be split into separate classes and methods so that testing can be carried out easily at a unit level.

Integration Testing

After the completion of Unit testing, there will always be the necessity for integration testing. Several units are tested in groups and this will help to reduce the defects exposed at the time of integration of several modules.

Example: We can run tests together by means of specifying “suite name” and can do different classes together.

Priority Testing

By using annotations like @Test(priority=1/2/…), we can set the priority of the tests. If a test class is having @Test annotation alone, it will high priority and if any specific test numbers are given, it is executed as per the order. So we can set the order of execution by using annotations as above. Let us take a maven project and from there will cover important topics.

Example Project

Project Structure:

Project Structure

 

This is a maven kind of project and hence dependencies need to be mentioned in 

pom.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\test\resources\parametrized_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\test\resources\test_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>


In TestNG, Via XML files, We can pass parameters as specified in the below XML using <parameter> tag with name and value

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>


These parameters are collected via @DataProvider or @Parameter in Java files

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

We can run tests together by means of specifying “suite name” and can do different classes together.

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>


This specifies that “int” is the suite name and 2 classes namely com.gfg.MultiThreadedIntegrationTest and com.gfg.TimeOutCheckTest together. Like this, we can group classes under a single suite. And also we can specify different suite names and can group classes whichever we need. Dependency tests. i.e. depends upon a specific test and thereupon logging some information

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);
}

Order of test execution can be controlled by using @Priority annotation

@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 can be mentioned by using @Test(timeout=<certain value>). TestNG supports for timed out tests. 

@Test(timeOut = 1000, enabled = false)
public void asNoStoppingPointItRunsTimeOut() {
     while (true) ;
}
  • Actually, in the previous test, we are having enabled = false,, that is if we want to ignore the test cases
  • We can include 
    • @BeforeClass and @AfterClass at the class level are mainly used to initialize and clean up the code. 
    • Similarly, we can include @BeforeMethod and @AfterMethod at the method level
    • @BeforeSuite, @AfterSuite, @BeforeGroup, and @AfterGroup annotations, for configurations at suite and group levels respectively.
 private int evenNumber, oddNumber;

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

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

As a whole let us see the java code with the above features

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);
    }
  
}


ParametrizedUnitTest.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);
    }
  
    @Test(dataProvider = "numbersObject")
    public void evenNumberObjectCheck(EvenNumberPOJO number) {
        assertEquals(number.isEven(), number.getValue() % 2 == 0);
    }
  
    @DataProvider(name = "numbersObject")
    public Object[][] parameterProvider() {
        return new Object[][]{{new EvenNumberPOJO(111, false)}, {new EvenNumberPOJO(2432, true)}, {new EvenNumberPOJO(4712, true),}};
    }
  
    class EvenNumberPOJO {
        private int value;
        private boolean isEven;
  
        EvenNumberPOJO(int number, boolean isEven) {
            this.value = number;
            this.isEven = isEven;
        }
  
        int getValue() {
            return value;
        }
  
        public void setValue(int value) {
            this.value = value;
        }
  
        boolean isEven() {
            return isEven;
        }
  
        public void setEven(boolean even) {
            isEven = even;
        }
  
        @Override
        public String toString() {
            return "EvenNumber{" +
              "value=" + value +
              ", isEven=" + isEven +
              '}';
        }
    }
}


PriorityUnitTest.java

Java




import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
  
public class PriorityUnitTest {
  
    @Test(priority = 1)
    public void stringToIntCheck() {
        String testString = "100";
        assertTrue(Integer.valueOf(testString) instanceof Integer);
    }
  
    @Test(priority = 2)
    public void intToStringCheck() {
        int testInt = 100;
        assertTrue(String.valueOf(testInt) instanceof String);
    }
  
}


TimeOutCheckTest.java

Java




import org.testng.annotations.Test;
  
public class TimeOutCheckTest {
    // @Test(timeOut = 1000)
    // If we want to skip the test means, 
    // enabled = false has to be added
    @Test(timeOut = 1000, enabled = false)
    public void asNoStoppingPointItRunsTimeOut() {
        while (true) ;
    }
}


Now let’s run the test by using

mvn test

Or from eclipse 

Output:

 

We can see the success/failure reports under the target/surefire-reports folder as well.



Last Updated : 15 Nov, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads