t0mmy

2020年12月30日に参加

学習履歴詳細

単体テスト考え方/使い方 3章

やったこと

  • 単体テスト考え方/使い方 3章 読了

学び

  • テストは Arrange(準備)/Act(実行)/Assert(確認) の3フェーズ(以降AAA)で構成すること
  • 単体テストのテストケースでは、必ず一つの振る舞いだけテストすること
    • 実行フェーズや確認フェーズが複数ある場合、テストを分割すること
    • 実行フェーズが複数行の場合は、カプセル化に失敗している可能性を示唆している
    • 一方で、「実行フェーズを一行に収めること」を強制するべきではない
    • if 文を含む単体テストはアンチパターン
    • if 文が不要なくらい、単純なケースをテストするべき
  • テストメソッドの名前に「should」を用いるのはアンチパターン
    • テストメソッド名に希望や要望(つまりshould)を含めるべきではない
    • 希望や要望ではなく、事実(~である、つまり「is」の方が適切

気付き

  • コメントで AAA を明示するとよさそう
    • 空行だと、準備フェーズを分けにくそう(Aの準備、Bの準備、AとBを使用してCの準備 ... など)
  • 分かりやすい=>メソッド名と引数で、何をするメソッドか一発で理解できること
    • 言い換えると、メソッドの実装コードを見なくても、実装をイメージできるようなメソッド名・引数となっていること
  • テストメソッドの名付けに、実装に強く依存する(名前に、テスト対象のメソッド名を含むなど)ような厳格な命名規則を用いると、テストコードの保守性低下に繋がる
  • パラメータ化する際は、「よくあるユースケースの正常系」「よくあるユースケースの異常系」「その他エッジケース」の3つぐらいがよさそう

まとめ

  • 必ず Arrange/Act/Assert の流れ!
  • Act は1行!
    • 複数行の場合、何らかの依存を疑うこと
  • テスト対象システムを簡単に識別できるようにすること
  • fixture を活用する事
  • テストメソッドは、非開発者にも伝わるような名前に!
  • パラメータ化を活用する
  • 「確認したいこと」を、より明確に表現できるライブラリ有り。必要に応じて活用する
    • Fluent Assertions

メモ

AAA

  • テストは Arrange(準備)/Act(実行)/Assert(確認) の3フェーズ(以降AAA)で構成すること
  • 単体テストのテストケースでは、必ず一つの振る舞いだけテストすること
    • 実行フェーズや確認フェーズが複数ある場合、テストを分割すること
    • 実行速度の維持
    • 目的の明確化(この場合、テストで確認したいこと)
    • AAA 以外のフェーズが許されるのは、統合テストぐらい
    • if 文を含む単体テストはアンチパターン
    • if 文が必要なほど、複雑なケースをテストしている、と捉える
    • if 文が不要なくらい、単純なケースをテストするべき

テスト・フィクスチャ

  • 「準備フェーズのコードを切り出し、再利用する」というのは良い考え方
    • 「外部結合のmock化」など、全テストケース共通の処理は、コンストラクタがOK
    • 上記以外はファクトリやヘルパークラス・メソッドの活用が吉(※)
    • (※)「全テストケース共通の処理」以外でコンストラクタを利用することは、以下の二つの理由で非推奨
    • コンストラクタコードとテストコードの結びつきが強くなってしまう
      • テストAのために準備フェーズのコード(≒コンストラクタ)を変更すると、他のテストケースも影響を受けてしまう
    • テストケースの可読性が低下する

テストメソッドの命名

  • テストメソッドの名前には、「確認(検証)したいこと」や「振る舞い」に焦点を当てる
    • 実装に強く依存する(名前に、テスト対象のメソッド名を含むなど)ような厳格な命名規則は、テストコードの保守性低下に繋がり、よろしくない
    • 「確認(検証)したいこと」や「振る舞い」に焦点を当てた名前は、テストの意図を把握しやすい(つまり、読みやすい)
  • テストメソッドの名前に「should」を用いるのはアンチパターン
    • テストメソッド名に希望や要望(つまりshould)を含めるべきではない
    • 希望や要望ではなく、事実(~である、つまり「is」の方が適切
テスト

2023年03月12日(日)

2.0時間