背景
テストコードはあってもどのようなケースを想定しているのかわからない。
少しでも頑張らなくて良くなるテストコードとなる様にはどうすれば良いかを検討している。
※これは検討中のメモです
※コードは適当です(動きません)
課題
- どんなケースを想定したテストなのかがわからない
- 十分なケースかわからない
- 愚直過ぎて解析が辛い
解消案検討
1. どんなケースを想定したテストなのかがわからない
詳細
- テストケースの説明がない or 情報が不十分
- コードを解析しないといけない
検討案
- docにケースの説明を記載する
/**
* 説明: xxx
* 設定値: yyy
* 期待値: zzz
*/
@Test
public void testXXX() {}
2. 十分なケースかわからない
詳細
- テストケースの全量がない
- 全てのケースを解析するしかない
検討案
- テストコード設計しましょう
※方針は検討中 - コード中にテストケースのサマリを記載する
3. 愚直過ぎて解析が辛い
詳細
- 各テストメソッドで、モック作成・期待値作成・テスト対象実行・アサーションなどなどほぼ全てをやっている
検討案
- テストメソッドは、テスト対象実行とアサーションを役割とさせる
- モックや期待値などのデータは外部に任せる
- アサーションはオブジェクト単位で実行する
HogeTest.java
class HogeTest {
@Test
public void success_XX取得 {
/* データ生成 */
Fixture fixture = Fixture.BASIC;
TargetStruct expected = fixture.getExpected();
/* テスト実行 */
Hoge hoge = new Hoge();
TargetStruct actual = hoge.getXX();
assertEquals(expected, actual);
}
}
Fixture.java
/**
* データパターンはここで定義する
* →expected だけだが、必要な情報は増やしていく
* データを定義するのはモデル側に任せてしまう
* →状況に応じて面倒な処理をここに定義してもOK
*/
public enum Fixture {
BASIC(ExpectedStructA.class);
@Get
private TargetStruct expected;
private Fixture(Class expected) {
this.expected = new expected();
}
}
ExpectedStructA.java
/**
* クラスが増えるけど許容する
* →どこかで面倒なことをしないといけないので、ここに集約する
*/
public class ExpectedStructA extends TargetStruct {
public void ExpectedStructA() {
this.id = 1;
this.name = "hoge";
}
}
番外
検討案
- テストメソッド命名規則
- [success|failure]_(日本語で説明)
- ex) success_対象データが1件
- [success|failure]_(日本語で説明)
- privateメソッドのテストケース実施を許容
- 規模にもよるが楽になるなら全然OK