opensoul.org

How to test dependencies on external services?

April 25, 2007 code 3 min read

I’ve been writing a lot of code lately that depends on external services, and I’ve really been struggling with how to test it well.

Tinder

The tests for Tinder, the unofficial Campfire “API”, are pathetic. Partially because it was originally just a proof of concept and partially because I just didn’t have a clue about how to write tests that would actually tests and not just execute the code.

The problem with Tinder is that it is really hard to isolate the tests. By default, every test will have 2 points of failure, the code to set up the test and the code to verify the result.

For example, here would be the test for deleting a room:

c = Tinder::Campfire.new 'mycampfire'
c.login('email', 'pass')
room = c.create_room 'My Test Room'
assert room.destroy
assert !c.find_room_by_name('My Test Room')

How do I know that it is working? All I’m testing is that #destroy returns true and that Tinder thinks that it is gone. Is that good enough? To make matters worse, every other test will depend on at least login with whatever other setup code is required.

Ideally, each API method would be tested by making assertions on the HTTP request/response.

Graticule

With Graticule, I decided that instead of requiring API keys for every service and hitting up against them with every test (especially since some services are pay-per-request), I would just save sample responses and mock the HTTP connection. This works really well as far as unit testing goes, but poses problems if services change their APIs.

Ideally, what I need is to be able to run the exact same test suite locally and remotely, but I haven’t figured out a good way to do the setup.

What is a wanna-be tester to do?

I could keep talking about examples (LDAP, CalDAV, etc.), but you get the point.

Testing isn’t supposed to worry about the internals of the code and only test the API, but with something like Tinder, how do you properly test it without peeking into the guts? What are some things you are doing to handle external dependencies?

This content is open source. Suggest Improvements.

@bkeepers

avatar of Brandon Keepers I am Brandon Keepers, and I work at GitHub on making Open Source more approachable, effective, and ubiquitous. I tend to think like an engineer, work like an artist, dream like an astronaut, love like a human, and sleep like a baby.