Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Testing HTTP APIs in Ruby - @shaiguitar - RailsConf 2013

Testing HTTP APIs in Ruby

@shaiguitar

  • Everything as a service
  • Test it!
  • Problem statement: Testing a server/client HTTP API
  • Good plan:
    • Create API
    • Build client lib that can be used in confusmer apps
    • Make it easy for consumer apps to test w/ our client library
  • How?

Isolation

  • Test server, code server, test client, code client
  • Have to use FakeWeb to mimic the server
    • Not testing the whole thing
    • No integration
    • non-representative tests

Sandboxes

  • Running server that clients can test against
  • Server dev the same
  • Test client against real server
  • If server API changes, test fail (good!)
  • But...
  • Setting up sandbox takes time
  • Server API changes require releases to sandbox
  • Real requests to sandbox slow down client tests
  • Unique data conflicts
  • Complex tests setup/teardown
  • No fixtures shipped with client
  • Still better than Isolation!

Fake Servers

  • Create a fake server to use in the client
  • Ship a fake_server.rb in the client
  • Mirror of API from the outside, doesn't do all internal stuff
module MyAPI
  class FakeServer < Sinatra::Base
  end
end
  • Fake server mimics API

  • Slim code, Keep it simple

  • Fast/in-memory

  • Ensure low dependencies

  • Run client tests against both real AND fake server

    • Local dev runs against just fake, CI runs against real (or both)
  • Fake is validated by 'real' run mode

  • Full integration

  • Local dev of client is quick

  • (fog & zendesk can do @client.mock!)

  • (Look up github.com/lanej/cistern)

  • More steps for client in making server code changes (mostly for client library developer)

Mapper style

  • Share more code!
  • Consolidate fake + real into one repo
  • Only EngineYard does this
  • Create a repo to hol
  • Mappers in both API repos which maps between fake/real
  • On rack you can mount shared API definitions together
  • mount RealOrFake::Server, :at => 'api'
  • Consumer apps using lib use fake mapper
  • Still have full integration
  • Less duplication of API definition code
  • Specific lib dependencies (Rack and Faraday)
  • Must be familiar w/ the concepts, it can be hard to maintain and enhance

Conclusions

  • This bubble is all about APIs
  • Consider using client to test server (sensical to couple server/client)
  • Validated fake API is great for local client dev

Questions/Comments

  • VCR could come in handy (use cached response locally, make fresh requests on CI)

Woah, we should have given the talk together! ;)

The slides are here:

github.com/shaiguitar/ruby_apis_and_clients

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment