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