JUnit:在调用每个@Test方法之前的新实例。有什么好处?

2022-09-01 17:15:13

目前,我正在阅读“JUnit in Action”一书。在这本书中,我发现了下面的文字:

JUnit 在调用每个@Test方法之前,会创建测试类的新实例。这有助于在测试方法之间提供独立性,并避免测试代码中无意的副作用。由于每个测试方法都在新的测试类实例上运行,因此我们无法在测试方法中重用实例变量值。

现在我不认为这种方法有什么意义:

例如:

public class CalculatorTest {
    @Test
    public void testAdd_1() {
        Calculator calculator = new Calculator();
        double result = calculator.add(1, 1);
        assertEquals(2, result, 0);
    }

    @Test
    public void testAdd_2() {
        Calculator calculator = new Calculator();
        double result = calculator.add(2, 2);
        assertEquals(4, result, 0);
    }
}

对于测试类计算器测试没有任何好处。

好吧,让我们注意另一个例子:

public class OneTest {

    static byte count;

    public OneTest() {
        count++;
    }

    @Test
    public void test1() {
        System.out.println(count);
    }

    @Test
    public void test2() {
        System.out.println(count);
    }
}

对于测试类OneTest,我找到了一种方法,可以对许多测试方法使用相同的变量计数...

那么,如何看到书中描述的方法的真正好处呢?


答案 1

如何看待书中描述的方法的真正好处?

单独实例的目的不是为了任何好处,而是为了维护每个测试都应该独立执行的契约,而不受执行先前测试的任何影响。除了为每个测试使用不同的实例之外,没有其他方法可以确保此协定。

例如,默认情况下,Spring 事务管理确保通过测试回滚对数据库所做的所有更改,以维护相同的协定。

因此,通常不鼓励在测试中使用静态变量,因为它会破坏每个测试一个实例的整个目的,即为每个测试提供一个干净的石板。


答案 2

保持测试方法之间的状态干净对于单元测试很有用,但对于功能测试来说会妨碍,在功能测试中,测试之间通常需要依赖关系(例如,当您使用Selenium测试网页时,如果登录页面的测试失败,则不要打扰运行某个页面的测试是很有用的)。

这是我创建TestNG的主要原因之一,它不会在每个方法之间实例化一个新类,因此给你选择,而不是把这个决定强加给你。

TestNG还支持测试的依赖性,多线程测试,具有组的概念(“仅运行servlet测试”)以及更多功能。


推荐