在相同的测试用例或单独的测试用例中测试默认值和设置器


问题内容

您是否建议在@Test方法中对测试用例进行任何分组,还是每个测试方案都有一个@Test方法?例如,假设有多种方法可以在应用程序中设置上下文。

以下想法可以接受吗?

@Test
public void testContextSetting() {
    // Test default setting
    assert(...)

    // Test setting a context variable
    assert(...)

    ...
}

或者,您宁愿建议这样做,让每个方法都尽可能原子化:

@Test
public void textDefaultSetting() {
    // Test default setting
    assert(...)
}

@Test
public void testSettingContextVar() {
    // Test setting a context variable
    assert(...)

    ...
}

对于任何反馈,我们都表示感谢。


问题答案:

我更喜欢每种方法有一个测试用例。

首先,如果将它们拆分为多个方法,则比查找代码中嵌入的注释要容易得多。大多数IDE都会为您提供方法的摘要,因此,您无需说“我是否测试XYZ边缘情况?”。然后寻找注释,或寻找设置该边缘情况的代码,只需寻找名为的方法setupContextEdgeCaseXYZ()

第二个原因是,如果您有多个案例,一个案例可能会失败,而其他案例则永远不会执行。

 testDefaultCase()
 testInvalidInput()
 testEdgeCase1()
 testEdgeCase2()

使用这种结构,可以更容易地确定输入检查不正确并且边缘情况2处理不当,但其他情况都可以(您可能会发现两个失败的情况相关并且可以更快地诊断问题)。

第三个原因是,您可能会不小心留下前一个测试集的值,而这些值会使后一个测试以不显眼的方式失效。一个简单的例子:

@Test
public void testMyMethod() {
  //test default
  String test = Foo.bar(null);
  assertEquals("foo", test);

  //test case 1
  Foo.bar(aValue);
  //Oops forgot to set value above, this passes regardless of 
  //what the above call does
  assertEquals("foo", test);
}

通过区分大小写,可以避免上述错误,因为这会变成编译错误或警告。