Убиваем внешние запросы во время тестирования rails приложений с помощью VCR

от автора

Совсем недавно, у меня возникла проблема заключающаяся в том, что тесты моего приложения довольно долго ходят. Это происходит в виду того, что некоторые части кода любят обращаться к сторонним сервисам вроде iTunes и Facebook.

Обращение к сторонним сервисам во время тестирования это зло по следующим причинам:

  1. Eсли во время исполнения тестов начинаются проблемы со связью, то они могут либо медленно проходить, либо вовсе падать.
  2. Как уже и писалось — довольно сильно замедляется скорость прохождения тестов.
  3. Возможны проблемы с ограничением числа запросов самими сервисами.


На написание данной статьи меня вдохновил пост How to Stub External Services in Tests, в котором описывается несколько методик избавление от запросов к внешним сервисам и подмена их локальными вызовами. В статье представлены следующие способы:

  1. Создать заглушку на синатре, которая поднимается на время хождения тестов.
  2. Использовать библиотеку VCR, которая позволяет перехватывать все внешние запросы с ответами и писать их в файл.

По собственному опыту — оба подхода хороши для несколько разных ситуаций. Синатра хороша когда есть один небольшой запрос и известен JSON ответа. VCR хороша когда уже используется чей-то SDK (в моем случае Koala для общения с Facebook) который делает цепочку запросов к чьему-то апи используя внутреннюю логику библиотеки.

В этой статье, мы остановимся на использовании VCR. Для тестирования использовался rspec.

Для ясности стоит отметить, что файлы с цепочкой запросов (и их содержимым) в идеологии VCR называются кассетами. Это можно заметить в названии методов и если посмотреть документацию. Ну а сам VCR можно дословно перевести как «видик».

Первым делом устанавливаем сам 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.

В этом файле лежит хелпер который регистрирует нового тестового пользователя и отдает его последний пост из ленты
spec/support/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 секунд.

Полную документацию на библиотеку можно посмотреть здесь.

ссылка на оригинал статьи http://habrahabr.ru/post/246409/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *