我遇到了一些问题,有一些非常先进的单元测试(使用PowerMock进行模拟和JUnit 4.5)。在没有详细介绍的情况下,测试类的第一个测试用例将始终成功,但同一测试类中的任何后续测试用例都会失败。但是,如果我选择仅运行10中的测试用例5,它将通过。所以所有测试都在单独运行时通过。有没有办法强制JUnit一次运行一个测试用例?我从一个蚂蚁脚本中调用JUnit。
我知道依赖测试用例的问题,但我无法确定原因。测试用例中没有保存的变量,因此@Before注释无需执行任何操作。这就是为什么我正在寻找一种紧急解决方案,比如强制JUnit单独运行测试。
答案 0 :(得分:14)
我知道所有的建议,但最终在这里回答你的问题是一种实现你想要的简单方法。只需将此代码放入测试用例中即可:
Lock sequential = new ReentrantLock();
@Override
protected void setUp() throws Exception {
super.setUp();
sequential.lock();
}
@Override
protected void tearDown() throws Exception {
sequential.unlock();
super.tearDown();
}
这样,在获取锁定之前不能开始测试,并且一次只能获取一个锁定。
答案 1 :(得分:10)
您的测试用例似乎是依赖的,即:case-X的执行会影响case-Y的执行。应避免使用这样的测试系统(例如:JUnit将无法保证您的案例运行顺序)。
你应该重构你的案件,使它们彼此独立。很多时候使用@Before和@After方法可以帮助你解决这些依赖关系。
答案 2 :(得分:6)
你的问题不是JUnit一次运行所有测试,问题是你没有看到为什么测试失败。解决方案:
示例:
assertEquals(list.toString(), 5, list.size());
答案 3 :(得分:3)
祝贺。你找到了一个bug。 ; - )
如果测试“不应该”相互影响,那么您可能已经发现了代码可能进入损坏状态的情况。尝试添加断言和日志记录以找出代码出错的位置。您甚至可能需要在调试器中运行测试,并在第一次测试后检查代码的内部值。
答案 4 :(得分:2)
对不起,如果我不直接回答你的问题,但问题究竟是TestCase.setUp()和TestCase.tearDown()应该解决的问题吗?这些是JUnit框架在每个测试用例之前和之后始终调用的方法,通常用于确保您以相同的状态开始每个测试用例。
另请参阅TestCase的JavaDoc。
答案 5 :(得分:1)
你应该检查整个代码库,没有引用可变状态的静态变量。理想情况下,程序应该没有静态可变状态(或者至少应该记录它们like I did here)。如果测试写入文件系统或数据库,您应该非常小心清理您所写的内容。否则,运行测试可能会泄漏一些副作用,这使得测试难以独立且可重复。
Maven和Ant包含用于运行JUnit测试的“forkmode”参数,该参数指定每个测试类是否获得自己的JVM,或者所有测试是否在同一JVM中运行。但是他们没有在自己的JVM中运行每个测试方法的选项。
答案 6 :(得分:0)
您的描述告诉我,您的单元测试相互依赖。在单元测试中强烈不推荐。
单元测试必须独立且隔离。你必须能够单独执行它们,所有这些(按顺序,无关紧要)。
我知道,这对你没有帮助。问题出在您的@BeforeClass
或@Before
声明中。会有依赖关系。所以重构它们并试图找出问题所在。
您的模拟可能是在@BeforeClass
中创建的。考虑将其放入@Before
语句中。所以没有比测试用例更长的实例。
答案 7 :(得分:0)
我知道依赖的问题 测试案例,但我无法确定原因 这是。没有保存的变量 跨越测试用例,所以没什么可做的 在@Before注释处做。这就是为什么 我正在寻找紧急解决方案 比如强制JUnit运行测试 单独
@Before语句是无害的,因为每个测试用例都会调用它。 @Before Class 很危险,因为它必须是静态的。
答案 8 :(得分:0)
对我来说,也许并不是说你没有正确设置或拆除你的测试(尽管额外的设置/拆卸可能是解决方案的一部分),但也许你在代码中有共享状态你不知道。如果早期测试正在设置您不知道的静态/单例/共享变量,则后期测试将失败,如果他们没有预料到这一点。即使使用Mocks,这也是非常有可能的。你需要找到这个原因。我同意其他答案,因为你的测试暴露了一个不应该通过尝试以不同方式运行测试来解决的问题。