2011-10-11 69 views
0

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

  1. test1间接导致某些classA将classA.somestaticMember设置为xyz值。测试obj不直接维护对classA的任何引用 - 但是当test1结束时,classA仍然由vm通过值xyz加载。
  2. test2访问classA并跳到某个具有xyz值的静态成员上。

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

+1

如果您的测试依赖于执行顺序而失败,那么它们并不是真正的单元测试。那,或者你没有利用夹具。 – cHao

回答

1

你可以声明的方法与@Before,像

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

和JUnit将在每次测试之前运行它。你可以用它来建立一个“夹具”(一组已知的新对象,数据等,你的测试可以独立工作)。

还有一个@After,你可以使用进行任何清理,每次测试后。您通常不需要这样做,因为Java将清理您使用的任何对象,但它可能对于将外部对象(您不创建和控制的对象)恢复到已知状态很有用。 (注意,如果你为了做测试而依赖外部对象,那么你所拥有的不再是单元测试,你不能真正说出失败是由于你的代码或外部对象,这是单元测试的目的之一)。

+0

我同意 - 它不是“单元”测试。自从我使用完整的外部对象以来,它更多地是功能/集成测试。不过,我对这件事没有多少发言权。只有HAVING测试是一个巨大的改进,而不是没有。我正在使用junit 3.8和setup和teardown方法,但对于外部对象,我该如何重新初始化? – treefrog

+0

@treefrog:取决于你的DI框架和/或你的对象。您需要能够用已知的新物体替换物体,或者在必要时手动“重置”现有物体。例如,如果您的外部对象是数据库,请删除所有旧数据,然后插入足够的数据以进行所有测试。或者对于文件,删除文件或放回或用已知版本替换它。对于网络的东西,关闭连接并重新启动它。重点是,*撤消任何副作用*您的测试可能导致 - 每个测试的环境应该完全相同。 – cHao

+0

是的,我明白这是我需要做的 - 我正在寻找方法来完成 - junit提供了一种方法来指定一个单独的类加载器来加载测试吗?或者可能是我需要遍历所有由类加载器加载的类并通过反射进行清理 - 我想不出任何其他方式 – treefrog