Junit 是否通过每个测试方法调用重新初始化类?

2022-09-01 18:20:58

当我运行下面的代码时,两个测试用例都成真了:

import static junit.framework.Assert.assertEquals;

import org.junit.Test;

public class MyTest{
    private int count;

    @Before
    public void before(){
        count=1;
    }

    @Test
    public void test1(){
        count++;
        assertEquals(2, count); 
    }

    @Test
    public void test2(){
        count++;
        assertEquals(2, count); 
    }
}

预期行为

  1. 测试 1 - 成功
  2. test2 - 失败(如预期,计数将变为 3)

实际行为

  1. 测试 1 - 成功
  2. test2 - 成功

为什么 junit 与每个测试方法调用。它是 junit 中的一个错误,或者是故意提供的。reinitializing class/variable


答案 1

这是因为测试隔离。

任何测试都不应依赖于另一个测试。


答案 2

每个测试方法的新实例MyTest

对于每个测试方法,将创建一个新的实例,这是 Junit 的行为。MyTest

因此,在你的情况下,对于这两种方法,变量将具有值,因此 的值将同时用于测试方法,因此测试用例通过。count1count++2

public class MyTest{
   public MyTest(){
      // called n times
      System.out.println("Constructor called for MyTest");
   }

   @Before //called n times
   public void setUp(){
      System.out.println("Before called for MyTest");
   }
    
   //n test methods
}

如果使用 2 种测试方法执行上述代码:

输出将为:

Constructor called for MyTest
Before called for MyTest
//test execution
Constructor called for MyTest
Before called for MyTest

编辑:

与F.I.R.S.T测试原理隔离

测试框架可以帮助您做正确的事情,单元测试的一个非常重要的属性是隔离

通过为每个测试方法创建一个新实例,脏的SUT被丢弃。因此,我们每次测试都有一个新的状态。

阅读有关F.I.R.S.T测试原理的信息。


推荐