2

foo特定の入力値のセットについては正常に完了して結果を返すことが期待され、他の値のセットについては特定の例外をスローすることが期待されるという名前のメソッドがあるとします。この方法をテストするには、いくつかの設定が必要です。

これらの条件を考えると、1 つのテストで成功と失敗のテストをクラブ化する方がよいでしょうか?それとも、これらのケースを別々のテスト方法で維持する必要がありますか?

言い換えれば、次の2つのアプローチのどちらが望ましいでしょうか?

アプローチ 1:

@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) {
  }
}

アプローチ 2:

@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つの別々のメソッドに入れることで、少なくとも両方のテストを実行することができます..失敗するかどうか。

単体テストは、特定の 1 つのユニットに焦点を当てるだけでなく、そのユニットの特定の 1 つの動作に焦点を当てる必要があります。一度に複数の動作をテストしても、水が濁るだけです。時間をかけて、各動作を独自の単体テストに分けてください。

于 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);
}

一度に 1 つの条件のみを実行する焦点を絞ったテストを用意して、失敗したテストが 1 つのことしか意味しないようにすることをお勧めします (アプローチ 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

次の 2 つの理由から、テスト ケースをより適切に分離します。

  1. テストケースはアトミックでなければなりません
  2. 最初の assert 条件が失敗した場合、2 番目の assert 条件は評価されません。
于 2012-11-02T17:06:44.330 に答える