tag:www.rhnh.net,2008:/rr Rr - Xavier Shay's Blog 2008-10-01T06:11:51Z Enki Xavier Shay notreal@rhnh.net tag:www.rhnh.net,2008:Post/786 2008-10-01T06:11:00Z 2008-10-01T06:11:51Z Integration testing with Cucumber, RSpec and Thinking Sphinx <p>Ideally you would want to include sphinx in your integration tests. It&#8217;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 &#8211; change the initializer for the <code>ThinkingSphinx::Configuration</code> to allow you to specify the environment). Here&#8217;s the rub though &#8211; if you&#8217;re using transactional fixtures the sphinx indexer won&#8217;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&#8217;re going to be making a few cups of coffee while they run.</p> <p>One approach I&#8217;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&#8217;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&#8217;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&#8217;t done it yet.</p> <p>Enough talk! Here&#8217;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> =&gt; 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>