JUnit 4: Set up things in a test suite before tests are run (like a test's @BeforeClass method, just for a test suite)
I want to do some functional testing on a (restful) webservice. The testsuite contains a bunch of test cases, each of which performs a couple of HTTP requests on the webservice.
Naturally, the webservice has to run or the tests will fail. :-)
Starting the webservice takes a couple of minutes (it does some heavy data lifting), so I want to start it as infrequently as possible (at least all test cases that only GET resources from the service could share one).
So is there a way to do set up me the bomb in a test suite, before the tests are run like in a @BeforeClass method of a test case?
Solution 1:
The answer is now to create a @ClassRule
within your suite. The rule will be invoked before or after (depending on how you implement it) each test class is run. There are a few different base classes you can extend/implement. What is nice about class rules is that if you do not implement them as anonymous classes then you can reuse the code!
Here is an article about them: http://java.dzone.com/articles/junit-49-class-and-suite-level-rules
Here is some sample code to illustrate their use. Yes, it is trivial, but it should illustrate the life-cycle well enough for you to get started.
First the suite definition:
import org.junit.*;
import org.junit.rules.ExternalResource;
import org.junit.runners.Suite;
import org.junit.runner.RunWith;
@RunWith( Suite.class )
@Suite.SuiteClasses( {
RuleTest.class,
} )
public class RuleSuite{
private static int bCount = 0;
private static int aCount = 0;
@ClassRule
public static ExternalResource testRule = new ExternalResource(){
@Override
protected void before() throws Throwable{
System.err.println( "before test class: " + ++bCount );
sss = "asdf";
};
@Override
protected void after(){
System.err.println( "after test class: " + ++aCount );
};
};
public static String sss;
}
And now the test class definition:
import static org.junit.Assert.*;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
public class RuleTest {
@Test
public void asdf1(){
assertNotNull( "A value should've been set by a rule.", RuleSuite.sss );
}
@Test
public void asdf2(){
assertEquals( "This value should be set by the rule.", "asdf", RuleSuite.sss );
}
}
Solution 2:
jUnit can't do that sort of thing -- though TestNG does have @BeforeSuite
and @AfterSuite
annotations. Normally, you get your build system to do it. In maven, there are the "pre-integration-test" and "post-integration-test" phases. In ANT, well you just add the steps to the task.
Your question is pretty much a dup of Before and After Suite execution hook in jUnit 4.x, so I'd take a look at the suggestions over there.