Java jUnit忽略基类中的@Test方法
假设我有一个名为Java jUnit忽略基类中的@Test方法,java,inheritance,junit,Java,Inheritance,Junit,假设我有一个名为testFixtureA的测试类,它有几个方法testA,testB,testC,等等,每个方法都带有@test注释 现在让我们假设我将testFixtureA子类化到名为testFixtureAB的类中,并且我不覆盖任何内容testFixtureAB目前为空 当我从testFixtureAB运行测试时,方法testA、testB和testC由测试运行程序执行,因为测试运行程序不区分类和基类的测试方法 如何强制测试运行程序忽略基类中的测试?忽略整个基类: @Ignore clas
testFixtureA
的测试类,它有几个方法testA
,testB
,testC
,等等,每个方法都带有@test
注释
现在让我们假设我将testFixtureA
子类化到名为testFixtureAB
的类中,并且我不覆盖任何内容testFixtureAB
目前为空
当我从testFixtureAB
运行测试时,方法testA
、testB
和testC
由测试运行程序执行,因为测试运行程序不区分类和基类的测试方法
如何强制测试运行程序忽略基类中的测试?忽略整个基类:
@Ignore
class BaseClass {
// ...
}
重新构造测试类
- 如果您不想使用基类中的测试,那么不要扩展它
- 如果您需要基类中的其他功能,请将该类分成两部分-测试和其他功能
public class testFixtureAB extends testFixtureA {
@Override
public void testB() {}
}
我知道,这不是答案 考虑一下扩展具体测试类的原因。这样就可以复制测试方法
如果您在测试之间共享代码,那么考虑用OR或.
如果要运行测试,请尝试使用套件和组织测试。如果要对同一测试套件的不同配置执行同一测试,该怎么办 例如,假设您有一个包含test1、test2和test3方法的类,这些方法命中一个嵌入式数据库,然后您希望为每个嵌入式供应商(H2、HyperSQL等)创建单独的“设置”和“拆卸”,但对每个供应商都运行相同的测试
我想扩展一个包含这些测试方法的类,并在子类中配置它。我的问题是,超级类不应该被认为有资格成为测试运行者。当测试运行程序执行超类时,如果没有找到相应的设置和拆卸方法,就会出现问题:(实现一些类很容易:
- 创建自己的
TestRunner
- 创建类似于
@IgnoreInheritedTests
- 创建一个扩展
org.junit.runner.manipulation.Filter
public class InheritedTestsFilter extends Filter {
@Override
public boolean shouldRun(Description description) {
Class<?> clazz = description.getTestClass();
String methodName = description.getMethodName();
if (clazz.isAnnotationPresent(IgnoreInheritedTests.class)) {
try {
return clazz.getDeclaredMethod(methodName) != null;
} catch (Exception e) {
return false;
}
}
return true;
}
@Override
public String describe() {
// TODO Auto-generated method stub
return null;
}
}
公共类继承的测试过滤器扩展了过滤器{
@凌驾
公共布尔值应运行(说明){
Class clazz=description.getTestClass();
String methodName=description.getMethodName();
if(clazz.isAnnotationPresent(IgnoreInheritedTests.class)){
试一试{
return clazz.getDeclaredMethod(methodName)!=null;
}捕获(例外e){
返回false;
}
}
返回true;
}
@凌驾
公共字符串descripe(){
//TODO自动生成的方法存根
返回null;
}
}
在自定义跑步器上:
/**
* @param klass
* @throws InitializationError
* @since
*/
public CustomBaseRunner(Class<?> klass) throws InitializationError {
super(klass);
try {
this.filter(new InheritedTestsFilter());
} catch (NoTestsRemainException e) {
throw new IllegalStateException("class should contain at least one runnable test", e);
}
}
/**
*@param-klass
*@throws初始化错误
*@自
*/
公共CustomBaseRunner(类klass)引发初始化错误{
超级(klass);;
试一试{
this.filter(新继承的testsfilter());
}捕获(notestsremaine异常){
抛出新的IllegalStateException(“类应至少包含一个可运行的测试”,e);
}
}
在基本测试类“@测试方法:
assumeTrue(getClass().equals(BaseClassTest.class));
它将忽略子类测试中的那些,但不会完全忽略它们。如果出于任何原因,您需要两个JUnit类来实现相同的功能,对我来说最好的方法是:
- 将公共代码放在父类
中,只包含常量和模拟服务TestFixture
- 创建两个子类:
和TestFixtureA
TestFixtureB
这样,您就不会有重复的代码,也不会重复运行。在JUnit5中,您可以将基类作为抽象类,并使用具体类对其进行扩展
当您在IDE中运行抽象时,您的子类将被执行。这将忽略所有基类,使其基本上无用。使基类抽象?为了向其他人澄清,因为我第一次看到这个答案时不理解它,假设您在基类中有方法
testB
,并用@Test注释,你不希望testB
test在你的子类中运行,然后转到子类,重写这个testB
方法,那么这个测试将不再在你的子类中运行这是没有帮助的,因为@martosler在下面的答案中指出了这一点-有明显的情况(在我的情况下,针对不同浏览器的Selenium测试)这是一个非常糟糕的建议。有时你需要相同的行为;只是子类之间“SUT”变量的设置不同。@MikeBurton-事实上,这是一个很好的建议,尽管Bozho的建议可能并不明显。你需要做的是重构基类,提取应该重用到新类中的代码,(摘要)proto基类。然后,您的新测试类将扩展proto基类,而不是我们所称的基类。这将是一个遵循LSP和一般规则的好例子,即您永远不应覆盖具体实现。如果您不介意违反这些规则,您可以按照我下面的建议进行操作。我不采取行动我知道为什么我在七月份就反对这个,这正是我想要的解决方案