Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUNIT : run setup only once for a large number of test classes

Tags:

I have a class, which I use as a basis for my unit tests. In this class I initialize the whole environment for my tests, setting up database mappings, enter a number of database records across multiple tables, etc. That class has a method with a @BeforeClass annotation which does the initialization. Next thing, I extend that class with specific classes in which I have @Test methods.

My question is, since the before class is exactly the same for all these test classes, how can I ensure that they are run only once for all the tests. One simple solution is that I could keep all the tests in one class. However, the number of tests is huge, also they are categorised based on functional heads. So they are located in different classes. However since they need the exact same setup, they inherit the @BeforeClass. As a result the whole setup is done at least once per test class, taking much more time in total than I would prefer.

I could, though, put them all in various subpackages under one package, hence if there is a way, how I can run set up once for all the tests within that package, it would be great.

like image 255
neoInfinite Avatar asked Sep 02 '13 13:09

neoInfinite


2 Answers

With JUnit4 test suite you can do something like this :

@RunWith(Suite.class) @Suite.SuiteClasses({ Test1IT.class, Test2IT.class }) public class IntegrationTestSuite {     @BeforeClass     public static void setUp()     {         System.out.println("Runs before all tests in the annotation above.");     }      @AfterClass     public static void tearDown()     {         System.out.println("Runs after all tests in the annotation above.");     } } 

Then you run this class as you would run a normal test class and it will run all of your tests.

like image 200
FredBoutin Avatar answered Oct 03 '22 03:10

FredBoutin


JUnit doesn't support this, you will have to use the standard Java work-arounds for singletons: Move the common setup code into a static code block and then call an empty method in this class:

 static {      ...init code here...  }   public static void init() {} // Empty method to trigger the execution of the block above 

Make sure that all tests call init(), for example my putting it into a @BeforeClass method. Or put the static code block into a shared base class.

Alternatively, use a global variable:

 private static boolean initialize = true;  public static void init() {      if(!initialize) return;      initialize = false;       ...init code here...  } 
like image 28
Aaron Digulla Avatar answered Oct 03 '22 03:10

Aaron Digulla