Reputation: 43053
Here my test code:
public class Test1 {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
// test methods...
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
public class Test2 {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
// test methods...
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
// ...
As you can see, I duplicate the start and stop calls to embedded tomcat in each Test class. How can I avoid this duplication with JUnit ?
Requirement: - The start and stop calls must be called ONCE for all test classes
JUnit 4.11
Upvotes: 0
Views: 2399
Reputation: 31658
In addition to making a parent class that runs the @BeforeClass
and @AfterClass
. you can create a JUnit Rule. You can make your rule subclass ExternalResource which has methods to override for adding behavior before and after executions (class or tests).
public class EmbeddedTomcatServer extends ExternalResource {
...
@Override
protected void before() throws Throwable {
EmbeddedTomcat.start();
};
@Override
protected void after() {
EmbeddedTomcat.stop();
};
}
Then in your test use the @ClassRule
which runs the server's before()
and after()
methods during BeforeClass
and AfterClass
time.
public class Test1 {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
//tests as normal, no more @BeforeClass or @AfterClass
}
public class Test2 {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
//tests as normal, no more @BeforeClass or @AfterClass
}
This solution might be better than the using a parent class because you can use this Rule in any test without having to change the parent class.
EDIT only running the start() and stop() once
It is a little unclear if you mean running the start and stop once per test class (as your original code using @BeforeClass and @AfterClass)
Or if you want to run start and stop only once over ALL of the tests across the all the test classes that are run.
If you want to do the latter, @ClassRules are helpful here too. Just create a test suite with the test classes to use and then put the ClassRule ONLY IN THE SUITE CLASS
@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
}
This will start tomcat when the AllTests suite starts and then stop tomcat when all the tests in the test suite have run.
Upvotes: 4
Reputation: 85789
If possible for your project, you can create a TestParent
class which defines these @BeforeClass
and @AfterClass
methods and make your Test1
and Test2
classes extend from it.
public class TestParent {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
public class Test1 extends TestParent {
//...
}
public class Test2 extends TestParent {
//...
}
Upvotes: 2