Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing APIs

Testing APIs

Rodrigo Flores

May 27, 2013
Tweet

More Decks by Rodrigo Flores

Other Decks in Programming

Transcript

  1. O que preciso da API ? Preciso autenticar ? Preciso

    pegar uma lista com as informações de algum lugar ? Monday, May 27, 13
  2. Multi-ambiente Em desenvolvimento a API deve funcionar mas não ter

    efeitos Em teste, a API não deve funcionar (nem fazer as requests) Em produção, deve funcionar Monday, May 27, 13
  3. require 'net/http' require 'json' uri = URI.parse('https://api.github.com/users/ rodrigoflores/repos') http =

    Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri.request_uri) response = http.request(request) repos = JSON.parse(response.body) repos.each do |repo| puts repo['name'] end Monday, May 27, 13
  4. # encoding: utf-8 require 'net/http' require 'json' require 'webmock' include

    WebMock::API stub_request(:get, "https://api.github.com/users/rodrigoflores/ repos").to_return(body: File.read('response.json')) uri = URI.parse('https://api.github.com/users/rodrigoflores/repos') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri.request_uri) response = http.request(request) repos = JSON.parse(response.body) repos.each do |repo| puts repo['name'] end Monday, May 27, 13
  5. Real HTTP connections are disabled. Unregistered request: GET https:// api.github.com/users/rodrigoflores/repos

    with headers {'Accept'=>'*/*', 'User-Agent'=>'Ruby'} (WebMock::NetConnectNotAllowedError) You can stub this request with the following snippet: stub_request(:get, "https://api.github.com/users/rodrigoflores/repos"). with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}). to_return(:status => 200, :body => "", :headers => {}) registered request stubs: stub_request(:get, "https://api.github.com/users/josevalim/repos") Não “stuba” o Net::HTTP Monday, May 27, 13
  6. 1a Vez: Faz o Request e serializa o request/response 2..n

    vez: Reproduz o que foi serializado Monday, May 27, 13
  7. uri = URI.parse('https://api.github.com/users/ rodrigoflores/repos') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl =

    true request = Net::HTTP::Get.new(uri.request_uri) VCR.use_cassette('repos') do response = http.request(request) repos = JSON.parse(response.body) repos.each do |repo| puts repo['name'] end end Monday, May 27, 13
  8. --- http_interactions: - request: method: get uri: https://api.github.com/users/rodrigoflores/repos body: encoding:

    US-ASCII string: "" headers: Accept: - "*/*" User-Agent: - Ruby response: # (...) recorded_at: Sat, 25 May 2013 13:59:28 GMT recorded_with: VCR 2.5.0 Monday, May 27, 13
  9. response: status: code: 200 message: OK headers: #(...) body: encoding:

    ASCII-8BIT string: "[{\"id\":1254869,\"name\":\"1001\",\"full_name\": \"rodrigoflores" # (...) Monday, May 27, 13
  10. require 'net/http' require 'json' require 'faraday' require 'faraday_middleware' conn =

    Faraday.new(:url => 'https://api.github.com') do |faraday| faraday.adapter Faraday.default_adapter faraday.response :json, :content_type => /\bjson$/ end repos = conn.get('/users/rodrigoflores/repos').body repos.each do |repo| puts repo['name'] end Monday, May 27, 13
  11. require 'net/http' require 'json' require 'faraday' require 'faraday_middleware' conn =

    Faraday.new(:url => 'https://api.github.com') do |faraday| faraday.adapter :test do |stub| stub.get('/users/rodrigoflores/repos') {[ 200, { 'Content-Type' => 'application/json; charset=utf-8' }, File.read('response.json') ]} end faraday.response :json, :content_type => /\bjson$/ end repos = conn.get('/users/rodrigoflores/repos').body repos.each do |repo| puts repo['name'] end Monday, May 27, 13
  12. Decidir qual o melhor jeito de testar Testar o cliente

    como uma aplicação Ruby Tomar cuidado para não fazer requests em teste (pelo menos não o tempo todo) Testes de contrato podem valer a pena ou não Monday, May 27, 13
  13. class ExampleController < ApplicationController def index expires_in 10.minutes, public: true

    render json: { version: '3.2.19' } end end Monday, May 27, 13
  14. describe ExampleController do describe "GET #index" do it "shows the

    version info" do get :index parsed_response = JSON.parse(response.body) parsed_response['version'].should == '3.2.19' end it "has a max-age of 10 minutes" do get :index response.headers['Cache-Control'].should == "max-age=600, public" end it 'has a 200 status' do get :index response.status.should == 200 end end end Monday, May 27, 13
  15. Testar com testes de controller Testar headers e status code

    (quando forem relevantes) Manter documentação (com testes parece ser mais simples) Monday, May 27, 13