はじめに
テスト自動化を始めたら、色々躓きがあるかと思いますが、それをまとめてみました。
今後も躓いたら定期的にアップデートしていこうと思います。
今の所、単体テスト、結合テスト、機能テスト等の区別は特にしていません。
コピペの氾濫
コピペの原因による。もちろん、本当にコピペしただけのテストコードは
問題ありすぎですが、何らかの意図があってのものなら仕方がないかなと。
例えばテストケースはシンプルに保ちたい(i.e. if文を入れたくない)、
よってデータ駆動テストは使いたくない、なら納得しますね。
ただし、テストケースが網羅されているかどうかは気にしたほうがいいですね。
Statist or Behaviourist
ここの方が丁寧に書いてくださってますが、ようはMock/Stubを使って、
テスト対象の依存オブジェクトをどう検証するかということです。
Mock/Stubを使うと、依存オブジェクトから独立したテストを作れて、実行速度も早くできますが、
依存オブジェクトとの結合時や依存オブジェクトの変更に脆くなりやすいと言われています。
そのため、特別な理由がない限りは使わないほうが良いと思います。
何%のカバレッジを目標とするべきか
カバレッジはテストによってプロダクションコードがどの程度実行されたかを表す指標です。
よって、ある特定の機能が丸々ごっそり抜けていることを指し示す指標ではないですし、
意味あるテストが為されていることを指し示す指標でもありません(意図的にあげることは簡単なので)。
この前提を踏まえた上で、記述すると80%から90%程度に設定するプロジェクトが多いようです。
あとはプロジェクトのQCDSやプロダクトの性質(ユニットテストしやすいかどうか)に
よって調整する感じでしょうか。
スローテスト問題
開発を進めていくとユニットテストの数も比例して増えていきますが、
だんだん無視できなくなるのがその実行時間です。
比較的先進的な現場では、プルリクをwebhookして
ユニットテストを自動実行させてると思いますが、
その実行時間が30分とかになったらおそらく待てないですね。
そんな時にどうするかですけど、対策として以下の4つがあります。
##1. テスト実行環境を強化する
札束でしばくとよいということですね。プロジェクトの予算との相談でしょうか。
「人件費より高いコストはない」という意見もありますが、ポンッと出してくれる現場でなければ、
スペックの良いマシンをレンタルしてきて比較実験をする必要がありそうですね。
##2. テストを並列で実行する
こちらは複数のマシンを使ってテストを実行するということですね。
この時気にするべきは以下の2点です。
a. テストケースは任意の順番で実行できること。
b. テストケース間でリソース(e.g. 何かしかのグローバル変数やDBのデータ)を共有していないこと。
テストを分割して実行するには、何らかのツールを導入したり、作成・設定が必要になるかもしれません。
なるべく管理上煩雑にならないものが好ましいかと思います。
##3. テストの実行時間を短くする
この方法では遅いテストケースを丹念に調べ上げて、1つずつ実行時間を短くします。
具体的には以下のような作業でしょうか。
a. テストデータの共有(共有フィクスチャ)
b. リアルオブジェクトをモックオブジェクトに変換
c. パフォーマンスを考慮したテストコードを書く
ただし、それぞれテストケースの独立性の低下、テストの安定性及び
テストコードの可読性とのトレードオフになってきますし、
そもそも作業自体にリスクが伴うので、基本的には最終手段と考えたほうがよいです。
##4. 実行するテストを絞り込む
作ったテストを潔く廃棄するか、実行頻度を下げるという方法です。
対象になるのはさほど重要でなかったり、重複していたり、
特に実行時間のかかるテストケースです。
個人的にはこれが一番適用しやすいと思いますが、
どのテストケースを廃棄して、どのテストケースの実行頻度を下げるか等、
チーム内で何らかの基準を作って、管理しやすい形にまとめておく必要がありそうです。
参考
http://endok.hatenablog.com/entry/2014/06/08/215043
JUnit実践入門