【问题标题】:How to deal with interdependent JUnit tests?如何处理相互依赖的 JUnit 测试?
【发布时间】:2011-07-11 23:12:13
【问题描述】:

我有一个关于 JUnit 测试的问题。

我们的 JUnit 套件正在测试我们编写的与内存系统交互的各种函数。

我们系统的设计方式要求它是静态的,因此在运行测试之前进行初始化。

我们遇到的问题是,在运行后续测试时,它们会受到之前测试的影响,因此我们有可能(并且很可能)得到误报或不准确的失败。

有没有办法维护我们的 JUnit 测试的测试顺序,但让它重新初始化整个系统,就像从头开始测试系统一样。

我们能想到的唯一选择是编写一个执行此操作的方法,并在每次测试结束时调用它,但是由于需要以这种方式重置很多东西,我希望有是一种更简单的方法。

【问题讨论】:

  • 另外,编写一个重新初始化的新方法会非常昂贵。
  • 我想我误读了这条评论。您的意思是 开发 成本高昂,运行时间不长 - 对吗?从可测试性的角度来看,您的系统似乎设计得不好——但我敢肯定这是老新闻了。
  • 很抱歉给您带来了困惑。从效率的角度来看,我的意思是成本高昂,例如运行时间更长,实施效率低下。不是从开发的角度来看。
  • 此外,后续测试并不依赖于先前的测试,它们只是受其影响。当我说保持测试顺序时,我的意思是继续运行测试,尽管由于“重置”而出现任何中断。这在可测试性设计中可能仍然存在问题,但由于内存系统是静态的,我真的看不到我目前的障碍。 (@Before @After 标签看起来像我想要的东西,但仅从代码量的角度来看,这似乎更有效。我想我希望的是一些通用的 @Reset 或其他东西。

标签: java unit-testing testing junit


【解决方案1】:

我多次看到测试存在相互依赖的问题(有时是故意的!)。

首先你需要设置一个setUp方法:

@Before
public void setUp() {
    super.setUp();
    // Now clear, reset, etc all your static data.
}

这是由 JUnit 在每次测试之前自动运行的,并将重置环境。您也可以在之后添加一个,但在确保起点干净之前更好。

测试的顺序通常是它们在测试类中的顺序。但这不应该被假设,并且基于它的代码是一个非常糟糕的主意。

返回documentation。如果您需要更多信息。

【讨论】:

  • 如果您提到有助于测试性能的策略,尤其是大型设置和仅用于少数测试的拆解,如果可以的话,我会支持您两次。
  • 提高测试性能的第一个技巧是确保缓慢的测试实际上需要长时间的设置。我经常看到真正的单元测试被编码为集成测试。其次,我的经验是注释驱动的 junit 4.5 不完全支持围绕测试运行的设置,只支持类和测试。所以如果你有真正的问题,你必须回到 3.8 TestSuites。很多都归结为您实际尝试做的事情。例如,内存数据库和 Web 服务器可以加速集成测试。
  • 谢谢你,我想这正是我所需要的。 :)
【解决方案2】:

我对这类问题采取的方法是在每次测试之前进行部分重新初始化。每个测试都知道它需要的先决条件,并且设置确保它们是真实的。不确定这是否与您相关。依赖顺序通常最终会成为一个持续的 PITA——能够自己运行测试会更好。

哦,是的 - 有一个“测试”作为负责静态初始化的套件的开始运行。

【讨论】:

  • 您为什么不使用设置方法或等效方法?
  • @Arafangion - 是的 - 和 Anuj 一样 - 每次测试都非常昂贵。此外,就我而言,它正在进行一些相对冗长的数据库初始化,如果我只是调试一个测试,我不需要重做。另外,我喜欢使用一些测试风格的验证来确保正确执行。在我的情况下,我也怀疑在 Anuj 的情况下,我正在做集成测试——不是真正的单元测试本身——而是使用 JUnit。
  • 那么你有一个(潜在的)设置,其中包含不应该被所有测试使用的逻辑。与测试无关的逻辑令人困惑,并建议您需要设置另一个测试套件。然而,没有什么比显然依赖于其他测试的测试更令人困惑的了。
  • @Arafangion - 这有点宗教化。所有测试都需要数据库设置 - 只是不经常,当然在运行每个测试时也不需要。在 Hudson 领导下,它每天作为 CI 套件的一部分运行几次,因为在那里时间不是问题。否则,我只在明确需要运行时才运行它。
  • 我同意这些主题变得宗教化! :) 我只是认为数据库设置应该只用于那些需要它的测试 - 你说它是“所有测试都需要的”,但是你自相矛盾并说它只是不经常,当然不是运行每个测试时”。
【解决方案3】:

你可能想看看TestNG,它支持这种功能测试的测试依赖(JUnit 是一个单元测试框架):

@Test
public void f1() {}

@Test(dependsOnMethods = "f1")
public void f2() {}

【讨论】:

    猜你喜欢
    • 2012-03-28
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 2018-10-19
    相关资源
    最近更新 更多