I have a lot of unit tests files that basically execute the same @BeforeClass
.
They start jetty web server, add some system properties.
So I'm wondering, is it possible to execute this only once, before unit test will be run?
The @Before annotation is used when different test cases share the same logic. The method with the @Before annotation always runs before the execution of each test case. This annotation is commonly used to develop necessary preconditions for each @Test method.
It is possible to run a method only once for the entire test class before any of the tests are executed, and prior to any @Before method(s). “Once only setup” are useful for starting servers, opening communications, etc. It's time-consuming to close and re-open resources for each test.
Create Test fixture before each test. @Before - method that is run before every test case. setUp( ) is the traditional name. @After - method that is run after every test case.
You could use the @RunWith annotation:
@RunWith(JettyRunner.class)
public class MyAwesomeTest {
@Test
//...
}
And implement a new Runner
public class JettyRunner extends BlockJUnit4ClassRunner {
private static boolean initialized = false;
public JettyRunner(Class<?> klass) throws InitializationError {
super(klass);
synchronized (JettyRunner.class) {
if (!initialized) {
System.out.println("Let's run jetty...");
initialized = true;
}
}
}
}
I'm not sure if the synchronized block is really needed, just threw it in for good measure...
Maybe using a static initializer will do? Although it's not a very good idea to initialize some fields only once when running unit tests since some of the tests may drive the fields to an illegal state which will impede the running of the other tests.
In addition to @Matt's answer about creating your own Runner (which I thought was the best approach) (see the answer here), I also created an additional JUnit test that validates that all of my tests use my Runner (in case one of my developers forgets):
PS: Note this depends on OpenPOJO.
@Test
public void ensureAllTestsUseEdgeRunner() {
for (PojoClass pojoClass : PojoClassFactory.getPojoClassesRecursively("your.base.package", null)) {
boolean hasTests = false;
for (PojoMethod pojoMethod : pojoClass.getPojoMethods()) {
if (hasTests = pojoMethod.getAnnotation(Test.class) != null) {
break;
}
if (hasTests = pojoMethod.getAnnotation(BeforeClass.class) != null) {
break;
}
if (hasTests = pojoMethod.getAnnotation(Before.class) != null) {
break;
}
if (hasTests = pojoMethod.getAnnotation(AfterClass.class) != null) {
break;
}
if (hasTests = pojoMethod.getAnnotation(After.class) != null) {
break;
}
}
if (hasTests) {
PojoClass superClass = pojoClass;
boolean hasRunWith = false;
while (superClass != null) {
// ensure it has the RunWith(EdgeJUnitRunner.class) annotation
RunWith runWithAnnotation = superClass.getAnnotation(RunWith.class);
if (runWithAnnotation != null && runWithAnnotation.value() == EdgeJUnitRunner.class) {
hasRunWith = true;
break;
}
superClass = superClass.getSuperClass();
}
if (!hasRunWith) {
throw new RuntimeException(pojoClass.getClazz().getName() + " should be annotated with @RunWith(EdgeRunner.class)");
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With