Wednesday, April 22, 2009

Adding static @BeforeClass method in the test class

I was looking at a integration test in project that takes 10 seconds to execute. Its a integration test in a for a class that connects to the FTP server and performs some operations. The test uses a in-memory mock ftp server. The issue is that it starts, initializes the mock file system for every test and then stops the server after each test. The initialization code is written as a part of @Before method and server is stopped in @After method. The fact that the server was getting started and closed for every test was the reason why test was so slow. I want to start and initialize it only once for the all the tests my my class. The way to achieve this is to use @BeforeClass annotation. The method marked with @BeforeClass runs only once for all the test. The corresponding tear down method is @AfterClass. By using @BeforeClass instead of @Before and with some other changes, I was able to reduce the time required to run the test to 3 seconds.

However, using @BeforeClass instead of @Before may make tests dependent on each other and on the order of execution. As all the tests will use the same objects, changes made by one test will be affecting others. So @BeforeClass method should be used to initialize objects which are not modified by the tests. The methods should be used to setup the environment for the test and not for creating the objects that will be directly consumed by the tests.

@BeforeClass (and @AfterClass) method has to be static, which means all the variables that are accessed in this method has to be maked as static. This puts up restrictions on the ways in which @BeforeClass can be used, but this makes it explicit that the @BeforeClass method should be used to set only the environment for the test and objects under test itself.

No comments: