Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JUnit4中有条件地忽略测试_Java_Unit Testing_Junit_Ignore - Fatal编程技术网

Java 在JUnit4中有条件地忽略测试

Java 在JUnit4中有条件地忽略测试,java,unit-testing,junit,ignore,Java,Unit Testing,Junit,Ignore,好的,@Ignore注释用于标记不应该运行测试用例 但是,有时我希望忽略基于运行时信息的测试。例如,如果我有一个并发测试,它需要在具有一定数量内核的机器上运行。如果这个测试是在单处理器机器上运行的,我认为仅仅通过测试是不正确的(因为它还没有运行过),而且测试失败并破坏构建肯定是不对的 因此,我希望能够在运行时忽略测试,因为这似乎是正确的结果(因为测试框架将允许构建通过,但记录测试未运行)。我相当肯定注释不会给我这种灵活性,并且怀疑我需要为讨论中的类手动创建测试套件。但是,文档中没有提到这方面的任

好的,
@Ignore
注释用于标记不应该运行测试用例

但是,有时我希望忽略基于运行时信息的测试。例如,如果我有一个并发测试,它需要在具有一定数量内核的机器上运行。如果这个测试是在单处理器机器上运行的,我认为仅仅通过测试是不正确的(因为它还没有运行过),而且测试失败并破坏构建肯定是不对的

因此,我希望能够在运行时忽略测试,因为这似乎是正确的结果(因为测试框架将允许构建通过,但记录测试未运行)。我相当肯定注释不会给我这种灵活性,并且怀疑我需要为讨论中的类手动创建测试套件。但是,文档中没有提到这方面的任何内容,并且通过查看也不清楚如何以编程方式实现这一点(即,如何以编程方式创建
Test
或类似的实例,该实例等同于
@Ignore
注释所创建的实例?)

如果有人在过去做过类似的事情,或者对我如何做这件事有一个很好的想法,我很高兴听到这个消息。

你应该检查这个项目。它们具有执行条件测试的
RunIf
注释,如:

@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

class DatabaseIsConnected implements Checker {
   public boolean satisify() {
        return Database.connect() != null;
   }
}

[从他们的教程中获取的代码示例]

JUnit方法是在运行时执行此操作

 @Before
 public void beforeMethod() {
     org.junit.Assume.assumeTrue(someCondition());
     // rest of setup.
 }
您可以在
@Before
方法或测试本身中执行,但不能在
@After
方法中执行。如果在测试本身中执行此操作,则将运行
@Before
方法。您还可以在
@BeforeClass
中执行此操作,以防止类初始化

假设失败会导致忽略测试。

编辑:与junit ext中的
@RunIf
注释相比,它们的示例代码如下所示:

@Test
public void calculateTotalSalary() {
    assumeThat(Database.connect(), is(notNull()));
    //test code below.
}
public class CustomRunner extends BlockJUnit4ClassRunner {
    public CTRunner(Class<?> klass) throws initializationError {
        super(klass);
    }

    @Override
    protected boolean isIgnored(FrameworkMethod child) {
        if(shouldIgnore()) {
            return true;
        }
        return super.isIgnored(child);
    }

    private boolean shouldIgnore(class) {
        /* some custom criteria */
    }
}

更不用说通过这种方式从
数据库捕获和使用连接要容易得多。connect()
方法。

快速提示:
假设。假设真(条件)
忽略其余步骤,但通过了测试。
要使测试失败,请在条件语句中使用
org.junit.Assert.fail()。与
假设.assumeTrue()
的工作原理相同,但测试失败。

在JUnit 4中,您的另一个选项可能是创建一个注释,表示测试需要满足您的自定义条件,然后使用您自己的反射扩展默认运行程序,并根据自定义条件做出决定。它可能看起来像这样:

@Test
public void calculateTotalSalary() {
    assumeThat(Database.connect(), is(notNull()));
    //test code below.
}
public class CustomRunner extends BlockJUnit4ClassRunner {
    public CTRunner(Class<?> klass) throws initializationError {
        super(klass);
    }

    @Override
    protected boolean isIgnored(FrameworkMethod child) {
        if(shouldIgnore()) {
            return true;
        }
        return super.isIgnored(child);
    }

    private boolean shouldIgnore(class) {
        /* some custom criteria */
    }
}
公共类CustomRunner扩展了BlockJUnit4ClassRunner{
公共CTRunner(类klass)引发初始化错误{
超级(klass);;
}
@凌驾
受保护的布尔值isIgnored(FrameworkMethod子级){
if(shouldIgnore()){
返回true;
}
返回super.isIgnored(子级);
}
私有布尔shouldingore(类){
/*一些自定义标准*/
}
}
除了@tkruse和@Yishai的答案之外:
我这样做是为了有条件地跳过测试方法,特别是对于
参数化的
测试,如果测试方法应该只针对一些测试数据记录运行

public class MyTest {
    // get current test method
    @Rule public TestName testName = new TestName();
    
    @Before
    public void setUp() {
        org.junit.Assume.assumeTrue(new Function<String, Boolean>() {
          @Override
          public Boolean apply(String testMethod) {
            if (testMethod.startsWith("testMyMethod")) {
              return <some condition>;
            }
            return true;
          }
        }.apply(testName.getMethodName()));
        
        ... continue setup ...
    }
}
公共类MyTest{
//获取当前测试方法
@规则public TestName TestName=new TestName();
@以前
公共作废设置(){
org.junit.aspect.assumeTrue(新函数(){
@凌驾
公共布尔应用(字符串测试方法){
if(testMethod.startsWith(“testMyMethod”)){
返回;
}
返回true;
}
}.apply(testName.getMethodName());
…继续安装。。。
}
}

@notnoop,这根本不是我的观察结果。他们被忽视了。IDEA测试运行者就是这样报告的,查看JUnit源代码可以发现它报告的测试被忽略了。引用:“在将来,这可能会改变,失败的假设可能会导致测试被忽略。”事实上,从4.5开始,它已经改变了。当前的javadoc说:“默认的JUnit运行程序会将假设失败的测试视为忽略。自定义运行程序的行为可能会有所不同。”带有JUnit 4.8.1的Eclipse 3.6会将错误假设报告为通过测试。与ant 1.8.1相同,Eclipse报告失败的假设,因为传递是一个bug:@JeffStorey,那么您正在寻找一些东西。一个是
@BeforeClass
注释,您可以在这里假设失败,这将跳过整个课程。另一个是
@ClassRule
(用于细粒度控制,但只对整个类进行一次)。感谢您的回答-这是一个有趣的功能替代语法,尽管我将直接使用
假设
,以免引入另一个依赖项。我个人更喜欢此解决方案。如果您有许多测试应该基于相同的条件运行,那么这将比在每个测试中都必须使用Aspect更为理想。此外,如果这可以在类级别而不是方法级别上使用,它将更加理想。我更喜欢它,因为这有助于在运行时有条件地运行测试。它适用于许多单元测试将要运行的地方,并且要求在特定的检查器上运行单元测试。看到maven存储库中没有JUnitExt,我真的很惊讶。我们如何在maven项目中利用这一点。类似于
@RunIf
的注释将测试应该运行的条件与实际测试代码分开,我认为这很好。我不喜欢的是它需要一个特定的测试运行程序。因此,我编写了一个有条件地忽略测试的方法。。。没有什么