November 11, 2018

TestNG

Comparison with JUnit

TestNG is a direct competitor with JUnit. But that may change with JUnit 5.

The main advantage of TestNG compared with JUnit 4, is that TestNG has build in support of Data Provider and Parallel support.

Below follows a summary of feature in TestNG.

Setup

Maven


<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.14.3</version>
    <scope>test</scope>
</dependency>

Eclipse

Open Eclipse and click on Help menu and Install New Software. Enter http://beust.com/eclipse

And then next and finish plugin installation.

TestNG Annotations


    @BeforeSuite
    @AfterSuite

    @BeforeTest
    @AfterTest

    @BeforeClass
    @AfterClass

    @BeforeMethod
    @AfterMethod

    @Test

    // order, but each test method should be independent
    @Test(priority=0)

Grouping Related Test Methods


    // group test method, so they are executed logical together
    @Test(groups = "cars")

Used for test suite, annotate with attribute group and call group in test suite xml.

TestNG Assert


    org.testng.Assert
        assertTrue
        assertFalse
        fail
        assertEquals
        assertNotNull
        assertNull
        assertSame
        assertNotSame

Running a Test Suite


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="tests">
    <test name="backend">
        <classes>
            <class name="se.magnuskkarksson.testng.SimpleTest" />
        </classes>
    </test>
</suite>

To run, right click on xml file and choose TestNG Suite

See also for more example of test suite. http://websystique.com/java/testing/testng-suites-example/

For Maven Surefire Plugin see http://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html

Dependent Test Methods


@Test(dependsOnMethods = {"test1"})
public void test1() throws Exception { }

@Test(dependsOnMethods = {"test2"})
public void test2() throws Exception { }

Disable and Timeout Test


@Test(enabled = false)
public void testEnabled() throws Exception { }

// The maximum number of milliseconds
@Test(timeOut = 1000)
public void testTimeConstraint() throws Exception { }

Providing Test Data from XML file


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="tests">
    <test name="backend">
        <parameter name="param1" value="value1" />
        <parameter name="param2" value="value2" />
        <parameter name="param3" value="value3" />
        <classes>
            <class name="se.magnuskkarksson.testng.SimpleTest" />
        </classes>
    </test>
</suite>

@BeforeClass
@Parameters({ "param1", "param2" })
public void beforeClass(String param1, String param2) throws Exception { }

@Test
@Parameters({ "param1" })
public void test(String param1) throws Exception { }

Running Tests in Parallel


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="tests" parallel="tests" thread-count="2">
 
    <test name="front-end">
        <packages>
            <package name="se.magnuskkarlsson.testng.frontend.*" />
        </packages>
    </test>
    <test name="back-end">
        <packages>
            <package name="se.magnuskkarlsson.testng.backend.*" />
        </packages>
    </test>
</suite>

Data Providers


package se.magnuskkarksson.testng;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class DataProviderTest {

    @Test(dataProvider = "testData")
    public void test(String param1, String param2) throws Exception {
        System.out.println("param1: " + param1 + ", param2: " + param2);
    }

    @DataProvider(name = "testData")
    public Object[][] getTestData() {
        return new Object[][] { //
                { "foo1", "bar1" }, //
                { "foo2", "bar2" } //
        };
    }
}

To reuse testdata move data provider to seperate class.


package se.magnuskkarksson.testng;

import org.testng.annotations.DataProvider;

public class TestData {

    @DataProvider(name = "testData")
    public Object[][] getTestData() {
        return new Object[][] { //
                { "foo1", "bar1" }, //
                { "foo2", "bar2" } //
        };
    }
}

Then modify @Test annotation attribute


package se.magnuskkarksson.testng;

import org.testng.annotations.Test;

public class DataProviderTest {

    @Test(dataProvider = "testData", dataProviderClass = TestData.class)
    public void test(String param1, String param2) throws Exception {
        System.out.println("param1: " + param1 + ", param2: " + param2);
    }
}

TestNG Listeners


org.testng.ITestResult 
org.testng.IInvokedMethodListener
org.testng.ITestListener
org.testng.ISuiteListener

TestNG Reporter Logs and HTML Reports

To create HTML TestNG report add org.testng.Reporter#log() logging to your unit test file. E.g.


@Test
public void aFastTest() {
    Assert.assertTrue(true);
    Reporter.log("Logging.....");
}

Then create test suite xml file and run test suite. Then will a test-output directory be created with a HTML report in it.

TestNG Selenium

Install chrome web browser. On Fedora 28 'yum install google-chrome-stable'

Download chrome webdriver from selenium web page - https://www.seleniumhq.org/download/. Which links to https://chromedriver.storage.googleapis.com/index.html?path=2.43/.

Download zip file and unzip somewhere on disk.

Add selenium for java maven dependency.


<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.5</version>
    <scope>test</scope>
</dependency>

Write test unit test.


package se.magnuskkarksson.testng;

import org.openqa.selenium.WebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumParallelTest {

    private String baseUrl;

    private WebDriver driver;

    @BeforeClass
    public void beforeClass() throws Exception {
        baseUrl = "https://www.google.com/";
        System.setProperty("webdriver.chrome.driver",
                "/home/magnuskkarlsson/bin/selenium/chromedriver_linux64/chromedriver");
        driver = new ChromeDriver();
        driver.get(baseUrl);
    }

    @AfterClass
    public void afterClass() throws Exception {
        driver.quit();
    }

    @Test
    public void test() throws Exception {
        String title = driver.getTitle();
        System.out.println("Title: " + title);
        Assert.assertEquals(title, "Google");
    }
}

No comments: