VCRを使用したRailsアプリケーションのテスト中に外部リクエストを強制終了します





ごく最近、アプリケーションのテストがかなり長い間実行されているという事実に問題がありました。 これは、コードの一部がiTunesやFacebookなどのサードパーティサービスにアクセスすることを好むためです。



テスト中にサードパーティのサービスにアクセスするのは、次の理由により悪です。



  1. テストの実行中に通信の問題が始まると、それらはゆっくりとパスするか、完全に落ちます。
  2. すでに述べたように、テストに合格する速度は非常に遅くなります。
  3. サービス自体によるリクエストの数の制限に問題がある可能性があります。




この記事は、外部サービスへのリクエストを削除してローカルコールに置き換えるためのいくつかの手法を説明する投稿「テスト外部サービスをスタブする方法」で書いたものです。 この記事では、次の方法を紹介しています。



  1. シナトラ上にスタブを作成します。これは、テストの進行中に上昇します。
  2. VCRライブラリを使用します。これにより、すべての外部リクエストを応答でインターセプトし、それらをファイルに書き込むことができます。


私自身の経験から-両方のアプローチは、わずかに異なる状況に適しています。 Sinatraは、小さなリクエストが1つあり、応答JSONがわかっている場合に適しています。 VCRは、誰かのSDK(私の場合はFacebookと通信するためのコアラ)が既に使用されている場合に便利です。これにより、ライブラリの内部ロジックを使用して誰かに一連の要求が行われます。



この記事では、VCRの使用に焦点を当てます。 テストには、rspecが使用されました。



明確にするために、クエリチェーン(およびその内容)を持つファイルは、VCRイデオロギーではカセットと呼ばれることに注意してください。 これは、メソッドの名前と、ドキュメントを見ると確認できます。 VCR自体は、文字通り「vidic」として翻訳できます。



まず、 VCR自体とwebmockをインストールして、外部からの要求をエミュレートします。 また、webmockはテスト中のすべての外部リクエストを禁止します。 Gemfile:



group :test do ... gem 'webmock' gem 'vcr' ... end
      
      







次に、spec_helper.rbに追加します。



 require 'webmock/rspec' require 'vcr' VCR.configure do |c| c.cassette_library_dir = 'fixtures/vcr_cassettes' #           c.ignore_hosts '127.0.0.1', 'localhost' c.hook_into :webmock end
      
      







例として、APIのテストを行い、その後、Facebookにいくつかのリクエストを行います。



このファイルには、新しいテストユーザーを登録し、フィードからの最後の投稿を提供するヘルパーが含まれています

スペック/サポート/ fb_helper.rb:



 module FbHelper def init_test_user VCR.use_cassette('fb_test_user') do result ={} test_users = Koala::Facebook::TestUsers.new(:app_id => Rails.application.config.fb_app_id, :secret => Rails.application.config.fb_app_secret) sandra = test_users.list.select! { |x| x["id"]=="1462678604000503" } @sandra_token = sandra.first['access_token'] @graph = Koala::Facebook::API.new(@sandra_token) @sender_id = @graph.get_object("me")["id"] posts = @graph.get_connections("me", "posts") @post_id = posts.select {|x| x['id']=="1462678604000503_1462707207330976"}.first["id"] result[:sandra_token] = @sandra_token result[:post_id]= @post_id result[:sender_id] = @sender_id return result end end end
      
      







テスト仕様ファイル自体/ spec / requests / facebook_register_post_request_spec.rb:



 require 'spec_helper' describe '    FB' do let(:device) { FactoryGirl.create(:device,:guid=>generate_guid) } it '      ' do result = init_test_user start_points = device.points VCR.use_cassette('fb_register_post') do #    /  get register_fb_post_api_path,{:id=>device.guid,:post=>result[:post_id],:sender=>result[:sender_id],:token=>result[:sandra_token]} end expect(response).to be_success end end
      
      







彼の小さなプロジェクトの経験によると、テストに合格する速度は25秒(不安定な接続中に1分で落ち着く可能性がありました)から8秒に低下しました。



ライブラリの完全なドキュメントはこちらにあります



All Articles