2

假设我有一个名为的方法foo,对于某些输入值集,预计会成功完成并返回结果,而对于其他一些值集,预计会抛出某个异常。此方法需要先进行一些设置,然后才能对其进行测试。

鉴于这些条件,将成功和失败测试集中在一个测试中是否更好,或者我应该在单独的测试方法中维护这些案例?

换句话说,以下两种方法中哪一种更可取?

方法一:

@Test
public void testFoo() {
  setUpThings();
  // testing success case
  assertEquals(foo(s), y);
  // testing failure case
  try {
    foo(f);
    fail("Expected an exception.")
  } catch (FooException ex) {
  }
}

方法二:

@Test
public void testFooSuccess() {
  setUpThings();
  assertEquals(foo(s), y);
}

@Test
public void testFooFailure() {
  setUpThings();
  try {
    foo(f);
    fail("Expected an exception.")
  } catch (FooException ex) {
  }
}
4

5 回答 5

5

最好采用方法#2。

为什么:

好吧,当断言失败时,不会评估该方法的其余部分……因此,通过将测试放在 2 个单独的方法中,您可以确保至少执行两个测试……失败与否。

单元测试不仅应该关注一个特定的单元,还应该关注该单元的一个特定行为。一次测试多种行为只会使水变得浑浊。花时间将每个行为分成自己的单元测试。

于 2012-11-02T17:03:56.623 回答
3

方法 3(2 的扩展)

@Before
public void setUpThings() {
  ...
}

@Test
public void testFooSuccess() {
  assertEquals(foo(s), y);
}

@Test(expected=FooException.class)
public void testFooFailure() {
  foo(f);
}

我很高兴有一次只练习一个条件的集中测试,因此失败的测试只能意味着一件事(方法 2)。如果它们都使用相同的设置,您可以将其移至通用设置方法 ( @Before)。如果没有,也许最好考虑将相关的案例分成不同的类,这样你不仅有更专注的案例(方法),还有更专注的固定装置(类)。

于 2012-11-02T17:11:44.930 回答
2

我喜欢方法#2。单独测试更好。

我不喜欢你做测试 2 的方式。这就是我要做的:

@Test(expected = FooException.class)
public void testFooFailure() {
  setUpThings();
  foo(f);
}
于 2012-11-02T17:02:41.807 回答
1

对我来说,方法 2 更可取。因为您首先测试快乐路径然后失败条件。如果有人需要测试快乐的场景,只有你会拥有它。

于 2012-11-02T17:06:34.073 回答
1

将测试用例分开更好有两个原因:

  1. 你的测试用例应该是原子的
  2. 如果第一个断言条件失败,它将不会评估第二个。
于 2012-11-02T17:06:44.330 回答