我有很多单元测试文件基本上执行相同的@BeforeClass
。
他们启动jetty web服务器,添加一些系统属性。
所以我想知道,在运行单元测试之前,是否可以只执行一次?
答案 0 :(得分:10)
您可以使用@RunWith注释:
@RunWith(JettyRunner.class)
public class MyAwesomeTest {
@Test
//...
}
并实施新的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;
}
}
}
}
我不确定是否真的需要同步块,只是把它扔进去做好...
答案 1 :(得分:1)
也许使用静态初始化程序会做什么?虽然在运行单元测试时仅初始化一些字段并不是一个好主意,因为某些测试可能会将字段驱动到非法状态,这将妨碍其他测试的运行。
答案 2 :(得分:1)
除了@Matt关于创建自己的Runner的答案(我认为这是最好的方法)(参见the answer here),我还创建了一个额外的JUnit测试,验证我的所有测试都使用了我的Runner(如果我的一个开发人员忘了):
PS:请注意,这取决于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)");
}
}
}
}
答案 3 :(得分:0)
您是否从套件中运行测试类?在运行任何测试之前,套件类上的@BeforeClass
将运行一次。