
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cory Schires &#187; Cucumber</title>
	<atom:link href="http://coryschires.com/tag/cucumber/feed/" rel="self" type="application/rss+xml" />
	<link>http://coryschires.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 14 Feb 2012 22:45:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Ten tips for writing better Cucumber steps</title>
		<link>http://coryschires.com/ten-tips-for-writing-better-cucumber-steps/</link>
		<comments>http://coryschires.com/ten-tips-for-writing-better-cucumber-steps/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 23:08:19 +0000</pubDate>
		<dc:creator>Cory Schires</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Best-Practices]]></category>
		<category><![CDATA[Capybara]]></category>
		<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby-on-Rails]]></category>

		<guid isPermaLink="false">http://coryschires.com/?p=420</guid>
		<description><![CDATA[I've written hundreds of Cucumber steps. Here's some tips I learned along the way.]]></description>
			<content:encoded><![CDATA[<h3>1. Use flexible pluralization.</h3>
<p>Add a <span class="code_text">?</span> immediately following the pluralized word:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Then /^the users? should receive an email$/ do
          # ...
        end
    </pre>
</div>
<p>The <span class="code_text">?</span> specifies that your looking for zero or more of the proceeding character. So the above example will capture both <span class="code_text">user</span> and <span class="code_text">users</span>.</p>
<h3>2. Use non-capturing groups to help steps read naturally.</h3>
<p>You can create non-capturing groups by adding a <span class="code_text">?:</span> to the beginning of a otherwise normal group (e.g. <span class="code_text">(?:some text)</span> rather than <span class="code_text">(some text)</span>). This is treated exactly like a normal group except that the result will is not captured and thus not passed as an argument to your step definition. This often useful in conjunction with alternation:</p>
<div class="code_block">
<pre class="brush: ruby;">
        And /^once the files? (?:have|has) finished processing$/ do
          # ...
        end
    </pre>
</div>
<p>Or another pattern I use regularly:</p>
<div class="code_block">
<pre class="brush: ruby;">
        When /^(?:I|they) create a profile$/ do
          # ...
        end
    </pre>
</div>
<h3>3. Consolidate step definitions by capturing optional groups.</h3>
<p>Often I find myself writing essentially the same step with both positive and negative assertions. You can remove this duplication by capturing an optional group:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Then /^I should( not)? see the following columns: "([^"]*)"$/ do |negate, columns|
          within('table thead tr') do
            columns.split(', ').each do |column|
              negate ? page.should_not(have_content(column)) : page.should(have_content(column))
            end
          end
        end
    </pre>
</div>
<p>Here we&#8217;re capturing an optional group (note <span class="code_text">( not)?</span> using the <span class="code_text">?</span> mentioned above). We then pass that into our step as the <span class="code_text">negate</span> variable which we can use to write conditional assertions.</p>
<h3>4. Not all matched phrases need to be surrounded by quotes.</h3>
<p>Don&#8217;t assume that matched phrases must (or should) be enclosed in double quotes. Often quotes are a good idea. They make it visually clear which phrases will be passed to the step definition. For example:</p>
<div class="code_block">
<pre class="brush: plain;">
        Given I have "potatoes" in my cart
    </pre>
</div>
<p>That&#8217;s reasonable. The quotes highlight the parts that change without hurting readability. But sometimes, quotes are just poor style:</p>
<div class="code_block">
<pre class="brush: plain;">
        Given I have "7" items in my cart
    </pre>
</div>
<p>It should be pretty obvious that the number is variable. The quotes add nothing except noise. A better step would read:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Then /^I have (\d+) items? in my cart$/ do |item_count|
          item_count.to_i.times { ... }
        end
    </pre>
</div>
<h3>5. Use transforms to make smarter, DRYer regular expressions.</h3>
<p>There&#8217;s an opportunity to refactor the previous example. Do you see it? Cucumber passes everything as a string, so you must remember to convert types within your step definition (e.g. above we use <span class="code_text">to_i</span> to transform <span class="code_text">item_count</span> into a proper integer). That&#8217;s annoying and easy to forget.</p>
<p>Fortunately, Cucumber gives us a way to avoid this peskiness by using <span class="code_text">Transform</span>:</p>
<div class="code_block">
<pre class="brush: ruby;">
        CAPTURE_A_NUMBER = Transform /^\d+$/ do |number|
          number.to_i
        end
    </pre>
