【问题标题】:Can I skip a JUnit test while the test is running?我可以在测试运行时跳过 JUnit 测试吗?
【发布时间】:2012-05-02 08:15:43
【问题描述】:

假设我想从我的 IDE(Intellij IDEA 或 eclipse)手动运行 4000 个 JUnit 测试;前 1000 次测试运行得非常顺利(比如全部 1000 次测试需要 3 分钟),但测试 1001 仅需要 30 多分钟。 有没有办法可以跳过测试 1001(当它仍在运行时)并让测试 1002(和其他测试)继续进行。我不想@Ignore 测试 1001 并重新运行套件,因为我已经有了测试 1-1000 的答案;我也不想选择测试 1001-4000,因为它需要太多时间。

我想要某种按钮 - 跳过当前测试 - 可以在测试运行时按下。

如果此类功能不存在,是否需要由 IDE 开发人员或 JUnit 开发人员对其进行增强?

【问题讨论】:

  • 听起来这些测试是集成测试,应该由 CI 解决方案而不是在开发端的 IDE 上运行。特别是如果单个测试需要那么长时间。深入研究并检查为什么需要这么长时间并减少测试的运行时间。单元测试必须快。
  • 确实是这样,但我想首先知道为什么所有失败的测试都失败了(或花费太多),然后继续调查。我不明白为什么 test1 失败(或花费太多)调查 test1 然后看看为什么 test2 失败并调查等等。

标签: java testing junit


【解决方案1】:

对于使用Assume 的JUnit 4,这实际上非常简单。 Assume 是一个类似于 Assert 的辅助类。区别在于Assert 会使测试失败,而Assume 会跳过它。

常见的用例是 Assume.assumeTrue( isWindows() ),用于仅适用于 Windows 文件系统的测试。

所以你可以做的是定义一个系统属性skipSlowTests并添加

Assume.assumeTrue( Boolean.getBoolean("skipSlowTests") )

在您通常想跳过的慢速测试开始时。创建一个 Eclipse 启动配置,将属性定义为 true,您可以方便地在两者之间切换。

如果您想运行慢速测试,请在 Eclipse(或整个类)中选择方法并使用上下文菜单中的“Run as JUnit Test”。由于该属性默认为false,因此将运行测试。

【讨论】:

    【解决方案2】:

    不,如果测试已经在运行,则不能跳过它们。

    我建议您使用Categories 将您的慢速测试与其他测试分开。

    例如:

    public interface SlowTests {
    }
    
    public class MyTest {
    
         @Test
         public void test1{
         }
    
         @Category(SlowTests.class)
         @Test
         public void test1001{
             // this is a slow test
         }
    }
    

    为快速测试创建一个测试套件。

    @RunWith(Categories.class)
    @ExcludeCategory(SlowTests.class)
    @SuiteClasses(MyTest.class)
    public class FastTestSuite {
    
    }
    

    如果您不想运行缓慢的测试(例如 test1001),现在执行 FastTestSuite。如果要运行所有测试,请照常执行MyTest。

    【讨论】:

    • 感谢您的回答。我也想知道您对第二个问题的看法:“如果这样的功能不存在,是否需要 IDE 开发人员或 JUnit 开发人员对其进行增强?”
    • 我想这必须由两个团队来完成。 JUnit 库需要更改测试运行器 API 以允许跳过测试,并且 IDE 需要更改以调用此新 API。
    【解决方案3】:

    您要求的是在测试中期停止执行您的代码。在你的代码中没有钩子来允许它,你不能停止执行当前的测试。您最好的解决方案是按照其他人的建议使用类别。

    基本上,JUnit 执行所有@Before 方法(包括@Rules),然后是您的@Test 方法,然后是@After 方法(同样,包括@Rules)。即使假设 JUnit 有一种机制来停止执行它的代码(它没有),大部分时间都花在你的代码上。因此,要“跳过”已经开始的测试,您需要修改您的测试代码(可能还有它正在测试的代码),以便您可以干净地停止它。完全停止正在执行的线程本身就是一个问题 [*]。

    那么你有什么选择?

    1. 并行运行测试,然后您不必等待测试完成。这可能可行,但并行化测试可能需要大量工作。

    2. 停止执行测试,并修复您正在处理的测试。大多数 IDE 都可以选择终止运行测试的 JVM。这绝对是最简单的选择。

    3. 实现您自己的测试运行程序,它在单独的线程中运行测试。然后,此测试运行程序要么等待线程完成执行,要么检查某处的标志,这将是它停止的信号。这听起来很复杂,因为您不需要管理线程,还需要在正在运行的 jvm 中设置标志。也许在某处创建文件?然后,此运行器将无法通过当前运行的测试,您可以继续进行下一个测试。请注意,中途“停止”测试可能会使某些内容处于不一致的状态,或者您最终可能会并行执行某些内容。

    那里有并行的 JUnit 运行程序,我认为您不会从 IDE 开发人员那里得到太多帮助(至少在短期内)。另外,看看 TestNG,它允许并行运行。

    对于使用类别,我使用的一种解决方案是使用 maven surefire 或类似工具单独运行长时间运行的测试,而不是通过 IDE。这涉及在我机器上的其他地方检查源代码并在那里构建。

    [*]:Java, how to stop threads,Regarding stopping of a thread

    【讨论】:

    • 在 Junit5 中,您实际上可以在代码中间停止测试,请参阅假设* 函数(其他答案)或内部发生的情况:AssumptionViolatedException
    【解决方案4】:

    我认为更常见的解决方案是拥有两个测试套件:一个用于快速测试,另一个用于慢速测试。这通常是您划分单元测试(快)和集成测试(慢)的方式。

    您不太可能因为这样的事情而对 JUnit 或 IntelliJ 进行修改。最好改变你使用它们的方式——它会让你更快地得到答案。

    【讨论】:

      【解决方案5】:

      你可以修改你的想法并做一些类似的事情

      public void theTest(){
          if (System.getProperty("skipMyTest") == null){
               //execute the test
          }
      }
      

      如果要跳过测试,请传递环境变量

      【讨论】:

      • 首先我必须停止测试,修改它们然后重新运行它们。我想在运行时停止它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 2016-01-06
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      相关资源
      最近更新 更多