Friday, 20 November 2015

Junit and TestNG - An important difference to be noted

Assume the tests are run sequentially to keep things simple. Have a look at the following code:

a) Using Junit

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class JunitExample
{
    private List<Integer> ints = new ArrayList<>();
   
    @Before
    public void initialize()
    {
        ints.add(1);
        ints.add(2);
        ints.add(3);
    }

    @Test
    public void test1()
    {
        ints.add(4);
        System.out.println(ints);
    }
   
    @Test
    public void test2()
    {
        ints.add(5);
        System.out.println(ints);
    }
}


Running the tests sequentially outputs
[1, 2, 3, 4]
[1, 2, 3, 5]

b) Using TestNG

import java.util.ArrayList;
import java.util.List;

import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;


public class TestNGExample
{
    private List<Integer> ints = new ArrayList<>();
   
    @BeforeTest
    public void initialize()
    {
        ints.add(1);
        ints.add(2);
        ints.add(3);
    }

    @Test
    public void test1()
    {
        ints.add(4);
        System.out.println(ints);
    }
   
    @Test
    public void test2()
    {
        ints.add(4);
        System.out.println(ints);
    }
}


This outputs,
[1, 2, 3, 4]
[1, 2, 3, 4, 4]

Surprised?. This is because Junit creates a separate instance of test class for each and every tests that are present. When test1 begins to gets executed ints consisted of [1, 2, 3] and when test2 begins to gets executed too it consisted of [1, 2, 3]. No surprises here. We ended up with [1, 2, 3, 4] on both these cases.

But in case of TestNG, there is only one instance of test class that gets created and that will be used by all test methods. So, before test1 got executed, ints were [1, 2, 3] and by the time test1 got completed, ints were [1, 2, 3, 4]. Now when test2 begins to get executed ints are already [1, 2, 3, 4] and we add up 4 again to ints. So, finally we ended up with [1, 2, 3, 4, 4].

When the tests are run in parallel, in case of TestNG, the behavior is undefined if instance variables are used without considering multithreading scenarios.

No comments:

Post a Comment