データベース統合テスト
-
09-06-2019 - |
質問
データ アクセス レイヤーのみ、またはアプリケーション スタックの大部分に対して統合テストを実行する場合。複数のテストを同じデータベース上で実行する場合に、それらのテストが互いに衝突しないようにする最善の方法は何ですか?
解決
取引。
Ruby on Rails 単体テスト フレームワークが行うことは次のとおりです。
Load all fixture data.
For each test:
BEGIN TRANSACTION
# Yield control to user code
ROLLBACK TRANSACTION
End for each
この意味は
- テストがデータベースに加えた変更は、テストの進行中に他のスレッドに影響を与えません。
- 次のテストのデータは前のテストによって汚染されません
- これは、テストごとにデータを手動でリロードするよりも約 1000 倍高速です。
私はこれはかなりクールだと思う
他のヒント
単純なデータベース アプリケーションの場合は、 SQLite 貴重な。これにより、テストごとに一意のスタンドアロン データベースを作成できます。
ただし、これが機能するのは、単純な汎用 SQL 機能を使用している場合、または SQLite と運用データベース システム間のわずかな違いをクラスの背後に簡単に隠すことができる場合に限られます。しかし、私がこれまでに開発した SQL アプリケーションでは、それがかなり簡単であることが常にわかりました。発展した。
Free Wildebeestの回答に追加するために、私も使用しました HSQLDB 各テストで DB のクリーンなインスタンスを取得する同様のタイプのテストを実行します。
私は Free Wildebeest と Orion Edwards の両方の答えを受け入れたかったのですが、許可されませんでした。私がこれを実行したいと思った理由は、主に次の 2 つの方法があるという結論に達したためですが、どちらを選択するかは個々のケース (主にデータベースのサイズ) によって異なります。
また、互いのパフォーマンスや有効性に影響を与えないように、テストを異なる時間に実行します。
ここでの他の回答の 1 つである Rails 単体テスト フレームワークほど賢明ではありませんが、テストまたはテストのグループごとに個別のデータを作成することも別の方法です。このソリューションの面倒さのレベルは、テスト ケースの数と、それらが相互にどの程度依存しているかによって決まります。テストごと、または依存するテストのグループごとに 1 つのデータベースがある場合、この面倒さは当てはまります。
テスト スイートを実行するときは、最初にデータをロードし、テスト スイートを実行し、結果をアンロード/比較して、実際の結果が期待される結果を満たしていることを確認します。そうでない場合は、サイクルを再度実行します。ロード、スイートの実行、アンロード/比較。