2015年8月9日日曜日

テストデータを管理する方針

『継続的デリバリー』の、テストデータの管理についての記述を整理してみた。該当する章節は、
  • 12.5 テストデータを管理する
  • 12.6 データの管理とデプロイメントパイプライン
それから12.5から参照されている、
  • 8.5.1 受入れテストにおける状態
の3箇所。特に断りの無い限り、『継続的デリバリー』のいう受入れテストのデータ管理を念頭に置いている。

テストデータの管理で問題となるのは、1) パフォーマンス、2) テストの分離の2つ。xUTPだとそれぞれSlow TestsSeparation of Concernsに対応しているように思う。

どちらの問題でも、真っ先に原因として挙がるのがデータベース。ユニットテストならデータベースアクセス移譲先 (デザインパターンDAO相当) をテストダブルで置き換えられる。これはパフォーマンスにも分離にも効く。DBの状態も含めてテストしたい場合、インメモリDB (H2, SQLite, JavaDBなど) を使うこともできる。

データベースに限らず、テストとデータのつながりを管理するアプローチには、次の3つがある。
  1. テストの分離: 各テスト用のデータは、そのテストからしか見えないようにする。
  2. 順応型テスト: テストがデータ環境を調べ、実際のデータに合わせて振る舞うようにする。
  3. テストの順序づけ: テストの実行順序を予め決めておいて、一つ前のテストの出力を次のテストの入力とする。
スケールするのは1だけだと言っている。3は分かりやすい無理ゲー。こんな強く依存していたらスケールさせられない。2は一見良さげに見えるけれど、分離しきれていないと、別のテストで実際のデータが思いもよらない状態になっていることがある。xUTPでもTest SmellsとしてConditional Test Logicが挙がっている。

「テストの分離」のためには、まずテスト終了時にテスト前の状態に戻すとある。そうしないと、次のテストに今のテストのデータが見えてしまう。ただこれにはオプションもある。『システムテスト自動化標準ガイド』や『実践テスト駆動開発』では、テスト対象が登録したデータはテスト終了時に消さずに、テスト開始時に消すことを勧めている。もう一つの方法は、データを機能分割すること。これができるかどうかは、テスト対象の特性に強く依存する。

データを分割し、巨大で複雑なデータ構造への依存を減らすには、まずデータを整理しないといけない。著者はこんな風に言っている。
何よりもまず、プロダクションデータのダンプを取得して受入れテスト用にテストデータベースに投入したいという誘惑に負けないこと。
統制のとれた最小限のデータセットを保守しよう。
整理の取っかかりとなるのが、次の3種類のデータの区別。
  1. テスト固有のデータ: 一意でなければならない。テストの分離の手段になる。
  2. テストが参照するデータ: テストには関係するがふるまいには影響しないデータ。そこら中で使われるマスタデータ類を指していると思う。
  3. アプリケーションが参照するデータ: アプリケーションを立ち上げるのに必要なデータ。

一言で言うと、正しく動くと分かっている(契約による設計の言葉を使うと、事前条件を満たしている)開始位置を特定し、テスト開始時にその状態を復元する。言ってしまえばこれだけなんだけれど、そのためにはテスト対象とテストデータをよく理解する必要がある。それも一部のテストだけじゃない。うまくテストを分離するには、全体を俯瞰する必要がある。

なお、その開始位置を復元するのには、アプリケーションのAPIを利用するよう勧めている。理由は3つ。
  • システムを矛盾した状態に持ち込ませない。
  • データベースやAPIのリファクタリングの影響を避けられる。
  • APIのテストにもなる。
できないときは、事前条件をアサートする防御的なテストコードにしたり、アサートを相対的(例えば、レコードが3件あることではなくて、3件増えたことにする)にしたりする。

References


0 件のコメント:

コメントを投稿