在JUnit测试用例中指定执行顺序

cra*_*liv 19 java junit4

我有一个测试用例,我添加一个实体,更新它并删除它.因此,执行顺序在这里很重要.我希望它是:

  1. 创建
  2. 更新
  3. 删除

奇怪的是,对于一个测试用例(15个中),JUnit按以下顺序执行:

  1. 删除
  2. 更新
  3. 创建 .

如何告诉JUnit以特定顺序执行它们?在其他情况下,JUnit完全正常(串行执行).为什么JUnit在这种情况下表现得很奇怪?

以下相关代码段:

    private static Date date;
    private static int entity;
    static Parking p;
    public ParkingTests(String name) {
       super(name);
    }
    public void testAdd() throws Exception {
           //Add code here
    }
    public void testUpdate() throws Exception {
            //update code here
    }
    public void testDelete() throws Exception {
            //delete code here
    }
  }
Run Code Online (Sandbox Code Playgroud)

它变得更奇怪了.作为套件的一部分,我运行了很多测试用例.如果我只运行停车箱,则维持订单.如果我和其他人一起运行它,有时会保持,有时不会!

Kul*_*ain 19

通常,junit测试(测试方法)不应相互依赖.以下内容来自junit FAQ

每个测试都在自己的测试夹具中运行,以将测试与其他测试所做的更改隔离开来.也就是说,测试不共享测试夹具中的对象状态.因为测试是隔离的,所以它们可以以任何顺序运行......不保证测试方法调用的顺序.

因此,如果你想做一些常见的初始化工作,那么你可以在注释方法注释的方法中使用@Before和清理方法@After.或者,如果测试类中的所有测试方法都不需要初始化,那么您可以将其放在私有方法中并从测试中适当地调用它们.

另外,如果您仍想进行测试订购,那么您可以查看一下TestNG.


DNA*_*DNA 18

你的情况很尴尬,因为为了隔离测试而保持重复工作感觉很糟糕(见下文) - 但请注意,大多数复制都可以用于setUp和tearDown(@Before,@After)方法,所以你不需要额外的代码.如果测试运行速度太慢而不能经常停止运行,那么最好在清洁测试的名义上浪费一点CPU.

public void testAdd() throws Exception {
      // wipe database
      // add something
      // assert that it was added
}
public void testUpdate() throws Exception {
      // wipe database
      // add something
      // update it
      // assert that it was updated
}
public void testDelete() throws Exception {
      // wipe database
      // add something
      // delete it
      // assert that it was deleted
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是将所有内容都放在一个带有多个断言的测试中,但这很难理解和维护,并且在测试失败时会提供更少的信息:

public void testCRUD() throws Exception {
      // wipe database
      // add something
      // assert that it was added
      // update it
      // assert that it was updated
      // delete it 
      // assert that it was deleted
}
Run Code Online (Sandbox Code Playgroud)

使用数据库或集合或任何类型的存储进行测试是棘手的,因为一个测试总是会通过将垃圾留在数据库/集合中来影响其他测试.即使您的测试没有明确地相互依赖,它们仍可能相互干扰,尤其是当其中一个失败时.

在可能的情况下,为每个测试使用一个新实例,或者擦除数据,理想情况下尽可能简单 - 例如对于数据库,擦除整个表比删除一个非常特定的删除更容易成功,您可能会意外地出错.

更新:通常在测试开始时擦除数据会更好,因此一次测试运行失败不会影响下一次运行.


eis*_*eis 12

如果你确定你想要测试的执行顺序,JUnit 4.11现在通过注释支持这个.有关更多讨论,请参阅此主题 - 基本上,您将使用

@FixMethodOrder
Run Code Online (Sandbox Code Playgroud)

以这种方式保证一些测试订单.但是气馁.


Jos*_*son 7

如果您使用的是Java 7,那么您应该知道Junit使用java.lang.Class中的"Method [] getDeclaredMethods()"获取所有测试的列表.你可以从这个方法的javadoc或junit docs中读取:" 返回的数组中的元素没有排序,也没有按任何特定的顺序排列. "但是在以前的jvm实现方法中,list是按源代码排序的.

这是从这个博客中获取的,他提供了一个解决方案.


小智 5

通常,JUnit不保证测试用例的排序.它不保证按字母顺序排列,也不保证文件中的顺序.如果测试的顺序很重要,那么一个依赖于前一个的输出.如果第一个失败怎么办?我们是否应该为后来的(和依赖的)测试烦恼?可能不是.

所以,如果我们有这个:

@Test
public void first(){...}

@Test
public void second() {...}

@Test
public void third() {...}
Run Code Online (Sandbox Code Playgroud)

我们不知道它们将以什么顺序运行.由于我们希望它们按顺序排列,如果前一个失败,我们应该不会打扰第二个或第三个,我们可以这样做:

@Test
public void firstThree(){
    first();
    second();
    third();
}

public void first(){...}
public void second() {...}
public void third() {...}
Run Code Online (Sandbox Code Playgroud)

请注意,这次我们只有一个@Test,它保证了订购.