web-dev-qa-db-ja.com

大規模なアプリケーションでのRSpecテストの高速化Rails=

RSpecテストには2,000以上の例があるRailsアプリケーションがあります。言うまでもなく、それは大規模なアプリケーションであり、多くのテストを行う必要があります。時間がかかるので、新しいビルドをプッシュする前にそれらを作成することをお勧めしません。私は--profileをspec.optsに追加して、最も実行時間の長いサンプルを見つけました。 RSpecの専門家の間でそれは普通ですか?1つの例では10秒が長すぎますか?2,000の例では、すべてを徹底的にテストするのに重要な時間を要することがわかります。この時点で4時間は少し滑dicです。

最も長く実行されている例については、どのような時期を見ていますか?ボトルネックを見つけて速度を上げるために、既存の仕様のトラブルシューティングを行うにはどうすればよいですか。この時点では毎分が本当に役立ちます。

90
randombits

1つのテストを実行するのに10秒は非常に長い時間です。私の直感では、あなたのスペックターゲットはユニットテストと統合テストの両方を同時に実行しているということです。これはプロジェクトが陥る典型的なことであり、ある段階で、あなたはこの技術的負債を克服する必要がありますより多く、より速く生産したい場合。これを行うのに役立ついくつかの戦略があります...そして、私が過去に使用したいくつかをお勧めします。

1。統合テストからユニットを分離する

最初に行うことは、ユニットを統合テストから分離することです。これは次のいずれかの方法で実行できます。

  1. それらを(specディレクトリーの下の個別のフォルダーに)移動し、rakeターゲットを変更します
  2. タグ付け(rspecを使用すると、テストにタグ付けできます)

哲学は、定期的なビルドを迅速にしたいということです-そうしないと、人々はそれらを頻繁に実行するのはあまり幸せではありません。だからその領土に戻ってください。定期的なテストを迅速に実行し、継続的な統合サーバーを使用してより完全なビルドを実行します。

統合テストは、外部の依存関係(たとえば、データベース、WebService、キュー、および一部のユーザーがFileSystemを主張する)を含むテストです。単体テストは、チェックするコードの特定の項目をテストするだけです。高速で実行する必要があります(45秒で9000が可能です)。つまり、ほとんどがメモリ内で実行されます。

2。統合テストを単体テストに変換する

単体テストの大部分が統合テストスイートより小さい場合、問題があります。これが意味することは、矛盾がより簡単に現れ始めるということです。そのため、ここから、統合テストに代わる単体テストの作成を開始します。このプロセスを支援するためにできることは次のとおりです。

  1. 実際のリソースの代わりにモックフレームワークを使用します。 Rspecには、組み込みのモックフレームワークがあります。
  2. 単体テストスイートでrcovを実行します。それを使用して、単体テストスイートがどれだけ徹底しているかを測定します。

統合テストを置き換える適切な単体テストができたら、統合テストを削除します。テストの重複は、メンテナンスを悪化させるだけです。

。フィクスチャを使用しない

フィクスチャは悪です。代わりに工場(machinistまたはfactory_girl)を使用してください。これらのシステムは、より適応性の高いデータグラフを構築できます。さらに重要なことは、外部データソースからデータを読み込むのではなく、使用できるメモリ内オブジェクトを構築できることです。

4。統合テストになる単体テストを停止するためのチェックを追加

より高速なテストが実施されたので、チェックを入れて、これが再び発生しないようにします。

データベース(UnitRecord)にアクセスしようとしたときにエラーをスローするようにアクティブレコードにモンキーパッチを適用するライブラリがあります。

また、ペアリングとTDDを試すこともできます。これにより、チームはより高速なテストを作成することができます。

  1. 誰かのチェック-だから誰も怠け者にならない
  2. 適切なTDDには高速フィードバックが必要です。テストが遅いと、全体が苦痛になります。

5。他のライブラリを使用して問題を克服する

誰かがspork(Rails3でのテストスイートのロード時間を高速化する)、hydra/parallel_tests-ユニットテストを(複数のコアで)並行して実行することについて言及しました。

これはおそらく最後に使用する必要があります。あなたの本当の問題は、ステップ1、2、3のすべてです。それを解決すれば、追加のインフラストラクチャをロールアウトするためのより良い立場になります。

119
BlueFish

テストスイートのパフォーマンスの向上に関する優れたクックブックについては、 Grease Your Suite プレゼンテーションをご覧ください。

彼は、次のような技術を利用することで、テストスイートの実行時間を45倍高速化したことを文書化しています。

16
marshally

Sporkを使用できます。 2.3.xをサポートしています。

https://github.com/sporkrb/spork

または2.xで動作する可能性のある./script/spec_server

また、データベース構成を編集して(基本的にデータベースクエリなどを高速化できます)、テストのパフォーマンスも向上します。

5
Rishav Rastogi

例ごとに10秒は非常に長い時間のようです。私は1秒以上かかったスペックを見たことがなく、ほとんどがはるかに少ないものを取りました。ネットワーク接続をテストしていますか?データベースの書き込み?ファイルシステムの書き込み?

モックとスタブをできるだけ使用してください-データベースにヒットするコードを書くよりもmuch速いです。残念ながら、モックとスタブの作成にも時間がかかります(正しく行うのが難しくなります)。テストの作成にかかる時間とテストの実行にかかる時間のバランスを取る必要があります。

2番目の Andrew Grimm は、テストスイートの並列化を可能にするCIシステムの調査に関するコメントです。そのサイズの何かについては、それが唯一の実行可能なソリューションかもしれません。

3
zetetic

ActiveRecordモデルを使用している場合、BCrypt暗号化のコストも考慮する必要があります。

詳細については、このブログ投稿をご覧ください: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html

2
Erdem Gezer

数人が上記のHydraに言及しています。過去に大成功を収めて使用しました。私は最近、ヒドラを起動して実行するプロセスを文書化しました: http://logicalfriday.com/2011/05/18/faster-Rails-tests-with-hydra/

この種の手法は、適切に構造化され、デフォルトで高速なテストを記述する代わりに使用すべきではないという意見に同意します。

2
Rodreegez

このプレゼンテーションをご覧ください: http://grease-your-suite.heroku.com/#1

1
user456733

テスト速度の改善に関する 非常に一般的なビデオ があります。役立つかもしれません。

0
Neil

いくつかの簡単なヒントに従って、まだ試していない場合、ほとんどの時間が費やされている場所を最初に調査できます。以下の記事をご覧ください。

https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581

これらのほとんどは一般的な手順であり、テストに使用されるツールに関係なく適用されると思います。

0
jake

試すことができます http://github.com/ngauthier/hydra

0
Reactormonk

faster_require gemが役に立つかもしれません。それに加えて、あなたの唯一の方法は、(あなたがしたように)プロファイリングと最適化を行うか、仕様を並行して実行するsporkまたは何かを使用することです。 http://Ruby-toolbox.com/categories/distributed_testing.html

0
rogerdpack