tag:kinderman.net,2005:/tag/gemkinderman.net : Tag gem, everything about gemcode code code2009-11-04T16:58:32-08:00Typotag:kinderman.net,2005:Article/1102009-11-01T19:36:22-08:002009-11-04T16:58:32-08:00ryanIntroducing Spectie, a behavior-driven-development library for RSpec<p>I'm a firm believer in the importance of <a href="http://kinderman.net/articles/2007/11/18/testing-on-high-bottom-up-versus-top-down-test-driven-development">top-down</a> and behavior-driven development. I often start writing an integration test as the first step to implementing a story. When I started doing Rails development, the expressiveness of Ruby encouraged me to start building a DSL to easily express the way I most-often wrote integration tests. In the pre-<a href="http://rspec.info/">RSpec</a> days, this was just a subclass of ActionController::IntegrationTest that encapsulated the session management code to simplify authoring tests from the perspective of a single user. As the <a href="http://dannorth.net/introducing-bdd">behavior-driven development</a> idea started taking hold, I adapted the DSL to more-closely match those concepts, and finally integrated it with RSpec. The result of this effort was Spectie (rhymes with necktie).</p>
<p>The primary goal of Spectie is to provide a simple, straight-forward way for developers to write BDD-style integration tests for their projects in a way that is most natural to them, using existing practices and idioms of the Ruby language.</p>
<p>Here is a simple example of the Spectie syntax in a Rails integration test:</p>
<pre><code>Feature "Compelling Feature" do
Scenario "As a user, I would like to use a compelling feature" do
Given :i_have_an_account, :email => "ryan@kinderman.net"
And :i_have_logged_in
When :i_access_a_compelling_feature
Then :i_am_presented_with_stunning_results
end
def i_have_an_account(options)
@user = create_user(options[:email])
end
def i_have_logged_in
log_in_as @user
end
def i_access_a_compelling_feature
get compelling_feature_path
response.should be_success
end
def i_am_presented_with_stunning_results
response.should have_text("Simply stunning!")
end
end
</code></pre>
<h1>Install</h1>
<p>Spectie is available on <a href="http://github.com/ryankinderman/spectie">GitHub</a>, <a href="http://gemcutter.org/gems/spectie">Gemcutter</a>, and <a href="http://rubyforge.org/projects/kinderman/">RubyForge</a>. The following should get it installed quickly for most people:</p>
<pre><code>% sudo gem install spectie
</code></pre>
<p>For more information on using Spectie, visit <a href="http://github.com/ryankinderman/spectie">http://github.com/ryankinderman/spectie</a>.</p>
<h1>Why not Cucumber or Coulda?</h1>
<p>At the time that this is being written, Cucumber is the new hotness in BDD integration testing. My reasons for sticking with Spectie instead of switching to <a href="http://github.com/aslakhellesoy/cucumber">Cucumber</a> like the rest of the world are as follows:</p>
<ul>
<li>Using regular expressions in place of normal Ruby method names seems like a potential maintenance nightmare, above and beyond the usual potential.</li>
<li>The layer of indirection that is created in order to write tests in plain text doesn't seem worth the cost of maintenance in most cases.</li>
<li>Separating a feature from its "step definitions" seems mostly unnecessary. I like keeping my scenarios and steps in one file until the feature becomes sufficiently big that it warrants extra organizational consideration.</li>
</ul>
<p>These reasons are more-or-less the same as those given by Evan Light, who recently published <a href="http://github.com/elight/coulda">Coulda</a>, which is his solution for avoiding the cuke. What sets Spectie apart from Coulda is its reliance on and integration with RSpec. The Spectie 'Feature' statement has the same behavior as an RSpec 'describe' statement, and the 'Scenario' statement is the same as the RSpec 'example' and 'it' statements. By building on RSpec, Spectie can take advantage of the contextual nesting provided by RSpec, and rely on RSpec to provide the BDD-style syntax within what I've been calling a scenario statement (the words after the Given/When/Thens). Coulda is built directly on Test::Unit. I'm a firm believer in code reuse, and RSpec is the de facto standard for writing BDD-style tests. Spectie, then, is a feature-driven skin on top of RSpec for writing BDD-style integration tests. To me, it only makes sense to do things that way; as RSpec evolves, so will Spectie.</p>tag:kinderman.net,2005:Article/1042007-11-16T18:39:44-08:002007-11-16T18:39:44-08:00ryanBug: composite_primary_keys and belongs_to with :class_name option<p>For those of you using the composite_primary_keys gem as of version 0.9.0, you may encounter an issue if you try to do something like:</p>
<pre><code>class Reading < ActiveRecord::Base
belongs_to :reader, :class_name => "User"
end
</code></pre>
<p>When a User is loaded up from the database via the <code>reader</code> association, the CPK modification to <code>ActiveRecord::Reflection::AssociationReflection#primary\_key\_name</code> incorrectly returns <code>"user_id"</code> as the primary key name. If you encounter this issue, I've submitted a patch against revision 124 that can be obtained <a href="http://groups.google.com/group/compositekeys/browse_thread/thread/502e6b0d77cac8c9">here</a>.</p>
<p>Hopefully this will get fixed in the next release. More hopefully, I won't need to care by then.</p>