<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>opensoul.org - How to test dependencies on external services? Changes</title>
  <id>tag:opensoul.org,2009:/2007/4/25/how-to-test-dependencies-on-external-services/changes</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  <link href="http://opensoul.org/2007/4/25/how-to-test-dependencies-on-external-services/changes.xml" rel="self" type="application/atom+xml"/>
  <link href="/2007/4/25/how-to-test-dependencies-on-external-services" rel="alternate" type="text/html"/>
  <updated>2007-04-25T19:35:27Z</updated>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2007-04-25:292:1</id>
    <updated>2007-04-25T19:35:27Z</updated>
    <link href="http://opensoul.org/2009/3/12/how-to-test-dependencies-on-external-services" rel="alternate" type="text/html"/>
    <title>How to test dependencies on external services?</title>
<content type="html">&lt;p&gt;I&#8217;ve been writing a lot of code lately that depends on external services, and I&#8217;ve really been struggling with how to test it well.&lt;/p&gt;


	&lt;h3&gt;Tinder&lt;/h3&gt;


	&lt;p&gt;The tests for &lt;a href=&quot;http://tinder.rubyforge.org&quot;&gt;Tinder&lt;/a&gt;, the unofficial &lt;a href=&quot;http://campfirenow.com&quot;&gt;Campfire&lt;/a&gt; &#8220;API&#8221;, are pathetic. Partially because it was originally just a proof of concept and partially because I just didn&#8217;t have a clue about how to write tests that would actually tests and not just execute the code.&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;For example, here would be the test for deleting a room:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;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')&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;How do I know that it is working?  All I&#8217;m testing is that &lt;code&gt;#destroy&lt;/code&gt; 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.&lt;/p&gt;


	&lt;p&gt;Ideally, each &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; method would be tested by making assertions on the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; request/response.&lt;/p&gt;


	&lt;h3&gt;Graticule&lt;/h3&gt;


	&lt;p&gt;With &lt;a href=&quot;http://graticule.rubyforge.org&quot;&gt;Graticule&lt;/a&gt;, I decided that instead of requiring &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; 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 &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; connection.  This works really well as far as unit testing goes, but poses problems if services change their APIs.&lt;/p&gt;


	&lt;p&gt;Ideally, what I need is to be able to run the exact same test suite locally and remotely, but I haven&#8217;t figured out a good way to do the setup.&lt;/p&gt;


	&lt;h3&gt;What is a wanna-be tester to do?&lt;/h3&gt;


	&lt;p&gt;I could keep talking about examples (LDAP, &lt;a href=&quot;http://rubyforge.org/projects/caldav&quot;&gt;CalDAV&lt;/a&gt;, etc.), but you get the point.&lt;/p&gt;


	&lt;p&gt;Testing &lt;strong&gt;isn&#8217;t supposed&lt;/strong&gt; to worry about the internals of the code and only test the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, 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?&lt;/p&gt;</content>  </entry>
</feed>
