SE情報技術研究会’s blog

http://se-info-tech.connpass.com

2016-01-24 『JUnit実践入門』読書会(第7章)の振り返り

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

第7章 テストフィクスチャ

テストフィクスチャとは?

  • テストフィクスチャとはテストで扱うデータや実行環境やオブジェクトの状態などのこと
  • テストフィクスチャの設定は工夫をしないとコードが長く複雑になる

ユニットテストのフィクスチャ

  • テスト対象オブジェクト
  • 入力値
  • 期待値
  • テスト実行前までに必要なテストオブジェクトの操作
  • 外部リソース
  • DBなどの外部システム
  • 依存クラスや依存外部システムのモックオブジェクト

フレッシュフィクスチャ

フレッシュフィクスチャとは下記のことを行う戦略

  1. フィクスチャはテストケースごとに取得する
  2. フィクスチャはテストケースの実行ごとに初期化する
  3. フィクスチャはテストケースの終了時に開放する

フィクスチャがいくつかのテストケースで共有されていると、実行順序や並列にテストを行うと結果が変わる可能性が高い

JUnitではテストの実行時にテストケースごとにテストクラスのインスタンスを生成している
→ テストクラスのインスタンス変数やローカル変数は各テストケースで共有されることがない

フィクスチャとスローテスト問題

  • フレッシュフィクスチャだとDBを扱う場合などに長時間になってしまう(スローテスト問題)
  • 解決策としてテストケースの並列実行、共有フィクスチャ、カテゴリ化テスト(第10章で説明)が有効
  • スローテスト問題はユニットテストの実行時間が何十分もかかるようになってから対応すべき

共有フィクスチャ

  • 共有フィクスチャとは各テストで使用するフィクスチャを共有し、再利用すること
  • セットアップコストが抑えられる

共有フィクスチャの問題

  • テストケースごとの独立性が弱くなる
  • グローバル変数の場合と同じ理由で、テストコードのメンテナンス性が下がる
  • 適切に後処理を行う必要がある

共有フィクスチャを使う場合

  • 不変オブジェクトにする

フィクスチャのセットアップパターン

インラインセットアップ

  • インラインセットアップとはテストケースごとにフィクスチャのセットアップを行うこと
  • セットアップがテストケースで完結できる
  • セットアップが複雑な場合、可読性が悪くなる

暗黙的セットアップ

  • 暗黙的セットアップとは@Beforeがついたセットアップメソッドにフィクスチャのセットアップを行い、各テストメソッドの実行前に暗黙的にセットアップを実行すること
  • テストケースはテスト実行と検証のコードがメインになり、可読性が高くなる
  • Enclosedランナーを使った場合に高い効果を期待できる

生成メソッドでのセットアップ

  • 独立したクラスにフィクスチャの生成メソッドを抽出し利用させるセットアップ方法
  • 複数のテストクラスでの共通のフィクスチャの生成が行えるようになる
  • staticメソッドで定義することでstaticインポートが使用でき、可読性が高くなる
  • 生成メソッド名を日本語で定義するとわかりやすくなる

外部リソースからのセットアップ

  • 外部に定義ファイルにテストデータを記述し、生成メソッドで読み込む手法
  • XMLは複雑なデータを記述できるが、メンテナンスが大変なため推奨しない
  • JSON複数行テキストの扱いが難しい
  • フィクスチャがリスト構造で大量の場合はCSVExcelが便利
  • 著者のおすすめはYAML
  • YAMLなどの外部リソースはテストケースとテストデータがそれぞれ独立したファイルになるため相互参照がしにくい

Java宣言的記法

  • Javaで宣言的な記述を行うには、匿名クラスを使って行うことができる
  • ただして匿名クラスの場合、final宣言されていると継承できないので使えない
  • Groovyを導入するでJavaの宣言的なコードをわかりやすく記述することが可能
    → 最近だとScalaでも可能かも?
    Scalaだとコンパイル遅い問題が出てきそう
  • テスト用のライブラリにGroovyを追加するのでプロダクトには影響しない
  • Groovyは学習コストも低く可読性も高い