tag:www.rhnh.net,2008:/cucumberCucumber - Xavier Shay's Blog2008-10-01T06:11:51ZEnkiXavier Shaynotreal@rhnh.nettag:www.rhnh.net,2008:Post/7862008-10-01T06:11:00Z2008-10-01T06:11:51ZIntegration testing with Cucumber, RSpec and Thinking Sphinx<p>Ideally you would want to include sphinx in your integration tests. It’s really just like your database. In practice, this is problematic. Ensuring the DB is started and triggering a re-index after each model load is doable, if slow, with a small bit of hacking of thinking sphinx (hint – change the initializer for the <code>ThinkingSphinx::Configuration</code> to allow you to specify the environment). Here’s the rub though – if you’re using transactional fixtures the sphinx indexer won’t be able to see any of your data! Turning that off can really slow down your tests, and once you add in the re-indexing time you’re going to be making a few cups of coffee while they run.</p>
<p>One approach I’ve been taking is to stub out the <code>search</code> methods with <a href="http://github.com/btakita/rr/tree/master">RR</a>. I know, I know, stubbing in your integration tests is evil. I’m being pragmatic here. For most applications your search is trivial (find me results for this keyword), and if you unit test your <code>define_index</code> block you’re pretty well covered. To go one step further you could unit test your controllers with an expect on the search method, or have a separate suite of non-transactional integration tests running against sphinx. I like the latter, but haven’t done it yet.</p>
<p>Enough talk! Here’s the magic you need to get it working with <a href="http://github.com/aslakhellesoy/cucumber/tree/master">cucumber</a>:</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' }"><span class="c"># features/steps/env.rb</span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">rr</span><span class="dl">'</span></span><tt>
</tt><span class="co">Cucumber</span>::<span class="co">Rails</span>::<span class="co">World</span>.send(<span class="sy">:include</span>, <span class="co">RR</span>::<span class="co">Adapters</span>::<span class="co">RRMethods</span>)<tt>
</tt><tt>
</tt><span class="c"># features/steps/*_steps.rb</span><tt>
</tt><span class="co">Given</span> <span class="rx"><span class="dl">/</span><span class="k">a car with model '(</span><span class="ch">\w</span><span class="k">+)' exists</span><span class="dl">/</span></span> <span class="r">do</span> |model|<tt>
</tt> car = <span class="co">Car</span>.create!(<span class="sy">:model</span> => model)<tt>
</tt> stub(<span class="co">Car</span>).search(model) { [car] }<tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>