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

时间:2012-03-02 05:42:12

标签: java junit4

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

  1. 创建
  2. 更新
  3. 删除
  4. 奇怪的是,对于一个测试用例(15个中),JUnit按以下顺序执行:

    1. 删除
    2. 更新
    3. 创建。
    4. 如何告诉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
          }
        }
      

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

6 个答案:

答案 0 :(得分:19)

一般来说,junit测试(测试方法)不应相互依赖。 以下摘自junit FAQ

  

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

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

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

答案 1 :(得分:18)

您的情况 尴尬,因为为了隔离测试而不断重复工作感觉很糟糕(见下文) - 但请注意,大部分复制都可以提取到{{ 1}}和setUptearDown@Before)方法,因此您不需要额外的代码。如果测试运行速度太慢而不能经常停止运行,那么最好在清洁测试的名义上浪费一些CPU。

@After

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

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
}

使用数据库或集合或任何类型的存储进行测试是棘手的,因为一个测试总是可以通过将垃圾留在数据库/集合中来影响其他测试。即使你的测试没有明确地依赖彼此,它们仍然可能互相干扰,特别是如果其中一个失败了。

在可能的情况下,为每个测试使用一个新实例,或者以尽可能简单的方式擦除数据 - 例如对于数据库而言,擦除整个表的可能性比您可能意外出错的非常具体的删除更有可能。

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

答案 2 :(得分:12)

如果您确定要为测试执行命令,JUnit 4.11现在通过注释支持此操作。有关更多讨论,请参阅this thread - 基本上,您可以使用

@FixMethodOrder

以这种方式保证一些测试订单。但不鼓励这样做。

答案 3 :(得分:7)

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

这是从blog获取的,他提供了解决方法。

答案 4 :(得分:5)

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

所以,如果我们有这个:

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

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

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

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

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

public void first(){...}
public void second() {...}
public void third() {...}

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

答案 5 :(得分:1)

你能做什么:

  • 每次测试前清理数据库
  • 首先测试第一个逻辑操作。如果你有足够的信心,假设它是正确的,并移动到下一个,等等......
  • 首先编写白盒测试,但从黑盒测试开始。例如,如果您的数据库中有触发器或类似触发器,请从此开始。