java 在JUnit测试用例中指定执行顺序[重复]

mbyulnm0  于 2023-05-21  发布在  Java
关注(0)|答案(7)|浏览(201)

此问题已在此处有答案

How to run test methods in specific order in JUnit4?(23答案)
9年前关闭。
我有一个测试用例,我添加一个实体,更新它并删除它。因此,执行的顺序在这里很重要。我希望它是:
1.创建
1.更新
1.删除
奇怪的是,对于一个测试用例(15个中的一个),JUnit按以下顺序执行它:
1.删除
1.更新
1.创造。
如何告诉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
    }
  }

更奇怪的是。我运行了很多测试用例作为一个套件的一部分。如果我只运行Parking案例,则会保持顺序。如果我和其他人沿着运行它,它有时会被维护,有时不会!

xwbd5t1u

xwbd5t1u1#

您的情况很尴尬,因为为了隔离测试而不断重复工作感觉很糟糕(见下文)-但请注意,大多数重复可以提取到setUptearDown@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
}

另一种方法是将所有内容都粘贴到一个具有多个Assert的测试中,但这更难理解和维护,并且在测试失败时提供的信息更少:

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
}

使用数据库或集合或任何类型的存储进行测试都是很棘手的,因为一个测试总是会在数据库/集合中留下垃圾,从而影响其他测试。即使您的测试没有显式地相互依赖,它们仍然可能相互干扰,特别是当其中一个测试失败时。
在可能的情况下,为每个测试使用一个新的示例,或者擦除数据,最好是以尽可能简单的方式进行-例如对于数据库,擦除整个表比您可能意外出错的非常特定的删除更有可能成功。

更新:通常情况下,最好在测试开始时擦除数据,这样一次测试失败不会影响下一次测试。

ff29svar

ff29svar2#

一般来说,junit测试(测试方法)不应该相互依赖。以下内容摘自junit FAQ
每个测试都在自己的测试夹具中运行,以将测试与其他测试所做的更改隔离开来。也就是说,测试不共享测试夹具中对象的状态。因为测试是独立的,所以它们可以以任何顺序运行......不保证测试方法调用的顺序。
因此,如果你想做一些常见的初始化工作,那么你可以在用@Before注解的方法中做,并在用@After注解的方法中做清理。或者,如果测试类中的所有测试方法都不需要初始化,那么您可以将其放在私有方法中,并从测试中适当地调用它们。
顺便说一下,如果你仍然想做测试的排序,那么你可以看看TestNG

vaqhlq81

vaqhlq813#

如果您决定要确定测试的执行顺序,JUnit 4.11现在通过注解支持这一点。有关更多讨论,请参见this thread基本上,您可以使用

@FixMethodOrder

来保证测试秩序但它是令人沮丧的。

7gyucuyw

7gyucuyw4#

如果你使用的是Java 7,那么你应该知道Junit会从java.lang.Class获取所有使用“Method[] getDeclaredMethods()”的测试列表。你可以从这个方法的javadoc或者junit文档中读到:“返回的数组中的元素没有排序,也没有任何特定的顺序。”,但在以前的jvm实现中,方法列表是按源代码中的顺序排列的。
这是从这个blog和他提供了一个工作。

bq9c1y66

bq9c1y665#

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

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

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

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

我们不知道他们会按什么顺序跑。因为我们希望它们按顺序运行,如果前一个失败了,我们可能不应该麻烦运行第二个或第三个,我们可以这样做:

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

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

注意,这次我们只有一个@Test,它保证了有序性。

eulz3vhy

eulz3vhy6#

如果你想按照“就像它们在你的源代码中一样”的顺序运行junit测试,请看我在这里的注解:
How to run junit tests in order as they present in your source code
但这真的不是一个好主意,测试必须是独立的。

s71maibg

s71maibg7#

你可以做的:

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

相关问题