我正在使用junit和eclipse来编写函数测试。
运行单个测试时,它按照我在类中设置的顺序运行。
例如
testCreateUser
testJoinUserToRoom
testVerify
testDeleteUser
但是,当我将此测试作为套件的一部分运行时(因此在包中),订单是随机的。
例如,它将执行验证,然后删除用户,然后是joinuserToRoom,然后是Createuser。
套件内的测试不依赖于彼此。但是,测试中的每个单独测试都取决于它们是否以正确的顺序运行。
有什么方法可以实现这个目标吗?
感谢。
答案 0 :(得分:6)
您无法保证在JUnit中执行测试方法的顺序。
套件中测试类的执行顺序是保证(如果您使用的是Suite),但是测试时执行的顺序通过反射找到的类不是(例如,如果您在Eclipse中运行包,或者从maven或ant运行一组测试)。这可以通过ant或maven定义,但它不是由JUnit定义的。
通常,JUnit按照源文件中定义的顺序执行测试方法,但并非所有JVM都能保证这一点(特别是JVM 7)。如果某些方法是从抽象基础测试类继承的,那么这可能也不成立。 (这听起来像你的情况,但我无法从你的描述中说出来。)
有关详细信息,请参阅我对Has JUnit4 begun supporting ordering of test? Is it intentional?的回答。
那么你可以做些什么来解决你的问题呢?有两种解决方案。
在您的原始示例中,您实际上只有一个测试(验证),但您有4个方法,两个设置(createUser,joinUserToRoom)和一个拆卸(deleteUser)。因此,您的第一个选择是使用TestRule更好地定义测试用例,尤其是ExternalResource。 ExternalResource
允许您定义测试的前/后行为,类似于@Before/@After
。但是,ExternalResource
的优势在于您可以将其考虑在内。
因此,您将在外部资源中创建/删除用户:
public class UsesExternalResource {
@Rule
public ExternalResource resource= new ExternalResource() {
@Override
protected void before() throws Throwable {
// create user
};
@Override
protected void after() {
// destroy user
};
};
@Test
public void testJoinUserToRoom() {
// join user to room
// verify all ok
}
}
对我来说,这更容易理解,你可以获得独立测试,这是一件好事。这就是我要做的,但你需要稍微重构一下你的测试。您还可以使用RuleChain堆叠这些规则。
如果您真的想在测试方法之间引入依赖关系,那么您的第二个选择是查看TestNG,您可以在其中定义从一个测试到另一个测试的依赖关系。
答案 1 :(得分:0)
如果他们有'正确'的顺序,那么他们不是多次测试,而是一次你错误地注释为多次独立测试的测试。
最佳做法是以经过批准的junit样式(setup - act - verify)重写它们,由@Before或@BeforeClass方法支持,这些方法执行任何所需的常见设置。
快速解决方法是使用单个@ Test-annotated方法按顺序调用其他测试方法。如果您使用Junit不进行严格的单元测试,那么这就变成了首选的替代方案,但更像是情景驱动的系统测试。它不一定是这种用途的最佳工具,但在某些情况下它确实能很好地工作。
然后,你到目前为止只有一个测试:
@Test public void testUserNominalLifeCycle(...
然后,如果你感觉良性,可以通过额外的新测试补充,如
@Test public void testUserWhoNeverJoinsARoom(...