【问题标题】:how to troubleshoot intermittent junit test failures?如何解决间歇性junit测试失败?
【发布时间】:2011-10-11 00:28:53
【问题描述】:

我正在处理我的测试根据声明顺序通过或失败的情况。这当然指向没有正确隔离的测试。但我对如何寻找问题感到困惑。 问题是我的 junit 测试派生自一个类,该类属于基于 junit 构建的测试框架并具有一些依赖注入容器。容器通过基类设置为每个测试重置,因此至少在容器中没有延迟对象,因为容器本身是新的。所以我倾向于以下场景。

  1. test1 间接导致一些 classA 将 classA.somestaticMember 设置为 xyz 值。 test obj 不直接维护对 classA 的任何引用,但是当 test1 结束时,vm 仍然会加载 classA,其值为 xyz。
  2. test2 访问 classA 并在一些具有 xyz 值的静态成员上绊倒。

问题是 a) 我不知道这是否确实如此——我该如何找到它?我似乎无法在代码中找到对静态变量的引用... b) 有没有办法告诉 junit 转储所有已加载的类并为每个测试方法重新执行?

【问题讨论】:

  • 如果您的测试因执行顺序而失败,那么它们就不是真正的单元测试。那,或者你没有利用固定装置。

标签: dependency-injection junit isolation


【解决方案1】:

你可以用@Before声明一个方法,比如

@Before public void init()
{
    // set up stuff
}

JUnit 会在每次测试之前运行它。您可以使用它来设置“夹具”(一组已知的新对象、数据等,您的测试将相互独立地使用它们)。

还有一个@After,您可以在每次测试之后使用它来进行任何所需的清理工作。您通常不需要这样做,因为 Java 会清理您使用的任何对象,但它对于将外部对象(您不创建和控制的东西)恢复到已知状态可能很有用。

(但请注意:如果您依赖外部对象来进行测试,那么您所拥有的就不再是单元测试了。您不能真正说失败是由于您的代码还是由于外部对象,这是单元测试的目的之一。)

【讨论】:

  • 我同意 - 它不是“单元”测试。它更多的是功能/集成测试,因为我使用的是完整的外部对象。不过,我在这件事上没有太多发言权。与没有相比,仅进行测试是一个很大的改进。我正在使用 junit 3.8 和 setup 和 teardown 方法,但是对于外部对象我该如何重新初始化?
  • @treefrog:取决于您的 DI 框架和/或您的对象。您需要能够用已知的新对象替换对象,或者“重置”现有对象——如有必要,手动进行。例如,如果您的外部对象是数据库,请删除所有旧数据,然后插入足够的数据来进行所有测试。或者对于文件,删除文件或将其放回原处或将其替换为已知版本。对于网络的东西,关闭连接并重新启动它。关键是,撤消任何副作用您的测试可能导致 - 每个测试的环境应该完全相同。
  • 是的,我知道这是我需要做的——我正在寻找实现这一目标的方法——junit 是否为我提供了一种方法来指定一个单独的类加载器来加载测试?或者我可能需要遍历类加载器加载的所有类并通过反射清理它 - 我想不出任何其他方式
猜你喜欢
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 2021-05-27
  • 2018-11-11
  • 2018-11-09
  • 2019-04-18
  • 2011-10-21
  • 1970-01-01
相关资源
最近更新 更多