tag:www.rhnh.net,2008:/db2s3Db2s3 - Xavier Shay's Blog2009-03-10T08:33:15ZEnkiXavier Shaynotreal@rhnh.nettag:www.rhnh.net,2008:Post/7952009-03-10T08:33:15Z2009-03-10T08:33:15ZTesting Glue Code<p><a href="http://github.com/xaviershay/db2s3">db2s3</a> combines together 3 external dependencies – your database, the filesystem, and Amazon’s S3 service. It has 1 conditional in the main code path (and it’s not even an important one). The classic unit testing approach of “stub everything” provides little benefit.</p>
<p>Unit testing is good for ensuring complex code paths execute properly, that edge cases are properly explored, and for answering the question “what broke?”. For trivial glue code, none of these are of particular benefit. There are no complex code paths or edge cases, and it will be quickly obvious what broke. In fact, the most likely thing to “break” (or change) over time isn’t your code, but the external services it is sticking together, which stubs cannot protect you from. Considering the high relative cost of stubbing out all your dependencies, unit testing becomes an expensive way of testing something quite simple.</p>
<p>For glue code, integration tests are the best solution. Glue code needs to stick, and integration tests ensures that it does. Here is the only test that matters from db2s3:</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">it <span class="s"><span class="dl">'</span><span class="k">can save and restore a backup to S3</span><span class="dl">'</span></span> <span class="r">do</span><tt>
</tt> db2s3 = <span class="co">DB2S3</span>.new<tt>
</tt> load_schema<tt>
</tt> <span class="co">Person</span>.create!(<span class="sy">:name</span> => <span class="s"><span class="dl">"</span><span class="k">Baxter</span><span class="dl">"</span></span>)<tt>
</tt> db2s3.full_backup<tt>
</tt> drop_schema<tt>
</tt> db2s3.restore<tt>
</tt> <span class="co">Person</span>.find_by_name(<span class="s"><span class="dl">"</span><span class="k">Baxter</span><span class="dl">"</span></span>).should_not be_nil<tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<p>This test costs money to run since it hits the live S3 service, but only in the academic sense. The question you need to ask is “would I pay one cent to have confidence my backup solution works?”</p>
<p>Always remember why your are testing. <strong>Unit tests are a focussed tool, and not always necessary.</strong></p>