xUnit成熟度モデル 〜あなたの組織はどのレベル?
本エントリーは、Software Test & Quality Advent Calendar 2011の10日目です。
http://atnd.org/events/22833
前の9日目は @m_seko さんの
「負荷テスト対象のWebアプリがこういう非機能要件(+α)を備えていたらいいのにという願望」です。
http://d.hatena.ne.jp/sekom/20111209
普段、品質やテストなどには興味なさそう(?)にしている私ですが、
たまには、エンジニア視点から、テストについて語ってみましょう。
xUnit成熟度モデルって?
xUnit成熟度モデルとは、
組織がxUnitをより適切に利用できるようになることを目的として
遵守するべき指針を体系化したものである。
あわせて読みたい : 能力成熟度モデル統合 (CMMI) - Wikipedia
正味の話で言うと、僕がJUnitに初めて出会ってから今に至るまで、
どのようにJUnitを使い、失敗し、改善して行ったのかを、段階ごとに振り返った軌跡です。
レベル1 : 初期
xUnitを利用しているが、記述粒度、記述方針や、利用プロセスなどを決めておらず
それぞれのエンジニアが、自分の裁量でテストコードを書いている。
このレベルの典型的な問題
- assert文がなく、目視で結果を確認するテストコードが多い。
- テスト実施前に手動準備が必要である。しかし、その手順がどこにも記載されていない。
- なぜかxUnitを使っていないテストコードもある。
- テストコードがバージョン管理されていない。
- テストコードをバージョン管理しているが、ほぼエビエンス代わりであり、まず再テストは通らない。
次のレベルに向けた活動
- xUnitの利用方法について、組織内・プロジェクト内での勉強会を行ない、レベル感を合わせる。
- 組織、プロジェクトとして、どの工程でどのようにxUnitを利用するかを、事前に決める。
レベル2 : 過剰に書かれた
開発プロセスにてxUnitの利用方法を規定している。
ただし、過剰にテストしてしまったり、テストデータ量を爆発させたり、
xUnitが向いてないテストまで無理にxUnit化するなどするため、テスト工数がこれまでよりも掛かっている。
このレベルの典型的な問題
- 手動でテストしていた時に比べて、テスト工数が2倍以上に増えている。
- テストコードが、本体コードと同程度〜2倍程度の規模にまで膨らんでいる。
- Excel形式の投入データ、検証データが大量にあって、レビューも修正もできない。
- カバレッジ100%を達成するべく、特に最後の10%のためにテスト工数の半分を消費している。
- テストコードをバージョン管理しているが、膨大すぎてメンテナンスできず、再テストが通らない。
これらは、xUnitを始めた者が、一度は必ず陥る暗黒面だと言える。
次のレベルに向けた活動
- 小さな部分を、小さくテストする文化を浸透させる。
- 設計時や実装時に、テスト容易性を考慮した設計を行う。
- モックを利用したテストを取り入れる。
レベル3 : モック化された
過剰なテストへの対策として、「小さな範囲を小さくテストし、積み重ねる」ために、モックを利用している。
モックを実現する方法として、設計・実装を工夫する(protectedメソッドの活用など)か
モックライブラリ(djUnit、Mockitoなど)を利用するかは問わない。
いずれの方法を使っていても、モックを使う事でテストをスリム化することができ、
テスト工数や、メンテナンスコストを削減することができている。
このぐらいのレベルから、テストの事前準備自体をテストコード内で記述しているため、
リポジトリからソースを取得してビルドするだけで、すぐにテストを実行できるようになっている。
このレベルの典型的な問題
- モックライブラリの罠に陥っている
- 本体にバグがあっても、テスト自体がうっかり通ってしまっていて、問題に気付けない。
- 気がついたら、モック自体をテストしている。
次のレベルに向けた活動
- モックライブラリを使わずともモック化しやすいような設計・実装を浸透させる。
- 継承ではなく委譲
- メンバ変数よりも引数
- ステートレス化
- protectedメンバ、protectedメソッドの活用
レベル4:継続的に実施された
CIツールなどを導入して、ビルドとxUnitを定期的に実施している。
CIツールを導入することで、テストコードのメンテナンスを行う習慣が浸透するほか、
テスト環境に依存しない、テスト環境を壊さないようなテストコードを作成するようになっている。
このレベルの典型的な問題
CIツールに対して過剰な安心感を持ってしまい、これまで気付けた問題に気付けなくなる。
たとえば、テスト全体ではなく、一部のテストのみを定期的に実行している場合で
「CIしているから大丈夫」と考えて、動作確認を疎かにしてしまいバグを埋め込んでしまう。
CIツールは「安心」のための「シートベルト」に例えられることがあるが、
シートベルトをしていれば時速200kmで峠を攻めても良い、というわけではない。
レベル5 : 最適化している
テストコードを書くポイントや、分量などのバランスが分かり、
最適なテストコードを書くようになる。
もちろん、組織やプロジェクトの性質によって「最適」の定義、観点は異なっている。
参考までに、観点や選択肢を、いくつか列挙しておく。
- テスト工程の考え方 / CIの考え方
- 単体テスト対象の考え方
- あくまで単一メソッドのテストを行ない、外部メソッドは全てモック化している
- 原則としてpublicメソッドをテスト対象と考え、ある程度のまとまりごとに試験する
- 外部システムとの連携
- データベースへのデータ投入や外部システム操作を、テストコード内で実施する
- データベース部分や、外部システム連携箇所は、すべてモック化する
- モックの考え方
- モックライブラリを使いこなす
- モックライブラリは禁止して、ライブラリなくモック化できるよう設計する
まとめ
- レベル1:xUnitを使っているが、テスト自体が杜撰である
- レベル2:テストコードが過剰である
- レベル3:モックを使っている。
- レベル4:CIで定期実行している。
- レベル5:組織として、最適な解を選択している。
割と好き放題に書いてきましたが、いかがでしたか?
また、あなたの組織は、どのレベルでしたか?
もしこのエントリがあなたの組織のxUnitレベルが上がる一助になれば、幸いです!(><)