</div>
<p>And we can use this in our steps:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Then /^I have (#{CAPTURE_A_NUMBER}) items? in my cart$/ do |item_count|
          item_count.times { ... }
        end
    </pre>
</div>
<p>Not only have we removed the need to call <span class="code_text">to_i</span> but we&#8217;ve also moved our regex into a reusable constant.</p>
<h3>6. Define methods to DRY up your step definitions.</h3>
<p>Sometimes it&#8217;s a good idea to remove duplication by defining methods. For example, it&#8217;s common to define a <span class="code_text">current_user</span> method:</p>
<div class="code_block">
<pre class="brush: ruby;">
        def current_user
          User.find_by_email('current_user@example.com')
        end
    </pre>
</div>
<p>Similarly, if you find yourself wrapping several steps with the same logic, you might consider making a helper method. On <a href="http://scholasticahq.com/">Scholastica</a>, we test a lot of lightboxes using of this method:</p>
<div class="code_block">
<pre class="brush: ruby;">
        def within_lightbox(opts = {sleep: 0} )
          sleep(opts[:sleep])
          within_frame("prettyPhotoIframe") { yield }
        end
    </pre>
</div>
<p>And our step definitions stay nice and clean:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Then /^some stuff should be visible in the lightbox$/ do
          within_lightbox { page.should have_content('Some Stuff') }
        end
    </pre>
</div>
<p>By convention, these methods should live in <span class="code_text">features/support/world_extensions.rb</span> and be included in the Cucumber <span class="code_text">World</span> module. But keep in mind this is a tradeoff: you&#8217;re removing duplication but adding indirection. You should be reluctant to define methods until the code makes it very obvious that it&#8217;s a good idea.</p>
<h3>7. Use steps within steps.</h3>
<p>Sometimes it&#8217;s useful to call steps within steps. Another example from <a href="scholasticahq.com">Scholastica</a>:</p>
<div class="code_block">
<pre class="brush: ruby;">
        When /^the request for an expedited decision should be canceled$/ do
          manuscript.should_not be_expedited
          step %{"#{current_user.email}" should receive an email with subject "Expedited decision request canceled"}
        end
    </pre>
</div>
<p>But don&#8217;t go crazy, it&#8217;s better to use the capybara methods directly when possible:</p>
<div class="code_block">
<pre class="brush: ruby;">
        When /^I update the email template to read "([^"]*)"$/ do |text|
          fill_in("email_template[text], with: text)
          click_button("Save changes and close")
          # Rather than...
          # step %{I fill in "email_template[text]" with "#{text}"}
          # step %{I press "Save changes and close"}
        end
    </pre>
</div>
<h3>8. Improve readability with unanchored regular expressions.</h3>
<p>Most step definitions look something like:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Given /^I am an admin user$/ do |item_count|
          # ...
        end
    </pre>
</div>
<p>Note we&#8217;re using <span class="code_text">^</span> and <span class="code_text">$</span> to anchor our regex to the start and end of the captured string. This ensures the regular expression exactly matches &#8220;I am an admin user&#8221; (i.e. allows no additional words at the beginning or end of the step). Most of the time, this is exactly what want.</p>
<p>Occasionally, however, it makes sense to omit the final <span class="code_text">$</span>. Take this step for example:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Then /^wait (\d+) seconds/ do |seconds|
          sleep(seconds.to_i)
        end
    </pre>
</div>
<p>Now you can use this definition to write flexible, expressive steps:</p>
<div class="code_block">
<pre class="brush: plain;">
        Then wait 2 seconds for the revenue statistics to finish loading
        Then wait 5 seconds while the document is converted
    </pre>
</div>
<h3>9. When your steps must include data, use tables.</h3>
<p>Generally, steps should be human readable and that means they shouldn&#8217;t include loads of cryptic data. But sometimes, you have no other choice. In those cases, use tables to clearly represent the data:</p>
<div class="code_block">
<pre class="brush: plain;">
        Given "Frankie's Hams" are selling for $25:
        And the following orders have been placed:
          | buyer email      | quantity |
          | eddy@example.com | 3        |
          | matt@example.com | 2        |
    </pre>
</div>
<p>Using tables within your step definitions can get a bit tricky. I use <a href="https://gist.github.com/1548498">this helper method</a> but you should really <a href="https://github.com/cucumber/cucumber/blob/master/lib/cucumber/ast/table.rb">read the relevant source code</a> and figure out what makes sense for your application.</p>
<h3>10. Don&#8217;t get carried away and spoil a good thing.</h3>
<p>As you use these tips, remember that tests should favor clarity over cleverness. In other words, if you&#8217;re removing a small amount of duplication but adding a lot of complexity, that&#8217;s a poor tradeoff. Here&#8217;s an example from <a href="scholasticahq.com">Scholastica</a>:</p>
<div class="code_block">
<pre class="brush: ruby;">
        Given /^(?:I|they) have opened (?:a|an) ([^\s]+) invitation$/ do |invitation_type|
          invitation = Factory("#{invitation_type}_invitation".to_sym, recipient: current_user, to: current_user.email)
          reset_mailer
          eval "ApplicationMailer.invite_#{invitation_type}(invitation).deliver"
          open_email(current_user.email)
        end
    </pre>
</div>
<p>This steps allows us to write both <span class="code_text">Given I have opened a reviewer invitation</span> and <span class="code_text">Given I have opened an editor invitation</span>. I&#8217;d say this step is borderline too complex (lots of interpolation and an eval). Maybe it would be better to just write two separate steps? Remember no one is testing your tests so don&#8217;t fuck around. A little bit of duplication is not the end of the world.</p>
]]></content:encoded>
			<wfw:commentRss>http://coryschires.com/ten-tips-for-writing-better-cucumber-steps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to equip rails for behavior driven development.</title>
		<link>http://coryschires.com/how-to-equip-rails-for-behavior-driven-development/</link>
		<comments>http://coryschires.com/how-to-equip-rails-for-behavior-driven-development/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 01:29:33 +0000</pubDate>
		<dc:creator>Cory Schires</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[Ruby-on-Rails]]></category>
		<category><![CDATA[Selenium]]></category>

		<guid isPermaLink="false">http://coryschires.com/?p=214</guid>
		<description><![CDATA[There's a lot of hype around behavior driven development. Learn how to get your application equipped for the challenge...]]></description>
			<content:encoded><![CDATA[<p>First, you&#8217;re going to need a few gems: cucumber, rspec-rails, rspec, and webrat. Although there are a number of ways you can get these running in your new rails project, the best plan is to set up gem dependencies directly in your application using the handy <span class="code_text">config.gem</span> command. </p>
<p>Just add these lines to <span class="code_text">config/environments/test.rb</span>:</p>
<div class="code_block">
<pre class="brush: ruby;">
		config.gem 'rspec-rails' , :lib => false
		config.gem 'rspec' , :lib => false
		config.gem 'cucumber'
		config.gem 'webrat'
	</pre>
</div>
<p>Next, make sure these gems are installed by typing:</p>
<div class="code_block">
<pre class="brush: plain;">
		RAILS_ENV=test sudo rake gems:install
	</pre>
</div>
<p>Finally, you&#8217;ll need to bootstrap your rails application for development with Cucumber and RSpec. Simply type:</p>
<div class="code_block">
<pre class="brush: plain;">
		script/generate rspec
		script/generate cucumber
	</pre>
</div>
<p>That&#8217;s it. Now you&#8217;re set up for behavior driven development in your rails app.</p>
]]></content:encoded>
			<wfw:commentRss>http://coryschires.com/how-to-equip-rails-for-behavior-driven-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

