JUnit - Lifecycle of a Test Class

[Updated: Apr 19, 2017, Created: Mar 10, 2017]

In this tutorial we will learn JUnit basic annotations which are used to specify lifecycle methods for test classes.

Every time we run a JUnit test class, a new instance of it is created. There is even a new instance before each test method execution. JUnit framework provides following basic lifecycle annotations (all are method level annotations).

  1. @BeforeClass:
    • This annotation must be used on public static void no-arg method.
    • The method is invoked before an instance of this test class is created and any tests are invoked.
    • This life cycle callback is not related to JVM class loading. JUnit framework calls this method explicitly before calling constructor/other methods.
    • This method is called only once, whereas, other instance lifecycle methods are called every time before calling each test method.
    • This annotation is useful for initializing static resources which would, otherwise, be expensive to create during each test invocation.
  2. @AfterClass: Similar to @BeforeClass but is called at the very end of all test/other lifecycle methods. It is called only once. Useful for static resource clean up.
  3. @Before:
    • It should be used on public void no-arg instance method.
    • It is invoked every time before each test method invocation.
    • Used to setup instance variables/resources which can be used during a test method execution. Useful to avoid code duplication and/or when there are many indirection of method calls starting from the target test method.
  4. @After: Similar to @Before but runs after target test method execution. Useful for cleaning up instance resources.
  5. @Test: public void methods to perform tests. This is where we perform one or more assertions by using static methods of org.junit.Assert. Assert methods throw org.junit.AssertionError on assertion failure. This exception or any other exception is reported as test failure. If no exceptions are thrown then the test will pass.

Example

In this example we are just printing messages to understand the methods invocation sequence.

public class LifeCycleTest {

  public LifeCycleTest() {
      System.out.printf("Constructor invoked. Instance: %s%n", this);
  }

  @BeforeClass
  public static void beforeClassMethod() {
      System.out.println("@BeforeClass static method invoked.");
  }

  @Test
  public void test1() {
      System.out.printf("@Test method 1  invoked. Instance: %s%n", this);
  }

  @Test
  public void test2() {
      System.out.printf("@Test method 2  invoked. Instance: %s%n", this);
  }

  @Before
  public void beforeMethod() {
      System.out.printf("@Before method invoked. Instance: %s%n", this);
  }

  @After
  public void afterMethod() {
      System.out.printf("@After method invoked. Instance: %s%n", this);
  }

  @AfterClass
  public static void afterClassMethod() {
      System.out.printf("@AfterClass static method invoked.%n");
  }
}
mvn -q test -Dtest=LifeCycleTest

Output

D:\example-projects\junit\junit-lifecycle> mvn -q test -Dtest=LifeCycleTest

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.logicbig.example.LifeCycleTest
@BeforeClass static method invoked.
Constructor invoked. Instance: com.logicbig.example.LifeCycleTest@76ccd017
@Before method invoked. Instance: com.logicbig.example.LifeCycleTest@76ccd017
@Test method 1 invoked. Instance: com.logicbig.example.LifeCycleTest@76ccd017
@After method invoked. Instance: com.logicbig.example.LifeCycleTest@76ccd017
Constructor invoked. Instance: com.logicbig.example.LifeCycleTest@3830f1c0
@Before method invoked. Instance: com.logicbig.example.LifeCycleTest@3830f1c0
@Test method 2 invoked. Instance: com.logicbig.example.LifeCycleTest@3830f1c0
@After method invoked. Instance: com.logicbig.example.LifeCycleTest@3830f1c0
@AfterClass static method invoked.
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.041 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

Now let's run the test class LifeCycleTest twice (in the same JVM instance) to confirm @BeforeClass and @AfterClass run each time instead of once (to see if that is not related to JVM class loading). We can run tests twice programmatically (in the same JVM instance) by using JUnitCore:

public class ProgrammaticTestRunner {

  public static void main(String[] args) {
      JUnitCore junit = new JUnitCore();
      junit.run(LifeCycleTest.class);
      System.out.println("----------------");
      junit.run(LifeCycleTest.class);
  }
}

Output

@BeforeClass static method invoked
Constructor invoked. Instance: com.logicbig.example.LifeCycleTest@3969c313
@Before method invoked. Instance: com.logicbig.example.LifeCycleTest@3969c313
@Test method 1 invoked. Instance: com.logicbig.example.LifeCycleTest@3969c313
@After method invoked. Instance: com.logicbig.example.LifeCycleTest@3969c313
Constructor invoked. Instance: com.logicbig.example.LifeCycleTest@aafa69f
@Before method invoked. Instance: com.logicbig.example.LifeCycleTest@aafa69f
@Test method 2 invoked. Instance: com.logicbig.example.LifeCycleTest@aafa69f
@After method invoked. Instance: com.logicbig.example.LifeCycleTest@aafa69f
@AfterClass static method invoked.
----------------
@BeforeClass static method invoked
Constructor invoked. Instance: com.logicbig.example.LifeCycleTest@61df15f6
@Before method invoked. Instance: com.logicbig.example.LifeCycleTest@61df15f6
@Test method 1 invoked. Instance: com.logicbig.example.LifeCycleTest@61df15f6
@After method invoked. Instance: com.logicbig.example.LifeCycleTest@61df15f6
Constructor invoked. Instance: com.logicbig.example.LifeCycleTest@16b3cc0c
@Before method invoked. Instance: com.logicbig.example.LifeCycleTest@16b3cc0c
@Test method 2 invoked. Instance: com.logicbig.example.LifeCycleTest@16b3cc0c
@After method invoked. Instance: com.logicbig.example.LifeCycleTest@16b3cc0c
@AfterClass static method invoked.

Example Project

Dependencies and Technologies Used :

  • junit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck..
  • JDK 1.8
  • Maven 3.3.9

Junit Lifecycle Select All Download
  • junit-lifecycle
    • src
      • main
        • java
          • com
            • logicbig
              • example
      • test
        • java
          • com
            • logicbig
              • example

See Also