データベースのテストの話
最近のお仕事の話とかデータベースのテストってみんなどうやってるんだろ?の続きみたいな話。
マーチン・ファウラーが Thought Works における、Ruby での開発について色々書いてます。(記事が書かれてすぐ邦訳されてた。ありがたやありがたや。)
で、全編通して面白い記事なのですが、特に興味深かったのが下記のくだり。ちょっと長いけど引用します。
Martin Fowler's Bliki in Japanese - ThoughtWorksでのRuby - Active Recordのテスティング
Active Recordの問題は、データベースアクセスコードをビジネスロジックと一緒にしてしまっていることだ。これでは、データベースダブルを作ることが難しい。 Mingleチームでは、Railsがデータベースと密接に結びついていることを受け入れ、本物のデータベースに対してすべてのコミットテストを実行している。
まったく逆の視点が、AtlantaチームとJerseyチームから提唱された。 Rubyにはメソッドを実行時に再定義できる強力な機能がある。これを使って、Active Recordのクラスにあるデータベースアクセスメソッドを再定義して、Active Recordクラスをスタブ化するのである。チームはこのために gem の unitrecord を使い始めていた。
3年経つが、我々はまだこの議論に決着がついていない。 Mingleチームは、本物のpostgresデータベースに接続して、8分以内に数千ものテストを実行している(マルチコアを活用してテストを並列処理している)。 AtlantaチームとJerseyチームは、コミットテストがスタブなしで8分以内に終わるよりも、スタブありで2分以内に終わることのほうが大切だと考えている。このトレードオフは、データベースを直接テストするシンプルさと、スタブテストの素早いコミットビルドとの対決だと言える。
まあウチの場合は、Rails ではないので、Active Record の問題とまったく同じというわけではありませんが、ビジネスロジックがストアドプロシージャに内包されているので、テストコードから見たら似ていると思います。
で、「マーチン・ファウラーをはじめとする、Thought Works の凄腕たちでも結論が出てないんだ」、ということにちょっと安心したような、やっぱ解答ほしいなぁ、という思いやら、複雑な気持ちです。
ちなみに、ウチは DB にテストデータを流し込んで、実際のデータでテストしてます。(Mingleチーム式)。テスト数は 2万5千くらいだっけ? 8分はかからないけど、多分 3, 4分はかかってますね。(ちゃんと測ってない...)
別件。以前、
データベースのテストってみんなどうやってるんだろ?
Apache のプロセスは Apache::Test を使えばユーザ毎とかに分けるとかできそうだけど、DB はそういうモジュールないし。
と書きましたが、MySQL::Sandbox使えば出来そうな感じです。
MySQL::Sandbox はあくまでもサンドボックスを作るだけっぽい感じなので、マスタデータに関しては何かしら考えないとダメそうですけどね。いずれにせよ、「DB のマスタが正」っていう状態はあんまり健全じゃないから、その辺も踏まえてちゃんと考えればいいのかなぁ。
もうちょっと頑張れば自分なりの答えは出そうな感じですね。
see also: