1. ホーム
  2. database

[解決済み] データベース駆動型アプリケーションのユニットテストに最適な戦略とは?

2022-03-14 08:13:01

質問

私は、バックエンドに様々な複雑さを持つデータベースによって駆動される多くのウェブアプリケーションを扱っています。一般的には オーエム ビジネスロジックやプレゼンテーションロジックとは別のレイヤーです。このため、ビジネスロジックのユニットテストは非常に簡単です。物事を個別のモジュールで実装し、テストに必要なデータはオブジェクトモッキングでフェイクすることが可能です。

しかし、ORMやデータベース自体のテストは、常に問題や妥協がつきまとうものでした。

長年にわたり、私はいくつかの戦略を試してきましたが、どれも完全に満足できるものではありませんでした。

  • 既知のデータでテスト用データベースをロードする。ORMに対してテストを実行し、正しいデータが戻ってくることを確認します。この場合の欠点は、テスト DB はアプリケーションデータベースのスキーマ変更に追従しなければならず、同期がとれなくなる可能性があることです。また、人工的なデータに依存するため、ユーザーの愚かな入力によって発生するバグを明らかにできない可能性があります。最後に、テストデータベースが小さいと、インデックスの欠落のような非効率的な部分を明らかにすることができません。(OK、最後のものはユニットテストが本当に使われるべきものではありませんが、それは問題ではありません)。

  • 本番用データベースのコピーをロードし、それに対してテストする。ここで問題なのは、本番用 DB に何が入っているのか、その時点では全くわからないということです。

これらの戦略はどちらも特定のデータに依存しており、ユニットテストは機能のみをテストするものであるべきだと指摘する人もいます。そのために、提案されているのを見たことがあります。

  • モックデータベースサーバーを使用し、ORMが与えられたメソッド呼び出しに応答して正しいクエリを送信しているかどうかだけをチェックします。

データベース駆動型アプリケーションのテストに使用したことのある戦略があれば、教えてください。最も効果的だったのは何ですか?

解決方法は?

私は、この最初の方法を使い、かなりの成功を収めましたが、少し違った方法で、あなたの問題のいくつかを解決できると思います。

  1. スキーマ全体とそれを作成するためのスクリプトをソース管理下に置き、チェックアウト後に誰でも現在のデータベース・スキーマを作成できるようにする。さらに、ビルドプロセスの一部で読み込まれるデータファイルに、サンプルデータを入れておきます。 エラーの原因となるデータを発見したら、それをサンプルデータに追加して、エラーが再発しないことをチェックします。

  2. 継続的インテグレーション・サーバーを使用して、データベース・スキーマを構築し、サンプル・データをロードし、テストを実行します。 このようにして、テスト用データベースの同期を保ちます(テスト実行のたびにデータベースを再構築します)。 CIサーバーが専用のデータベースインスタンスにアクセスし、所有する必要がありますが、1日に3回データベーススキーマを構築することで、おそらく納品直前まで見つからなかったであろうエラーを劇的に発見することができるようになりました。 毎回コミットする前にスキーマを再構築しているとは言えません。 誰かやってますか? このアプローチでは、その必要はありません(そうすべきかもしれませんが、誰かが忘れたとしても大したことではありません)。

  3. 私のグループでは、ユーザー入力はアプリケーションレベル(データベースではない)で行われるので、これは標準的なユニットテストによってテストされます。

本番用データベースコピーの読み込み。

これは、私が前職で使っていた方法です。 いくつかの問題があり、非常に苦労しました。

  1. コピーが製品版から古くなってしまう。
  2. コピーのスキーマに変更が加えられ、本番システムには伝搬されない。 この時点でスキーマがバラバラになってしまう。 面白くないですね。

データベースサーバをモック化する。

今の仕事でもやっています。 すべてのコミット後に、モックデータベースアクセサが注入されたアプリケーションコードに対してユニットテストを実行します。 そして、1日に3回、上記のような完全なDBビルドを実行します。 私は間違いなく両方のアプローチをお勧めします。