私の会社では、中規模の RAILS アプリ にCucumber BDD テスト フレームワークを使用しています。
遅いです。犬遅い。私が取り組んでいる 1 つのキュウリだけでも、実行に 30 秒から 40 秒かかり、何十もの異なるテスト ファイルがあります。すべてを実行するには、1時間以上かかります。
少し調べてみると、膨大な量の反復的なデータベース作業がありますが、合計データ サイズはかなり小さいです。たとえば、次のような遅いステートメントが表示されます。
Given I have all the discussion threads for "fake user 47"
それには1000ミリ秒以上かかります。これが行う唯一のことは、ディスク上のファイルから数十行のストック フィクスチャ データを取得し、一度に 1 行ずつデータベースにロードすることです。大量のデータではなく、せいぜい数 KiB です。しかし、ActiveRecord 処理のすべてのオーバーヘッドを合計して、それを数十の SQL ステートメントに変換し、クロスプロセス IPC を mysql に対して同期的に実行して、これらのステートメントを実行すると、合計されるようです。
Mysql 自体はここでは問題ではなく、メモリ内テーブルなどに切り替えても、テストの実行時間にはほとんど影響しません。cucumber プロセスは、約 70% の CPU 使用率で実行されます。
ただし、データベースへのアクセスは、要求ごとに 2 つ以上のコンテキスト スイッチは言うまでもなく、アダプター、データ ドライバー、マーシャリングなどの複数のレイヤーを通過する必要があるプロセスにまたがる要求であるため、依然としてかなりコストのかかる操作です。
したがって、私の理論では、単純なハッシュ テーブルなどにデータを格納するだけであれば、テストははるかに高速に実行されるということです。(Rubyでプロファイリングを行う方法を調べて、この理論を証明できるようにします)。
シムアウトされたインプロセスの「シミュレートされた」データベース レイヤーを使用してテスト スイートを実行することは可能ですか? 理想的には、理想的には SQL を処理する必要さえない超軽量の何かで、ActiveRecord が期待するコントラクトを実装するだけです。
また、同じセットアップを複数回行っているようです。あるテストでは、「データ X がある場合」と言って、データ X をロードしていくつかのチェックを行うのに何年も費やします。次に、別のテストで「データ Y がある場合」と言って、データベースをクリアし、データ Y の読み込みに何年も費やし、いくつかのチェックを行います。次に、3番目のテストで「データXがある場合」と表示され、データベースがクリアされ、Xの再ロードに時間がかかります。もちろん、4番目のテストでは、おそらくデータYが再び使用されます....
シナリオ全体でテスト初期化コードを再利用するための明確なパターンはありますか? または、特定の初期化状態をキャッシュするには?