Ramazan POLAT Ramazan POLAT - 1 month ago 20
Java Question

junit constructor runs AFTER test methods

AFAIK before any method, constructor method is run by JRE.
But in my case, constructor is running after test methods.

import org.junit.*;
public class CourseTest {

public CourseTest(){
System.out.println("Constructor");
}

@BeforeClass
public static void beforeClassTest() throws Exception{
System.out.println("beforeClassTest");
}

@AfterClass
public static void afterClassTest() throws Exception{
System.out.println("afterClassTest");
}

@Before
public void beforeTest() throws Exception{
System.out.println("beforeTest");
}

@After
public void afterTest() throws Exception{
System.out.println("afterTest");
}


@Test
public void getCredit() throws Exception {
System.out.println("test 1 is getCredit");

}

@Test
public void getName() throws Exception {
System.out.println("test 2 is getName");
}
}


And the result is:

beforeTest
test 2 is getName
afterTest
beforeTest
test 1 is getCredit
afterTest
beforeClassTest
Constructor
Constructor
afterClassTest


Not only that, my test cases are running in reverse order too.
Pretty confused by that.
I understand why constructor runs twice because for each test, a new class is instantiated. But how come constructor runs after test methods?

Edit:
As @mike-jenkins suggested, I debugged the test class and it runs in this order:

1-beforeClassTest
2-Constructor
3-beforeTest
4-test 2 is getName
5-afterTest
6-Constructor
7-beforeTest
8-test 1 is getCredit
9-afterTest
10-afterClassTest

Answer

The order of execution of the JUnit tests are NOT guaranteed as JUnit framework manages (internally) to run the tests in parallel. This is to make the text execution faster which will be especially helpful when you are building the application in CI (Continuous Integration) environments where thousands of tests have to be run for the whole application.

If you wanted to control the order of execution, you can use @FixMethodOrder annotation as below:

 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class MyTest {
    //your test code here
 }

The default order of execution of JUnit tests within a class is deterministic but not predictable. The order of execution is not guaranteed for Java 7 (and some previous versions), and can even change from run to run, so the order of execution was changed to be deterministic (in JUnit 4.11)

You can look at here

As there are multiple test cases, the constructor will be called multiple times (by different threads created by JUnit framework to execute them in parallel).

As multiple threads are running, constructor's System.out.prinln() (infact any logs), can't be guaranteed that it will always be printed first (even though it has been invoked first). In summary, in multi-threaded environments, you can't predict the order of logs and System.out.println() statements.