Palestra VCR
Upcoming SlideShare
Loading in...5
×
 

Palestra VCR

on

  • 4,508 views

Slides da

Slides da

Statistics

Views

Total Views
4,508
Views on SlideShare
1,152
Embed Views
3,356

Actions

Likes
0
Downloads
5
Comments
0

12 Embeds 3,356

http://cassiomarques.wordpress.com 3288
http://localhost:3000 23
http://gurusp.org 15
http://edit.optimizely.com 15
http://www.gurusp.org 4
http://translate.googleusercontent.com 3
url_unknown 2
http://cloud.feedly.com 2
http://www.swarmiq.com 1
http://www.goread.io 1
http://reader.aol.com.br 1
https://cassiomarques.wordpress.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Palestra VCR Palestra VCR Presentation Transcript

  • VCREscrevendo testes para clientes de APIs de forma inteligente Cássio Marques 16º encontro do GURU-SP 11/06/2011
  • http://cassiomarques.wordpress.com @cassiomarques cassiommc at gmail
  • Sistemas secomunicam entre si
  • Quer seja na web
  • Twitter AWSSua FacebookApp Seu serviço preferido
  • Ou dentro da suaprópria arquitetura
  • Autenticação Pedidos Geração de feedsSuaApp Middlewares para comunicação com HW Whatever
  • Mas somosresponsáveis
  • Queremos testar tudo isso
  • Certo?
  • Mas é difícil!
  • Dependemos de um recurso externo aocódigo sendo testado
  • Acesso à redeTestes lentos
  • Testes lentosNão rodo os testes com frequência
  • Algumas soluções
  • TOCAR O FODA-SE
  • Acessos reais à API
  • (lento)
  • Serviço indisponível Testes quebrados
  • Vantagem:
  • Se a API mudar, o teste quebra
  • stubbing
  • Mea culpa: a descrição da palestra está “imprecisa”
  • Testes rápidos
  • Não há dependência externa
  • Duas formas básicas...
  • class ApiClient def create(params) # ... endendclass SomeService def remote_create(params) client = ApiClient.new client.create params endend
  • describe SomeService do describe "#remote_create" do before do ApiClient.stub(:new).and_return(mock_client = mock(:api_client)) @expected = ... alguma forma complicada de preparar esse objeto ... mock_client.stub(:create).and_return(@expected) end it "returns the expected object" do service.remote_create(:foo => "bar").should == expected end endend
  • Estamos testandoSomeService de forma isolada
  • Isso é bom
  • Mas não temoscobertura alguma para ApiClient
  • Outra forma
  • Fakewebhttps://github.com/chrisk/fakeweb
  • page = `curl -is http://www.google.com/`FakeWeb.register_uri :get, "http://www.google.com/", :response => pageNet::HTTP.get(URI.parse("http://www.google.com/"))# => Full response, including headers
  • Webmockhttps://github.com/bblimke/webmock
  • stub_request(:post, "www.example.com").with( :body => "abc", :headers => { Content-Length => 3 })uri = URI.parse("http://www.example.com/")req = Net::HTTP::Post.new(uri.path)req[Content-Length] = 3res = Net::HTTP.start(uri.host, uri.port) {|http| http.request(req, "abc")} # ===> Success
  • stub_request(:any,"www.example.com").to_return( :body => "abc", :status => 200, :headers => { Content-Length => 3 })Net::HTTP.get("www.example.com", /)# ===> "abc"
  • Idéia geral:
  • Especifico uma resposta manualmente e forço que a mesma seja retornada
  • Já é um começo!
  • Automatizar!
  • VCRhttps://github.com/myronmarston/vcr
  • Grava as interaçõesreais entre nossa app e os serviços externos
  • Reproduz as interações nas chamadas posteriores
  • Rápido pra dedéu
  • Determinístico
  • VCR.config do |c| c.cassette_library_dir = fixtures/vcr_cassettes c.stub_with :webmock # or :fakewebend
  • describe ApiClient do describe "#create" do VCR.use_cassette("create") do client = ApiClient.new response = JSON.parse(client.create(:foo => "bar")) response["some_key"].should == "whatever" end endend
  • fixtures/vcr_cassettes/create.yml
  • •request mostra arquivo yml de exemplo acessando o Twitter. •method (colorscheme gobo) •uri •body •headers•response •status •code •message •headers •body •http version
  • Garantir que os testesnão realizam nenhum request real
  • VCR.config do |c| c.allow_http_connections_when_no_cassette = falseend
  • 1) PalestraVcr::Whatever should whatever Failure/Error: described_class.new.twitter WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: GET https://api.twitter.com/1/users/show.json?screen_name=foobar with headers {Accept=>application/json, Accept-Encoding=>gzip;q=1.0,deflate;q=0.6,identity;q=0.3, Authorization=>OAuthoauth_consumer_key="uxUyVGxMkKvBIX6UUjD0g", oauth_nonce="eccace43473c668ac18b5d73d058f987",oauth_signature="dIYPYQGLtxlbEJmDmQ5EHPz3rmw%3D", oauth_signature_method="HMAC-SHA1",oauth_timestamp="1307752227", oauth_token="63302783-bFB4P8fPv1HrPajZMePudJnjXMh3ywaMcRua1Dtjp", oauth_version="1.0", User-Agent=>TwitterRuby Gem 1.5.0}. You can use VCR to automatically record this request and replay it later.For more details, visit the VCR documentation at: http://relishapp.com/myronmarston/vcr/v/1-10-0
  • Mas e se eu quiser algo um pouco mais genérico?
  • ---- !ruby/struct:VCR::HTTPInteraction request: !ruby/struct:VCR::Request method: :get uri: !ruby/regexp /https://api.twitter.com:443/1/users/show.json?screen_name=w+/ body: headers: accept: - application/json
  • Se match só com aURL não for suficiente?
  • • :method - The HTTP method (i.e. GET, POST, PUT or DELETE) of the request.• :uri - The full URI of the request.• :host - The host of the URI. You can use this (alone, or in combination with:path) as an alternative to :uri to cause VCR to match using a regex that matches the host.• :path - The path of the URI. You can use this (alone, or in combination with:host) as an alternative to :uri to cause VCR to match using a regex that matches the path.• :body - The body of the request. (Unsupported when you use FakeWeb.)• :headers - The request headers. (Unsupported when you use FakeWeb.)
  • VCR.use_cassette "whatever", :match_requests_on => [:host, :path] do # ...end
  • Múltiplos ciclosrequest/response em um mesmo teste
  • ---- !ruby/struct:VCR::HTTPInteraction request: !ruby/struct:VCR::Request method: :get uri: “http://example.com/blabla” # ... response: !ruby/struct:VCR::Response status: !ruby/struct:VCR::ResponseStatus code: 200 message: OK headers: # ...- !ruby/struct:VCR::HTTPInteraction request: !ruby/struct:VCR::Request method: :get uri: “http://example.com/foobar” # ... response: !ruby/struct:VCR::Response status: !ruby/struct:VCR::ResponseStatus code: 200 message: OK headers: # ...
  • Cassetes dinâmicos
  • ---- !ruby/struct:VCR::HTTPInteraction request: !ruby/struct:VCR::Request method: :get uri: http://example.com:80/foo?a=<%= some_arg %> body: headers: response: !ruby/struct:VCR::Response status: !ruby/struct:VCR::ResponseStatus code: 200 message: OK headers: # ...
  • VCR.use_cassette(dynamic, :erb => { :some_arg => 123 }) do # ...end
  • Atualização automática das gravações
  • A_WEEK = 7 * 24 * 60 * 60VCR.use_cassette(my_cassette, :re_record_interval => A_WEEK) do # ...end
  • Obrigado!