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.
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:
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:
Create one base class for all tests:
and every test should inherit from it:
With JUnit4 test suite you can do something like this :
Then you run this class as you would run a normal test class and it will run all of your tests.
You can make one
BaseTest
class with a@BeforeClass
method, then have all the other tests inherit from it. This way, when each test object is constructed,@BeforeClass
gets executed.Also avoid executing it just once for all the test suite, since all the test cases should be independent.
@BeforeClass
should execute only once each test case, not test suite.If you can tolerate adding spring-test to your project, or you are using it already, then a good approach is to use the technique described here: How to load DBUnit test data once per case with Spring Test
Not sure if anyone still is using JUnit and trying to fix it without using Spring Runner (aka no spring integration). TestNG has this feature. But here is a JUnit based solution.
Create a RunOnce per thread operation like so. This maintains a list of classes for which the operation has run.
Back in your unit test
When you use this way, you can perform operations once per class using ThreadLocal.