Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Before and After Suite execution hook in jUnit 4.x

I'm trying to preform setup and teardown for a set of integration tests, using jUnit 4.4 to execute the tests. The teardown needs to be run reliably. I'm having other problems with TestNG, so I'm looking to port back to jUnit. What hooks are available for execution before any tests are run and after all tests have completed?

Note: we're using maven 2 for our build. I've tried using maven's pre- & post-integration-test phases, but, if a test fails, maven stops and doesn't run post-integration-test, which is no help.

like image 647
sblundy Avatar asked Sep 17 '08 13:09

sblundy


People also ask

What is before and after in JUnit?

org.junitIf you allocate external resources in a Before method you need to release them after the test runs. Annotating a public void method with @After causes that method to be run after the Test method. All @After methods are guaranteed to run even if a Before or Test method throws an exception.

How do you use before in JUnit?

The @Before annotation is used when different test cases share the same logic. The method with the @Before annotation always runs before the execution of each test case. This annotation is commonly used to develop necessary preconditions for each @Test method.

What is the difference between @AfterClass and @after?

Similarly function with @After annotation will be executed after each of test function in the class having @Test annotation but the function with @AfterClass will be execute only one time after all the test functions in the class.


1 Answers

Yes, it is possible to reliably run set up and tear down methods before and after any tests in a test suite. Let me demonstrate in code:

package com.test;  import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses;  @RunWith(Suite.class) @SuiteClasses({Test1.class, Test2.class}) public class TestSuite {      @BeforeClass     public static void setUp() {         System.out.println("setting up");     }      @AfterClass     public static void tearDown() {         System.out.println("tearing down");     }  } 

So your Test1 class would look something like:

package com.test;  import org.junit.Test;   public class Test1 {     @Test     public void test1() {         System.out.println("test1");     }  } 

...and you can imagine that Test2 looks similar. If you ran TestSuite, you would get:

setting up test1 test2 tearing down 

So you can see that the set up/tear down only run before and after all tests, respectively.

The catch: this only works if you're running the test suite, and not running Test1 and Test2 as individual JUnit tests. You mentioned you're using maven, and the maven surefire plugin likes to run tests individually, and not part of a suite. In this case, I would recommend creating a superclass that each test class extends. The superclass then contains the annotated @BeforeClass and @AfterClass methods. Although not quite as clean as the above method, I think it will work for you.

As for the problem with failed tests, you can set maven.test.error.ignore so that the build continues on failed tests. This is not recommended as a continuing practice, but it should get you functioning until all of your tests pass. For more detail, see the maven surefire documentation.

like image 67
Julie Avatar answered Sep 24 '22 07:09

Julie