<?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>Pathfinder Development &#187; Test Driven Development</title>
	<atom:link href="http://www.pathf.com/blogs/tag/test-driven-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pathf.com/blogs</link>
	<description>Running commentary about agile development, user experience design and Ajax.</description>
	<lastBuildDate>Tue, 16 Mar 2010 13:42:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>edge case city: requirements and testing dates for HR business logic</title>
		<link>http://www.pathf.com/blogs/2009/09/edge-case-city-requirements-testing-dates-hr-business-logic/</link>
		<comments>http://www.pathf.com/blogs/2009/09/edge-case-city-requirements-testing-dates-hr-business-logic/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 16:42:25 +0000</pubDate>
		<dc:creator>Jason Sendelbach</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Application Development]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3996</guid>
		<description><![CDATA[edge case city: requirements and testing dates for HR business logic
We have an internal application that does staffing, time entry, and now Paid Time Off (PTO) accrual, scheduling and management.  It is quite nice, as it has replaced three existing systems, and replaced a number of manual, tedious tasks.  I started it last [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/09/edge-case-city-requirements-testing-dates-hr-business-logic/">edge case city: requirements and testing dates for HR business logic</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2006/04/ajax_and_leaky_/' rel='bookmark' title='Permanent Link: Ajax and Leaky Business Logic'>Ajax and Leaky Business Logic</a></li><li><a href='http://www.pathf.com/blogs/2006/06/the_hazards_of_-3/' rel='bookmark' title='Permanent Link: The Hazards of Exposing Business Logic on the Client'>The Hazards of Exposing Business Logic on the Client</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>edge case city: requirements and testing dates for HR business logic</p>
<p>We have an internal application that does staffing, time entry, and now Paid Time Off (PTO) accrual, scheduling and management.  It is quite nice, as it has replaced three existing systems, and replaced a number of manual, tedious tasks.  I started it last year, as our current system was very inefficient.  It was a simple Ruby on Rails app that I was able to get working in a few weeks.  Over time the functionality grew.</p>
<p>We recently added in PTO accrual and functionality to debit PTO time.  In doing so in a test driven manner was great, as we could put all the edge cases.  What we found was that many of the requirements were plentiful with edge cases.  For instance, we get paid on the 15th or end of the month, unless that is a weekend. Then we get paid on a Friday - Except if that Friday is a holiday, then the previous Thursday - Except - if that is also a holiday.... So it is really the previous non-weekend, non-holiday on or before the 15th  or end of the month.  The same holds true to determine the beginning of the billing period.  If the Monday is the 2nd, than for some operations the effective billing period start is Tuesday the third.... Ugh...</p>
<p>Our initial thoughts were filled with visions of lots of very similar tests for all contexts that do things depending on the start or end of a billing period.  We didn't want to have lots of duplicate test code to test all edge cases, so we decided to extend the Date object to have a few helper methods to do the complicated logic in one place.  We get the full range of the billing period start and end, and then trim off any holidays or weekends.  What this did, was allow us to test the complicated logic in unit tests with a full set of complicated edge cases.  We created many crazy examples of billing periods starting and ending on weekends, holidays, and holidays before and after weekends.  This created a very robust set of methods to be used anywhere in the system.</p>
<p>We then mocked a call to each Date helper method everywhere in the system where it cared about what day it was, and weather it was the start/end of a billing period.  We had only a few edge cases now: is it the true effective billing period start/end, or not.  Our tests could then focus on the guts of what it actually did, regardless of the effective date.</p>
<p>This demonstrates how powerful unit testing is, and how mocking can really keep your tests concise.  It made not only our code cleaner, but our tests cleaner.  It reduced duplicate code, and increased our assurance that the code will function as designed.  </p>
<p>That being said, it still doesn't change the fact that implementing HR logic in any language is a pain in the ass.  I have worked on a couple of systems for accounting departments in the past, and their business requirements are much worse than HR.  Dealing with job codes, general ledger accounts, etc can make your head spin.  All I know, is that without TDD, this system would be buggy.</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/09/edge-case-city-requirements-testing-dates-hr-business-logic/">edge case city: requirements and testing dates for HR business logic</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2006/04/ajax_and_leaky_/' rel='bookmark' title='Permanent Link: Ajax and Leaky Business Logic'>Ajax and Leaky Business Logic</a></li><li><a href='http://www.pathf.com/blogs/2006/06/the_hazards_of_-3/' rel='bookmark' title='Permanent Link: The Hazards of Exposing Business Logic on the Client'>The Hazards of Exposing Business Logic on the Client</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/09/edge-case-city-requirements-testing-dates-hr-business-logic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ask A Rails Tester Person</title>
		<link>http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/</link>
		<comments>http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 15:39:20 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3945</guid>
		<description><![CDATA[
Ask Mr. Lizard, from Jim Henson's Dinosaurs
It's time to play "Ask A Tester Person", where I answer questions that I've gotten via email or otherwise about Rails Testing topics. 
If you have a question for Ask A Tester Person, send it to railsprescriptions at gmail.com.

Before I continue, I want to mention that Pathfinder's own John [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/">Ask A Rails Tester Person</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/elements-of-testing-style/' rel='bookmark' title='Permanent Link: Elements of Testing Style'>Elements of Testing Style</a></li><li><a href='http://www.pathf.com/blogs/2009/05/rails-testing-frequently-asked-questions-the-non-code-version/' rel='bookmark' title='Permanent Link: Rails Testing Frequently Asked Questions &#8212; The Non-Code Version'>Rails Testing Frequently Asked Questions &#8212; The Non-Code Version</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><img src="http://www.pathf.com/blogs/wp-content/uploads/2009/09/8B461F0C-C372-4689-A81C-146FD44E5EEB.jpg" alt="Ask Mr. Lizard" border="0" width="" height="" class="right"/><br clear="all"/><br />
<span class="right" style="font-size: smaller">Ask Mr. Lizard, from Jim Henson's Dinosaurs</span></div>
<p>It's time to play "Ask A Tester Person", where I answer questions that I've gotten via email or otherwise about Rails Testing topics. </p>
<p>If you have a question for Ask A Tester Person, send it to railsprescriptions at gmail.com.</p>
<div style="border: thin solid blue; padding: 5px">
Before I continue, I want to mention that Pathfinder's own John McCaffrey and myself will both be presenting at <a href="http://www.windycityrails">WindyCityRails 2009</a>, which is September 12th at the Westin Chicago River North. There are still some seats available for the main conference talks, registration is open until September 10th. So sign up and we'll see you there.
</div>
<p>I've got two questions today:<br />
<span id="more-3945"></span><br />
<h3>Question 1: I'm writing too many tests!</h3>
<blockquote><p>One subject I still have questions<br />
about is how to test authorization in controller tests. In my<br />
applications I've been testing three different user cases for every<br />
controller action, but this leads to, for example:</p>
<pre style="white-space: pre !important;">
test_edit_by_anonymous_user
test_edit_by_unauthorized_user
test_edit_by_authorized_user
</pre>
<p>So every action has at least three tests, which obviously means a<br />
*ton* of tests for the entire application. This has always felt like<br />
overdoing it but I haven't yet been able to convince myself that just<br />
testing the authorization part of the code is sufficient. If I could<br />
isolate the authorization mechanism for testing that might convince<br />
me, but I'm not really able to do that (maybe my authorization process<br />
needs to be redesigned?), and I'm not sure I'd be convinced<br />
anyway...how the application responds in all three cases seems like<br />
something that *should* be tested for every action...
</p></blockquote>
<p>I doubt that your authorization process needs to be redesigned, but then I've never seen your authentication process.</p>
<p>I'd recommend a couple of different things to clean this up a bit. On the assumption that unauthorized access has largely the same behavior across the application, you can create a boilerplate test like this example -- the example uses Shoulda, but the basic idea should work in any framework.</p>
<pre style="white-space: pre !important;">
  self.def should_block_access_for_anonymous_user(*actions)
    actions.each do |action|
      should "block anonymous access for #{action}" do
        logout_current_user
        get action
        assert_redirected_to root_path
      end
    end
	end
</pre>
<p>Which you would then use as:</p>
<pre style="white-space: pre !important;">
  should_block_access_for_anonymous_user :edit, :update, :delete
</pre>
<p>The implementation shown here is probably a little too simplistic for full use (you might need to pass more information than just the action for each request), but the simple version could easily cover the most basic authentication issues with very little fuss.</p>
<p>If your authentication system is more complicated, the other option is nested contexts -- again, this is in Shoulda, but can be adapted to RSpec or the Context gem:</p>
<pre style="white-space: pre !important;">
context "GET edit" do

  setup do
    # generic edit setup here
  end

  context "with an anonymous user" do
    setup do
      logout
      get edit
    end

    should "not allow access" do
      assert_redirected_to root_path
    end
  end

  context "with an admin user" do
    setup do
      login_as_admin
      get edit
    end

    should "allow access" do
      assert_response :success
    end
  end

end
</pre>
<p>The upside of this compared with what you are probably doing is that it consolidate the setup between the different options. The downside is that it can be kind of verbose and hard to follow. But it's still potentially easier than writing three separate tests for each action.</p>
<h3>Question two: I'm creating too many objects!</h3>
<blockquote><p>Okay, I actually can't find the email that this came from, which is driving me crazy, because how do you lose an email message these days? Anyway, the gist was that this person's tests were running very slowly because he or she was creating so many objects for each test -- I distinctly remember the number 50 to 100 being tossed around. So the question was how to avoid creating so many objects?
</p></blockquote>
<p>The bottom line is that there's no way that you should need to create 50 to 100 objects for every TDD test, or even for any TDD test -- it's pretty rare that a unit-level test really needs that much data to work. There are a lot of potential issues here. Three that spring to mind are:</p>
<ul>
<li>You are trying to test too much code at one time. It's possible (though still not very likely) that an integration test might need that many objects, but testing a single method almost never does</li>
<li>You've transitioned from fixtures to factories, but you are still writing your tests as though you were using fixtures.</li>
<li>You have perhaps an unnecessary fixation on providing "realistic" data in unit tests.</li>
</ul>
<p>There's some overlap here. One cause of this is problem is that in fixtureland, there's very little marginal cost to creating new objects, so the tendency is to create fairly large aggregations of objects that cover all possibilities and have that be the universe for all the tests. When you transition to factories, though, keeping that big data blob around is not necessary. Since you can and should be custom-creating the data for each unit test, most model methods only need one model with specific attributes in order to specify the logic. Sometimes that model will need associated objects, but the factory tool can be set to create those automatically.</p>
<p>A special find method or named scope can be tested with as little as two objects -- one to be found and one to be skipped. Sort logic similarly can be tested with two or maybe three objects. If the logic is really complicated, it's better to do multiple tests with small amounts of data than one test with the whole shebang. The idea of a "unit" test is to verify one small piece of logic with as little data as possible, not to check program behavior under realistic data load -- that's what integration tests, performance tests, and actual user acceptance is for. </p>
<p>I feel like I'm answering the question "How do I create fewer objects in my tests?" with "By creating fewer objects in your tests", I hope this answer gives you some tools for minimizing the number of objects you need to create in your tests.</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a>, <a href="http://www.pathf.com//services/testing-quality-assurance/">Testing and Quality Assurance</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/">Ask A Rails Tester Person</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/elements-of-testing-style/' rel='bookmark' title='Permanent Link: Elements of Testing Style'>Elements of Testing Style</a></li><li><a href='http://www.pathf.com/blogs/2009/05/rails-testing-frequently-asked-questions-the-non-code-version/' rel='bookmark' title='Permanent Link: Rails Testing Frequently Asked Questions &#8212; The Non-Code Version'>Rails Testing Frequently Asked Questions &#8212; The Non-Code Version</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rails Test Prescriptions to be Published by Pragmatic</title>
		<link>http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/</link>
		<comments>http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 21:33:15 +0000</pubDate>
		<dc:creator>Bernhard Kappe</dc:creator>
				<category><![CDATA[Pathfinder General]]></category>
		<category><![CDATA[Pathfinder News]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[rails testing]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3550</guid>
		<description><![CDATA[
Rails Test Prescriptions, the eBook put out by Noel Rappin, Director of Rails Development at Pathfinder, has been picked up by Pragmatic.  
Congratulations to Noel - he's done a great job of furthering testing best practices in rails, and this is a great reward.   As he said "I’m very excited by this. [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/">Rails Test Prescriptions to be Published by Pragmatic</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/more-kudos-for-rails-prescriptions/' rel='bookmark' title='Permanent Link: More Kudos for Rails Prescriptions'>More Kudos for Rails Prescriptions</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2008/12/announcing-rails-prescriptions/' rel='bookmark' title='Permanent Link: Announcing Rails Prescriptions'>Announcing Rails Prescriptions</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/08/pragmatic.png" alt="Pragmatic Programmers" width="290" /></p>
<p>Rails Test Prescriptions, the eBook put out by Noel Rappin, Director of <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Rails Development</a> at Pathfinder, has been <a href="http://blog.railsprescriptions.com/2009/08/18/rails-test-prescriptions-to-be-published-by-pragmatic">picked up by Pragmatic</a>.  </p>
<p>Congratulations to Noel - he's done a great job of furthering testing best practices in rails, and this is a great reward.   As he said "I’m very excited by this. I’ve wanted to work with Pragmatic for as long as they’ve been publishing books, and I’m thrilled that this particular project will be able to get wider distribution and access to Pragmatic’s editorial expertise and skill."</p>
<p>     * The current free <a href="http://www.railsprescriptions.com/pdf/getting_started.pdf">“Getting Started with Rails Testing”</a> ebook will continue to be available. If, at some time in the future, there’s a better Getting Started tutorial in the Pragmatic book, it may be offered as a replacement.</p>
<p>    * The update site for current Rails Test Prescription owners will continue to be available for the foreseeable future.</p>
<p>    * There will be one more official update to the current Rails Test Prescriptions, probably around the end of August. This will wrap up the chapter or two I’m working on, and tie up some other loose ends.</p>
<p>    * After that, errata and information about changes to test tools will most likely be handled via this blog and an errata page on the rails test prescriptions site.</p>
<p>This is Noel's 4th book with a major publisher, following <a href="http://www.pathf.com/ideas/books/professional-ruby-on-rails/">Professional Ruby on Rails</a>, wxPython in Action and Jython Essentials.  We're happy for Noel and happy to have him at Pathfinder.  </p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a> </p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/">Rails Test Prescriptions to be Published by Pragmatic</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/more-kudos-for-rails-prescriptions/' rel='bookmark' title='Permanent Link: More Kudos for Rails Prescriptions'>More Kudos for Rails Prescriptions</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2008/12/announcing-rails-prescriptions/' rel='bookmark' title='Permanent Link: Announcing Rails Prescriptions'>Announcing Rails Prescriptions</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Functional Testing Annoyances, Wapcaplet, And You</title>
		<link>http://www.pathf.com/blogs/2009/08/functional-testing-annoyances-wapcaplet-and-you/</link>
		<comments>http://www.pathf.com/blogs/2009/08/functional-testing-annoyances-wapcaplet-and-you/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 21:45:10 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[rails testing]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[wapcaplet]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3436</guid>
		<description><![CDATA[Here's a minor thing that bugs me all the time.
I'm writing a functional test:

should "do something functional"
  get :search,  rder_id => @order.id, :user_id => @user.id
  # and so on
end

The get call in that test simulates a browser request. Intuitively, you would (well, I would) expect this request to be identical to a [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/08/functional-testing-annoyances-wapcaplet-and-you/">Functional Testing Annoyances, Wapcaplet, And You</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/09/rails-ajax-rjs/' rel='bookmark' title='Permanent Link: Rails, Ajax, RJS, and Testing'>Rails, Ajax, RJS, and Testing</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-testing-first-look-blue-ridge/' rel='bookmark' title='Permanent Link: Rails Testing First Look: Blue Ridge'>Rails Testing First Look: Blue Ridge</a></li><li><a href='http://www.pathf.com/blogs/2009/07/elements-of-testing-style/' rel='bookmark' title='Permanent Link: Elements of Testing Style'>Elements of Testing Style</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Here's a minor thing that bugs me all the time.</p>
<p>I'm writing a functional test:</p>
<pre style="white-space: pre !important;">
should "do something functional"
  get :search, <img src='http://www.pathf.com/blogs/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder_id => @order.id, :user_id => @user.id
  # and so on
end
</pre>
<p>The <code>get</code> call in that test simulates a browser request. Intuitively, you would (well, I would) expect this request to be identical to a request coming from the actual view, via a helper like <code>link_to("search", :action => :search, <img src='http://www.pathf.com/blogs/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder_id => @order.id, :user_id => @user.id)</code>. At least, you'd expect that parameters hash in the controller to be the same between the </p>
<p>Makes sense, right? The testing call should set up the same environment as the actual call being tested.<span id="more-3436"></span>Well, if you've gotten this far, read the title that said "Annoyances", or have ever read any blogs, you know that isn't how Rails works. Specifically, the actual browser call has all its arguments converted to strings as part of going through the HTTP wire, but Rails, oddly, does not similarly convert the arguments in the test. </p>
<p>Most of the time it makes no difference -- if you pass the string or the integer directly to an ActiveRecord find method, everything works swimmingly. If you do a direct equality check on the parameter, though, you can get code that passes tests, but fails in the browser because the string value is no longer equal to the integer value.</p>
<p>For some time, I've had this on my list of annoyances that I don't have the energy to fix, right next to the slightly misaligned light over my desk, and the fact that they bought the wrong kind of Kleenex at the office that one time.  </p>
<p>This week, <a href="http://pivotallabs.com/users/amilligan/blog/articles/951-wapcaplet">Adam Milligan at Pivotal Labs</a> tried to do something about it. Specifically, he created a Rails patch, then a plugin, that can raise a warning or an error when a non-string argument is passed to an HTTP method in a functional test.</p>
<p>Adam chose to fail or warn rather than silently convert the parameter because he feels that some arguments that might get placed in an HTTP method don't have clear correct conversions (his example is <code>false</code>), and he's trying to avoid setting up a whole different kind of difficult-to-diagnose test to app misalignments. </p>
<p>As much as I love that Adam did this, I kind of think that it's more consistent with Rails design to silently convert, to make the browser call and the test consistent. Still, having the code warn or fail (your choice) is a pretty good way to get into good habits and avoid having to track down weird test errors. So, thanks, Adam. </p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/08/functional-testing-annoyances-wapcaplet-and-you/">Functional Testing Annoyances, Wapcaplet, And You</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/09/rails-ajax-rjs/' rel='bookmark' title='Permanent Link: Rails, Ajax, RJS, and Testing'>Rails, Ajax, RJS, and Testing</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-testing-first-look-blue-ridge/' rel='bookmark' title='Permanent Link: Rails Testing First Look: Blue Ridge'>Rails Testing First Look: Blue Ridge</a></li><li><a href='http://www.pathf.com/blogs/2009/07/elements-of-testing-style/' rel='bookmark' title='Permanent Link: Elements of Testing Style'>Elements of Testing Style</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/08/functional-testing-annoyances-wapcaplet-and-you/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Help, My Test Is Failing!</title>
		<link>http://www.pathf.com/blogs/2009/07/help-my-test-i-failing/</link>
		<comments>http://www.pathf.com/blogs/2009/07/help-my-test-i-failing/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 17:11:58 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Custom Application Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3399</guid>
		<description><![CDATA[Frustration, the game, photo by unlovalblesteve
Dot, dot, dot, dot, dot -- tests are passing, looks like it's time for lunch -- dot, dot, dot, dot, F. F? F? But the code works. I know it does. I think it does. Why is my test failing?
One of the most frustrating times as a TDD developer is [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/help-my-test-i-failing/">Help, My Test Is Failing!</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2008/02/lesser-known-te/' rel='bookmark' title='Permanent Link: Lesser Known Test Processes'>Lesser Known Test Processes</a></li><li><a href='http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/' rel='bookmark' title='Permanent Link: Again With The Test Driven Development'>Again With The Test Driven Development</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.flickr.com/photos/unloveable/2398611730/"><img src="http://farm3.static.flickr.com/2371/2398611730_4d027256e0_m_d.jpg" alt="Frustration, the game" border="0" width="" height="" class="right"/></a><br clear="all"/><span class="right" style="font-size: smaller"><a href="http://www.flickr.com/photos/unloveable/2398611730/">Frustration, the game, photo by unlovalblesteve</a></span></div>
<p>Dot, dot, dot, dot, dot -- tests are passing, looks like it's time for lunch -- dot, dot, dot, dot, F. F? F? But the code works. I know it does. I think it does. Why is my test failing?</p>
<p>One of the most frustrating times as a TDD developer is that moment when a test is failing and you don't know why, as opposed to the more normal case where the test fails as expected. Here's a grab bag of tips, tricks, hints, and thoughts to get us all through that difficult time.</p>
<div style="border: thin solid blue; padding: 5px">
	<strong>Self-promotion alert:</strong> More details about Rails testing can be found at <a href="http://www.railsrx.com">Rails Test Prescriptions</a>, there's a free getting started tutorial which contains an extensive section on Cucumber, and a <a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">nearly 300 pages and counting full book for $9</a>. Thanks. Also, follow <a href="http://www.twitter.com/railsrx">@railsrx</a> on Twitter for testing tips and updates.
</div>
<p><span id="more-3399"></span><br />
<h3>Something Must Have Changed</h3>
<p>This may be the most obvious piece of advice in the history of ever, but I find it's worth repeating, mantra-like, when confronted with a bad bug:</p>
<p>When a formerly-passing test fails, it means something changed.</p>
<p>It may be in the code, or the system, or the test. But it's probably not sunspots, and it's probably not evil spirits possessing your MacBook. (Unless you are either <a href="http://www.amazon.com/gp/product/0441016685?ie=UTF8&tag=10prinhell-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0441016685">living in a Charles Stross novel</a> or writing Perl, but I digress...) </p>
<p>Looking through recent changes can help figure out what the cause of the failure is. Git's bisect tool can do this automatically, or you can just look through recent changes in your source control viewer of choice. If the test was passing at one time, there's a good chance the answer is in there somewhere.</p>
<p>This is a great argument in favor of committing to your source control very, very frequently (especially when you are using git and can do local commits), so that your changes are very granular.</p>
<h3>Isolate</h3>
<p>When looking at a small number of failing tests, it's helpful to be able to run just those tests. Autotest is outstanding for this, since it will run the failing tests over and over until they pass. This is especially helpful if you have a number of failing tests that are not in the same test class.</p>
<p><a href="http://gist.github.com/101130">This little code and terminal snippet</a> is very helpful for quickly running one class at a time, which is almost like isolating a failing test, or at least close enough to be useful. Depending on your IDE and test framework of choice, you may also be able to run individual tests from the IDE.</p>
<p>Isolating tests makes the tests run faster when you are focused on just a few tests, and also makes any diagnostics you insert easier to interpret.</p>
<p>Two tips that I've stolen from listening to and reading Kent Beck:</p>
<ul>
<li>Back out your entire most recent change since your last passing test and start over. This works best if you work in very small increments, but it gets you out of the "I know I typed something wrong but I just can't see it" nightmare</li>
<li>Replace all the expressions in the method under test with literals -- if that passes, then put the expressions back one by one until you find the culprit.</li>
</ul>
<h3>Diagnose</h3>
<p>I have to say, I'm not a big fan of using stop-and-step debuggers. I've used them when I've been in an IDE, I've never really used the Rails command line debugger, but mostly I've found that not to be a great experience. </p>
<p>Normally, to diagnose what's going on in a test, I usually either add additional assertions in the test or have the code print information to the console. If I diagnose via assertions, generally I'm testing the values of variables in more detail.</p>
<p>For some reason, I see a lot of people using Ruby's <code>puts</code> method to write to the console -- I recommend <code>p</code>, which calls <code>inspect</code> on the object before printing, and generally results in more informative output. As a matter of course, I put <code>require pp</code>, which allows me to use <code>pp</code> to get pretty-printed output, which is nice for nested data structures. Also, <code>y</code> gives a YAML representation of the output -- very readable for ActiveRecord objects.</p>
<pre style="white-space: pre !important;">
>> x = {1 => ['a', 'b'], 2 => 'c'}
>> puts x
1ab2c

>> p x
{1=>["a", "b"], 2=>"c"}

>> pp x
{1=>["a", "b"], 2=>"c"}

>> y x
---
1:
- a
- b
2: c
</pre>
<p>Especially if I have autotest running just the one test, I've been known to bury print statements all over the place -- controllers, Rails itself (often educational). Just remember to take them out when you are done.</p>
<h3>Clear Your Head</h3>
<p>Take a walk. Force your pair to solve the problem. Get a cup of coffee (actually, I hate coffee, get a Diet Coke). Take a nap. All those silly clear your head things really do work sometimes. </p>
<h3>Band Aids</h3>
<p>It's tempting sometimes to comment out the offending test and then your suite passes and all is well with the world again. That's generally a bad idea (although sometimes a major refactoring can genuinely make tests obsolete. </p>
<p>Hope this helps. What do you do to fix stubborn tests?</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/help-my-test-i-failing/">Help, My Test Is Failing!</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2008/02/lesser-known-te/' rel='bookmark' title='Permanent Link: Lesser Known Test Processes'>Lesser Known Test Processes</a></li><li><a href='http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/' rel='bookmark' title='Permanent Link: Again With The Test Driven Development'>Again With The Test Driven Development</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/07/help-my-test-i-failing/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Real Testing Example, Part Two</title>
		<link>http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/</link>
		<comments>http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 16:45:19 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[rails development]]></category>
		<category><![CDATA[rails testing]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3356</guid>
		<description><![CDATA[Spam Wall, by freezelight
What with upward of two people saying nice things about last week&#8217;s post, I&#8217;ve decided to keep going with part two of a look at some real testing code.
Most code-heavy tutorials show the code but not the tests &#8212; I&#8217;m doing the opposite here, and showing the tests, but not much of [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/">Real Testing Example, Part Two</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/a-real-testing-example/' rel='bookmark' title='Permanent Link: A Real Testing Example'>A Real Testing Example</a></li><li><a href='http://www.pathf.com/blogs/2009/07/elements-of-testing-style/' rel='bookmark' title='Permanent Link: Elements of Testing Style'>Elements of Testing Style</a></li><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.flickr.com/photos/63056612@N00/155554663/"><img src="http://farm1.static.flickr.com/59/155554663_89beb0ac63_m.jpg" alt="" border="0" width="" height="" class="right"/></a><br clear="all"/><span class="right" style="font-size: smaller"><a href="http://www.flickr.com/photos/63056612@N00/155554663/">Spam Wall, by freezelight</a></span></div>
<p>What with upward of two people saying nice things about <a href="http://www.pathf.com/blogs/2009/07/a-real-testing-example/">last week&#8217;s post</a>, I&#8217;ve decided to keep going with part two of a look at some real testing code.</p>
<p>Most code-heavy tutorials show the code but not the tests &#8212; I&#8217;m doing the opposite here, and showing the tests, but not much of the code. Also, although I&#8217;m presenting these tests in chunks, you should realize that there was a lot of back-and-forth from Cucumber to tests to code and some backtracking, most of which I&#8217;ll spare you from having to wade through.</p>
<p>At the end of last week, I had run through the tests for spam-prevention code which worked by limiting the rate at which a user could send messages to other users of a particular social networking site. Cucumber was involved, and I think I went off on a tangent about writing lots of tests.</p>
<div style="border: thin solid blue; padding: 5px">
	<strong>Self-promotion alert:</strong> More details about Rails testing can be found at <a href="http://www.railsrx.com">Rails Test Prescriptions</a>, there's a free getting started tutorial which contains an extensive section on Cucumber, and a <a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">nearly 300 pages and counting full book for $9</a>. Thanks. Also, follow <a href="http://www.twitter.com/railsrx">@railsrx</a> on Twitter for testing tips and updates.
</div>
<p><span id="more-3356"></span>
<p>Once the basic rate limiting code was in place, the client and I came up with a couple of special cases. The application allows a user to explicitly reply to a specific message sent to them. We agreed that these replies should not count towards the rate limit on the grounds that a reply was, pretty much by definition, not spam. Similarly, we decided that any message between users with a friend relationship on the site also doesn&#8217;t count toward the rate limit. More subtly, we decided that if a user was inadvertently blocked, then reinstated by an administrator, that their rate count should drop back to zero, so the user doesn&#8217;t just get immediately re-blocked.</p>
<p>The Cucumber tests:</p>
<pre><code>Scenario: Reply behavior
  Given I am a user who is not a new member
  When I send 4 messages in a day
  And I reply to a message
  And I send 1 message in a day
  Then 6 messages are sent
  And I am not blocked from sending further messages
  And the administrator does not get an email

Scenario: Friend Behavior
  Given I am a user who is not a new member
  When I send 4 messages in a day
  And I send a message to a friend
  And I send 1 message in a day
  Then 6 messages are sent
  And I am not blocked from sending further messages
  And the administrator does not get an email

Scenario: Unblocked behavior
  Given I am a user who is not a new member
  When I send 6 messages in a day
  Then I am blocked from sending further messages
  When I am unblocked by an administrator
  And I send 5 messages in a day
  Then 5 messages are sent
  And I am not blocked from sending further messages
  And the administrator does not get an email
</code></pre>
<p>These tests are quite similar in structure to the tests I started with last week. I might start thinking about combining some of the steps, but in Cucumber, I bias in favor of having the actual test be as clear and readable as I can get it. I don&#8217;t think these scenarios are so complicated that they require simplification.</p>
<p>Most of these steps have already been defined, here are a couple that aren&#8217;t. The first two steps are slight variants on the message sending step definition:</p>
<pre><code>When /^I reply to a message$/ do
  original_message = Factory.create(:message, :sender =&gt; @recipient,
      :recipient =&gt; @sender)
  message = Factory.attributes_for(:message, :sender =&gt; @user)
  message[:in_reply_to] = original_message.id
  visit(messages_path,
      :post, {:recipient =&gt; @recipient.id, :message =&gt; message})
end

When /^I send a message to a friend$/ do
  @user.become_friends_with(@recipient)
  visit(messages_path,
      :post,
      {:recipient =&gt; @recipient.id,
          :message =&gt; Factory.attributes_for(:message, :sender =&gt; @user)})
end
</code></pre>
<p>One thing that you may have noticed about these step definitions. Despite all my jumping up and down about Cucumber being a black-box system, both of these steps bypass the UI to complete the setup. The first step creates a factory message and the second step creates a friend relationship. In both cases, the actual message send being tested passes through the UI.</p>
<p>There are basically two reasons for bypassing the UI in the setup. One is, of course, that it&#8217;s the setup and not the action being tested, the second is that being a purist all the time is a pain, and it&#8217;s much easier to get the background info out of the way directly.</p>
<p>The final missing step, however, is completely through the UI &#8212; the step logs the user out, logs in as an administrator, navigates to the page, unblocks the user, and then logs the administrator out and the original user back in.</p>
<pre><code>When /^I am unblocked by an administrator$/ do
  @blocked = @user
  visit "/logout"
  Given "I am a logged in administrator"
  visit path_to("the admin messaging page")
  click_link("Unblock")
  @user = @blocked
  visit "/logout"
  Given "I am logged in"
  reset_mailer
end
</code></pre>
<p>A little on the Rube Goldberg side, perhaps, but it works.</p>
<p>With the Cucumber step definitions in place, the question becomes what tests and code need to be written to make these pass. For the first two scenarios that adjust the definition of what makes a message count toward the rate limit, the code change will be in the User and Message models. Since it&#8217;s a thin controller that defers to the models for data, there shouldn&#8217;t be any code change in the controller at all. </p>
<p>Now, that&#8217;s a much easier determination to make in hindsight than up front, and as it happens I did write controller tests for both of those scenarios, largely because they were so similar to the controller context chunks in last week&#8217;s post that it only took about five minutes to set them both up. </p>
<p>The real test action was in the user and message models. I added a database column for messages called <code>counts_toward_spam</code>. The idea is that this would be true for most messages, but false for replies, friend messages, or messages otherwise cleared by the admins. This requires some unit tests in the message class to support it. Again, I&#8217;m using Matchy here, and testing the boolean <code>spam_message?</code>, which is basically an alias for <code>counts_toward_spam</code> that I added for readability. In retrospect, adding the method was probably unnecessary.</p>
<pre><code>context "spam count" do

  setup do
    @sender = Factory.create(:user)
    @recipient = Factory.create(:user)
  end

  should "give an ordinary message a spam count" do
    @message = Message.new_from_params(
        {:subject =&gt; "fred", :body =&gt; "body"}, @sender, @recipient)
    @message.sender_id.should == @sender.id
    @message.recipient_id.should == @recipient.id
    @message.should be_spam_message
  end

  should "not give an ordinary message a spam count if it is a reply" do
    @message = @message = Message.new_from_params(
        {:subject =&gt; "fred", :body =&gt; "body", :in_reply_to =&gt; 11},
        @sender, @recipient)
    @message.should be_reply
    @message.should_not be_spam_message
  end

  should "not make a message between mutual friends a spam count" do
    @sender.become_friends_with(@recipient)
    @message = Message.new_from_params(
        {:subject =&gt; "fred", :body =&gt; "body"}, @sender, @recipient)
    @message.should be_friend_message
    @message.should_not be_spam_message
  end
end
</code></pre>
<p>The message tests simply set up the different classes of message and verify that they are classified appropriately, they are pretty straightforward.</p>
<p>I also added a test to user to verify that the spam count was being used appropriately &#8212; this is part of the same context as last week&#8217;s user tests. The user has already sent four messages in the setup.</p>
<pre><code>should "not count a reply message" do
  message = Factory.create(:message, :sender =&gt; @user,
      :created_at =&gt; 10.minutes.ago)
  message.in_reply_to = 3
  message.update_count_toward_spam
  message.save!
  @user.spam_message_count.should == 4
  @user.update_message_block_status.should be_nil
  @user.should be_able_to_send_messages
end
</code></pre>
<p>It&#8217;s interesting what you see when you go back over a chunk of code to explain it to other people. In this case what I notice is the <code>update_count_toward_spam</code> method, which is part of Message that unsets the  <code>count_toward_spam_</code> field if the message is a reply and is automatically called as part of the controller create message code. However, strictly speaking, it should be tested in the message class rather than here (although, the message controller tests would also exercise it).</p>
<p>That&#8217;s the bulk of the testing for those features &#8212; at the time, I didn&#8217;t think there were any other special cases. </p>
<p>The part about unblocking a user requires controller tests, because the unblock action needs to be written in the controller. I&#8217;m making it part of the message controller, although I know that RESTfully speaking it probably should be a separate resource &#8212; the legacy app is such a REST tangle that it&#8217;s not worth it.</p>
<p>The controller test context looks like this &#8212; the setup creates a blocked user and calls the unblock method.</p>
<pre><code>context "GET unblock" do

  setup do
    ActionMailer::Base.deliveries.clear
    @recipient = Factory.create(:user)
    @user = Factory.create(:user,
      :message_sending_status =&gt; User::BLOCKED_STATUS)
    @user.should_not be_able_to_send_messages
    admin!
    get :unblock, :user_id =&gt; @user.id.to_s
    @user.reload
  end

  expect { @user.should be_able_to_send_messages }
  expect { assert_redirected_to :action =&gt; :admin }

  should "send email to unblocked user" do
    assert_sent_email do |email|
      email.to.first == @user.email &amp;&amp;
      email.from.first == "do_not_reply@singlestravelintl.com"
    end
  end
end
</code></pre>
<p>The assertion tests verify that the user can send messages again, and that the user gets an email from the system to that effect. The associated user model test validates that the user&#8217;s spam message count is reset back to zero, which was the specific point of this round of tests (in the actual application, there were other Cucumber scenarios supporting basic administrative behavior).</p>
<pre><code>context "unblocking a user" do

  setup do
    Message.new_from_params(Factory.attributes_for(:message,
        :created_at =&gt; 10.minutes.ago), @user,
         Factory.create(:user)).save!
    @user.update_message_block_status.should == "blocked"
    @user.should_not be_able_to_send_messages
    @user.unblock_message_status
  end

  expect { @user.should be_able_to_send_messages }
  expect { @user.spam_message_count.should == 0 }

  should "reblock" do
    @user.block_message_status
    @user.should_not be_able_to_send_messages
  end

end
</code></pre>
<p>Anyway, the code that I wrote along side these tests to make them pass seemed to work fine, and we deployed to production.</p>
<p>Shortly thereafter, we got a bug report. I haven&#8217;t stressed it here, but new users were limited to a single message in their earliest time on the system. We heard from a new user who sent a message, received a reply, and then replied back to that message, only to find that he was blocked, even though the reply message shouldn&#8217;t count toward the rate limit.</p>
<p>Interesting. It&#8217;s one of those bugs that almost turns philosophical &#8212; exactly when in this process does a user become blocked? In the code that I originally wrote, a user was blocked as soon as he or she hit the rate limit, and before sending another message. In fact, the code should wait until the user tries to send that next message to consider that user blocked, because a user who is at the rate limit border should still be able to send replies and friend messages without being blocked. </p>
<p>So, bug. Since the bug involves multiple interactions, I started in Cucumber:</p>
<pre><code>Scenario: New User Behavior on reply
  Given I am a new user
  When I send 1 message in a day
  And I reply to a message
  Then 2 messages are sent
  And I am not blocked from sending further messages
</code></pre>
<p>All those step definitions exist, but the last two steps fail without further work. I wasn&#8217;t initially sure whether the code change for this would wind up in the controller or not &#8212; as it happened, it turned out to be a minor controller change and minor model change but it took me a few tries to get it right. </p>
<p>Since I already had a decent controller harness for similar scenarios, it took almost no time to adapt to the new condition:</p>
<pre><code>context "with a borderline new user and a reply" do

  setup do
    reply = Factory.create(:message, :recipient =&gt; @user,
        :sender =&gt; Factory.create(:user))
    flexmock(User).should_receive(:new_user?).and_return(true)
    flexmock(Message).should_receive(
        :toward_spam_in_last_24_hours).and_return(1)
    post :create, :recipient =&gt; @recipient.id,
        :message =&gt; Factory.attributes_for(:message, :sender =&gt; @user,
            :in_reply_to =&gt; reply.id.to_s)
    @user.reload
  end

  expect { @user.messages_sent.size.should == 1 }
  expect { @user.spam_message_count.should == 1 }
  expect { assigns(:message).should_not be_new_record }
  expect { @user.should_not be_message_sending_blocked }
  expect { assert_no_email_to_administrator }
end
</code></pre>
<p>I have to say, in retrospect, that I&#8217;m not 100% sold on the use of the mock package here &#8212; it&#8217;s a clear user of mocking to limit the test&#8217;s exposure to the model layer, but I&#8217;m not convinced it makes the test more clear or readable. This setup and tests is very similar to the other bundles of controller test and makes most of the same assertions.</p>
<p>The main change was in the user method, triggered by the following tests &#8212; one of which tests the positive sequence, one the negative &#8212; and yes, the setups probably should have been combined. </p>
<pre><code>should "move a new user to blocked mode after first message" do
  Timecop.freeze(Date.today)
  new_user = Factory.create(:user, :created_at =&gt; 1.day.ago)
  m = Message.new_from_params(Factory.attributes_for(:message),
      new_user, Factory.create(:user))
  m.created_at = 2.hours.ago
  m.save!
  assert_equal(2.hours.ago, new_user.last_message_sent_time)
  assert_equal("blocked", new_user.update_message_block_status(true))
  assert new_user.message_sending_blocked?
end

should "allow a new user a second message that is a reply" do
  Timecop.freeze(Date.today)
  new_user = Factory.create(:user, :created_at =&gt; 1.day.ago)
  m = Message.new_from_params(Factory.attributes_for(:message),
      new_user, Factory.create(:user))
  m.created_at = 2.hours.ago
  m.save!
  assert_equal(2.hours.ago, new_user.last_message_sent_time)
  assert_nil new_user.update_message_block_status(false)
  assert !new_user.message_sending_blocked?
end
</code></pre>
<p>The key here &#8212; which would be easier to see if the setups were combined &#8212; is the next to last line where <code>update_message_block_status</code> is called. That&#8217;s the method called by the controller when a new message is sent, and the <code>false</code> argument means that the new message does not count toward the rate limit. So in the second test, the user can still send messages, while in the first test, the user does move to a blocked status.</p>
<p>Having the existing suite of tests around the controller and model behaviors was a big relief when fixing this bug &#8212; it&#8217;d be easy to make a fix for this issue that affected one of the other scenarios (I know because I made fixes that broke a lot of tests&#8230;). This was a case where the tests clearly made me more confident in the fix that I made. </p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Full Life Cycle Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/">Real Testing Example, Part Two</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/a-real-testing-example/' rel='bookmark' title='Permanent Link: A Real Testing Example'>A Real Testing Example</a></li><li><a href='http://www.pathf.com/blogs/2009/07/elements-of-testing-style/' rel='bookmark' title='Permanent Link: Elements of Testing Style'>Elements of Testing Style</a></li><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A Real Testing Example</title>
		<link>http://www.pathf.com/blogs/2009/07/a-real-testing-example/</link>
		<comments>http://www.pathf.com/blogs/2009/07/a-real-testing-example/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 21:36:04 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[rails testing]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3265</guid>
		<description><![CDATA[Spam Wall, by freezelight
As sort-of promised in last week&#8217;s post, I&#8217;m going to work through a real-world test example, with an eye toward explaining how and why I tested the way I did. Hopefully, I&#8217;ll be able to do this at blog-post length. If not, well, there&#8217;s always next week.
This site, which was a legacy [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/a-real-testing-example/">A Real Testing Example</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/' rel='bookmark' title='Permanent Link: Real Testing Example, Part Two'>Real Testing Example, Part Two</a></li><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.flickr.com/photos/63056612@N00/155554663/"><img src="http://farm1.static.flickr.com/59/155554663_89beb0ac63_m.jpg" alt="" border="0" width="" height="" class="right"/></a><br clear="all"/><span class="right" style="font-size: smaller"><a href="http://www.flickr.com/photos/63056612@N00/155554663/">Spam Wall, by freezelight</a></span></div>
<p>As sort-of promised in <a href="http://www.pathf.com/blogs/2009/07/to-mock-or-not-to-mock/">last week&#8217;s post</a>, I&#8217;m going to work through a real-world test example, with an eye toward explaining how and why I tested the way I did. Hopefully, I&#8217;ll be able to do this at blog-post length. If not, well, there&#8217;s always next week.</p>
<p>This site, which was a legacy rescue, allows users to send messages to each other within the site without having to give away their other contact information. The problem is that nefarious spammer types were creating logins and immediately sending messages to large numbers of the user population, irritating them. After some deliberation, the client decided on a rate-limiting strategy, where a member could only send a certain number of messages in a day, and a new member could send even fewer messages a day. Messages above that point would require administrative action to unblock the user&#8217;s privileges.</p>
<div style="border: thin solid blue; padding: 5px">
	<strong>Self-promotion alert:</strong> More details about Rails testing can be found at <a href="http://www.railsrx.com">Rails Test Prescriptions</a>, there's a free getting started tutorial which contains an extensive section on Cucumber, and a <a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">nearly 300 pages and counting full book for $9</a>. Thanks. Also, follow <a href="http://www.twitter.com/railsrx">@railsrx</a> on Twitter for testing tips and updates.
</div>
<p><span id="more-3265"></span>I started with Cucumber tests &#8212; the first two are representative of the initial batch. Everything you see here is actual code, only slightly tweaked to anonymize details of the site. But I&#8217;m trying not to present simplified &#8220;example&#8221; code. That said, this is the final state of the code, there were some intermediate steps and false trails that I&#8217;m sparing you from having to read about. I&#8217;m also focusing on the tests here, rather than the resulting application code. </p>
<pre><code>Background:
  Given the user database is cleared
  Given a group of recipients.

Scenario: Normal User behavior
  Given I am a user who is not a new member
  When I try to send 5 messages in a day
  Then 5 messages are sent
  And the administrator does not get an email

Scenario: Excessive User behavior
  Given I am a user who is not a new member
  When I try to send 6 messages in a day
  Then 5 messages are sent
  And I am blocked from sending further messages
  And the administrator gets an email
</code></pre>
<p>This test uses an implicit style, so a lot of the details are in the step definitions. I start by writing the step definitions one by one until I get to one that I can&#8217;t make work without writing new code. As it happens, since not sending email is the current state of the system, the entire first scenario should work without any new code. It&#8217;s very important to include that scenario, though, to ensure that the new changes don&#8217;t break the basic behavior.</p>
<p>Here&#8217;s what the steps look like &#8212; the user who is not a new member defers to the boilerplate RESTful Authentication step for logging in:</p>
<pre><code>Given /^I am a user who is not a new member$/ do
  @user = Factory.create(:user, :created_at =&gt; 5.months.ago)
    Given "I am logged in"
end

Given /^I am logged in$/ do
  visit "/login"
  fill_in("email", :with =&gt; @user.email)
  fill_in("password", :with =&gt; @user.password)
  click_button("Sign in")
end
</code></pre>
<p>Next up, sending messages. Since the point of Cucumber is to treat the application as a black box, the step definition uses Webrat to simulate number of posts to the create message RESTful action. (The <code>@recipient</code> is created in the background action, which I didn&#8217;t show here because it&#8217;s not very interesting.)</p>
<pre><code>When /^I try to send (.*) message(.*) in a day$/ do |count, plural|
  count.to_i.times do
    visit(messages_path, :post, {:recipient =&gt; @recipient.id,
             :message =&gt; Factory.attributes_for(:message,
                                :sender =&gt; @user)})
  end
end
</code></pre>
<p>So this step definition allows you to match &#8220;send 3 messages&#8221; and &#8220;send 1 message&#8221; by adding that little group at the end of the message, that group needs to have an associated variable in the block argument list, but it&#8217;s just ignored. Somebody with better offhand regular expression skills could easily make it so the end of the expression only matches &#8220;message&#8221; or &#8220;messages&#8221;, but I can live with it being a little overly matchy for now.</p>
<p>Closing out the normal case, the step definition to test emails sent uses the excellent<br />
<a href="http://github.com/bmabey/email-spec/tree/master">email_spec</a> plugin, which creates RSpec matchers and Cucumber step definitions for email testing. This one checks an <code>all_emails</code> method, filters out any methods sent to the administrator, and makes sure the right number exist.</p>
<pre><code>Then /^(.*) message(.*) (is|are) sent$/ do |count, plural, verb|
  emails_out = all_emails.select do |e|
    !e.to.include?("admin@admin.com")
  end
  assert_equal(count.to_i, emails_out.size)
end
</code></pre>
<p>The administrator email step definition uses the email_spec steps directly &#8212; and yes, I could have included those steps explicitly in the Cucumber scenario. I chose not to, on the perhaps dubious grounds that I wanted to keep explicit string literals out of the scenario. But it doesn&#8217;t make that much difference either way.</p>
<pre><code>Then /^the administrator (gets|does not get) an email$/ do |status|
  if status == "gets"
    Then '"admin@admin.com" should receive an email'
  else
    Then '"admin@admin.com" should not receive an email'
  end
end
</code></pre>
<p>Everything here passes for the normal case. So far, my main note is that all the step definitions are really simple &#8212; it&#8217;s almost impossible to misinterpret them.</p>
<p>At this point, I move on to the blocking case. There&#8217;s one more step definition to write. In actuality, the &#8220;then 5 messages are sent&#8221; step will fail, since the blocking isn&#8217;t in the code. So, I would normally jump to writing regular tests at that point, but since I&#8217;m here, I&#8217;ll present the last step definition. </p>
<p>Cucumber is a black box, therefore in order to detect if the user is blocked, we need to find some place in the application that will display it. After  their initial notification, the user doesn&#8217;t see anything confirming their block status. But the administrator does, via an admin screen that actually hasn&#8217;t been written yet. So, the cucumber tests logs the user out, logs an admin in, and checks the admin page for a row associated with the user.</p>
<pre><code>Then /^I am blocked from sending further messages$/ do
  @sender = @user
  visit "/logout"
  Given "I am a logged in administrator"
  @admin = @user
  visit path_to("the admin messaging page")
  assert_select("tr#?", dom_id(@sender, :blocked_row), :count =&gt; 1)
end
</code></pre>
<p>This step definition is a bit more complicated than the others, and it&#8217;s also taking it slightly on faith that the row with the correct DOM id will actually have the information the admin needs. (The tradeoff in view testing, as  always is faith an flexibility vs. certainty and brittleness&#8230;)</p>
<p>Okay, there are genuinely failing Cucumber steps, it&#8217;s time to make them pass.</p>
<p>A couple of things to note:</p>
<ul>
<li>After going back and forth on this some, I&#8217;ve decided that Cucumber tests don&#8217;t really replace controller tests, except in maybe the simplest cases. My rationale is that Cucumber and controller tests look at different error conditions, and that Cucumber tests are really (partially) replacing the hand-testing that I would be doing to verify that the feature is working. Cucumber is the 30,000 foot view of the application, I still feel the need to test from the ground.</li>
<li>This app was a legacy with effectively no tests, leading me to have to write some extra tests to cover the normal, non-blocking case. If the whole app was TDD, then that functionality would already have tests, but since I&#8217;m working on the new features, I need to go back and cover the base functionality.</li>
</ul>
<p>The basic ideas is write the tests in the class where the code is going to go. I can guess that code will need to go in the <code>MessageController</code>, the <code>Message</code> model, and the <code>User</code> model. In fact, I&#8217;m going to need a new field in the user model, a string representing message sending status. (It&#8217;s a string and not a boolean, because I know from a later requirement that there will be more than two states). I actually will wait to write the migration, though, until a test compels it. </p>
<p>My preference is to start with the controller tests &#8212; it&#8217;s the easiest way into the system for me. </p>
<p>Here&#8217;s the batch of tests I wrote to cover the normal sending a message and not getting blocked functionality. These tests will probably look weird to just about everybody since I wrote them using a combination of <a href="http://www.thoughtbot.com/projects/shoulda/">Shoulda</a>, <a href="http://github.com/giraffesoft/zebra/tree/master">Zebra</a>, and <a href="http://github.com/jeremymcanally/matchy/tree/master">Matchy</a>. Zebra gives nice one-line tests, and Matchy gives a sort-of RSpec syntax that I sometimes like.</p>
<pre><code>context "POST CREATE" do
  setup do
    ActionMailer::Base.deliveries.clear
    @recipient = Factory.create(:user)
    @user = login!
  end

  context "with a clean user" do
    setup do
      post :create, :recipient =&gt; @recipient.id,
          :message =&gt; Factory.attributes_for(:message,
                :sender_id =&gt; @user.id)
    end

    expect { @user.messages_sent.size.should == 1 }
    expect { @user.spam_message_count.should == 1 }
    expect { assigns(:message).should_not be_new_record }
    expect { @user.should_not be_message_sending_blocked }
    expect { assert_no_email_to_administrator }

    should "create and send" do
      assert_sent_email do |email|
        email.to.first == @recipient.email &amp;&amp;
        email.from.first == "do_not_reply@singlestravelintl.com"
      end
    end

  end

### Outer context continues
</code></pre>
<p>What to say about these tests&#8230;</p>
<ul>
<li>In controller tests, I organize contexts by action. The outer context setup clears the email and creates a couple of users &#8212; the <code>login!</code> method creates a factory user and simulates a login.</li>
<li>The internal context posts the message</li>
<li>The various <code>expect</code> blocks each resolve into a test that passes if the  block returns true. The first one checks that a message has actually gone into the database (<code>messages_sent</code> is an association on user). The <code>spam_message_count</code> is what is used to determine if a user is blocked &#8212; that&#8217;s not going to pass yet, because the concept of a spam count is new to the app. The third tests that the message assigned in the controller is actually saved. The fourth checks the <code>message_sending_blocked?</code> method of a user, which is also going to need to be written. The last calls a helper method to determine if an email is sent to the administrator, which should only happen if the user is blocked.</li>
</ul>
<p>Many of these tests pass as is. The ones that don&#8217;t are dependent on the new user features. Which means we need user tests. </p>
<p>I realize that some of you are starting to think that having all these tests is ridiculous overkill &#8212; I mean, you&#8217;ve got your Cucumber tests, you&#8217;ve got your controller tests, and now model tests. That&#8217;s, like, triple the work, isn&#8217;t it? </p>
<p>No, I don&#8217;t think it is. My rationale for doing all this testing goes something like this:</p>
<ul>
<li>In my head &#8212; which is, admittedly a strange place to be &#8212; these are all different tests covering different aspects of the same feature. They could all fail independently of each other, at least in theory. Each of them is exercising a different part of the code, and crucially, each of them is  responsible for potentially testing error conditions at in their own space.</li>
<li>It&#8217;s not that much extra time &#8212; I&#8217;m presenting the code in larger chunks than I actually wrote it (can you imagine how long this would be otherwise?). In the rhythm of testing, it&#8217;s a very short piece of test, followed by a very short bit of code, and the amount of tests grows over time. </li>
</ul>
<p>Anyway, the user tests cover the case where a user has four messages, and then the transition to five messages. The setup is pretty similar (another reason why the extra tests don&#8217;t take as long to write as you might think)</p>
<pre><code>context "rate limiting" do

  setup do
    ActionMailer::Base.deliveries.clear
    Timecop.freeze(Date.today)
    @user = Factory.create(:user, :created_at =&gt; 1.month.ago)
    4.times do |i|
      Message.new_from_params(
          Factory.attributes_for(:message,
              :created_at =&gt; i.hours.ago, :body =&gt; "Message #{i + 1}"),
          @user, Factory.create(:user)).save!
    end
  end

  should "correctly count messages" do
    @user.spam_message_count.should == 4
    @user.update_message_block_status.should be_nil
    @user.should be_able_to_send_messages
    assert_number_of_emails_to_administrator(0)
  end

  should "move user to blocked mode after fifth message" do
    Message.new_from_params(Factory.attributes_for(:message,
        :created_at =&gt; 10.minutes.ago), @user,
        Factory.create(:user)).save!
    @user.update_message_block_status.should be("blocked")
    @user.should_not be_able_to_send_messages
    assert_number_of_emails_to_administrator(1)
  end

## Outer context continues
</code></pre>
<p>Most of this should be clear given all my blabbering so far (and I have no real clear reason for abandoning Zebra in this section of tests). One thing is that the method <code>update_message_block_status</code> is actually responsible for changing the user status after a message is sent.</p>
<p>This is getting way long, so <a href="http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/">back next</a> with with how this played out with new requirements, and a kind of interesting bug.</p>
<p>Quibbles with my testing style or process should go in the comments.</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/a-real-testing-example/">A Real Testing Example</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/real-testing-example-part-two/' rel='bookmark' title='Permanent Link: Real Testing Example, Part Two'>Real Testing Example, Part Two</a></li><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/07/a-real-testing-example/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Elements of Testing Style</title>
		<link>http://www.pathf.com/blogs/2009/07/elements-of-testing-style/</link>
		<comments>http://www.pathf.com/blogs/2009/07/elements-of-testing-style/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 13:28:18 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[rails testing]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3165</guid>
		<description><![CDATA[


Cover image from Amazon.com


It's been way too long since I blathered on about style issues. Today I'd like to talk about testing style. This article assumes you are already writing tests and already using something approaching a Test-Driven Development process -- I'm not here to argue about process, at least not today.
Today the topic is [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/elements-of-testing-style/">Elements of Testing Style</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/' rel='bookmark' title='Permanent Link: Ask A Rails Tester Person'>Ask A Rails Tester Person</a></li><li><a href='http://www.pathf.com/blogs/2008/10/elements-of-ruby-style/' rel='bookmark' title='Permanent Link: Elements of Ruby Style'>Elements of Ruby Style</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.amazon.com/Elements-Style-50th-Anniversary/dp/0205632645"><br />
<img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2008/10/a64d7152-eba3-4f25-af5f-d5d102b741bd.jpg" border="0" alt="A64D7152-EBA3-4F25-AF5F-D5D102B741BD.jpg" width="240" height="240" /></a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://www.amazon.com/Elements-Style-50th-Anniversary/dp/0205632645">Cover image from Amazon.com</a><br />
</span></p>
</div>
<p>It's been way too long since I blathered on about style issues. Today I'd like to talk about testing style. This article assumes you are already writing tests and already using something approaching a Test-Driven Development process -- I'm not here to argue about process, at least not today.</p>
<p>Today the topic is the actual construction of individual tests, how to name them, how to group them, where to get data from and the like.</p>
<p>I suspect I'll think of five more things right after I post this, so look for an update sometime in the future. The update will also address all the places where everybody tells me that I'm totally wrong.</p>
<div style="border: thin solid blue; padding: 5px">
	<strong>Self-promotion alert:</strong> More details about Rails testing can be found at <a href="http://www.railsrx.com">Rails Test Prescriptions</a>, there's a free getting started tutorial which contains an extensive section on Cucumber, and a <a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">nearly 300 pages and counting full book for $9</a>. Thanks. Also, follow <a href="http://www.twitter.com/railsrx">@railsrx</a> on Twitter for a testing tip every weekday.
</div>
<p><span id="more-3165"></span><br />
<h3>Name tests after their expected behavior</h3>
<p>The first part of each test is its name. By now, there's no excuse for still using the <code>def test_underscore_instead_of_spaces</code> naming convention. Rails 2.3.x, Shoulda, and RSpec all support a style where the test name can be an actual string with actual readable spaces and everything.</p>
<p>A test should be named after the expected behavior it verifies. Being specific is helpful here -- the name is potentially important documentation.</p>
<p>GOOD: <code>test "should use last_name, first_name as display"</code></p>
<p>LESS GOOD: <code>test "should correctly display names"</code></p>
<p>BAD: <code>test "name display"</code></p>
<p>If you can't think of an easy name to describe the behavior being tested, this is a strong hint that the test is either a) richly deserving of being split into multiple parts or b) unneeded. Most of the time, it's (a).</p>
<h3>Use contexts to group related tests</h3>
<p>I'm also at the point of feeling like there's no good reason not to use contexts. If you don't want the weight of using Shoulda or RSpec, then just use the <a href="http://github.com/jeremymcanally/context/tree/master">Context</a> gem to get simple contexts. </p>
<p>So, what gets grouped in a context?</p>
<ul>
<li>A set of tests that all share a common data setup</li>
<li>A set of tests that exercise a common method, as in controller tests that all work on the same action</li>
</ul>
<p>Obviously, those two options tend to go together.</p>
<p>The context name should reflect the commonality -- either the name of the method being exercised, or something denoting the common data setup, like "as an administrative user".</p>
<h3>Nesting</h3>
<p>Contexts can also be nested, allowing for setups to be extended. I don't have very strong ideas on when nesting contexts is advisable, my current guidelines look like this:</p>
<ul>
<li>Only nest a context if the inner context uses all of the outer context setup and then adds on (similar to the guideline of only creating an Object subclass if the subclass uses 100% of the parent class data)</li>
<li>Try to keep the distance between the different setup methods as small as possible -- the problem is that having to trace setup code up multiple pages and across several generations of contexts is a real pain.</li>
</ul>
<p>Actually, the problem I'd really like a clean solution for is what to do if I want the inner context setup to be run first -- for example, a controller action that I want tested for multiple user types. The controller action is logically in the parent context, but the login as the various user type, logically in the inner context, needs to happen first. Putting a large context for each user type separates the tests for each action, which I'd rather avoid. Anybody smart got this one solved yet? </p>
<h3>Setting Up Data</h3>
<p>The guideline for creating data for tests is simple: create the minimum amount of unique data that you can while still having a meaningful test. In many cases, a model unit test will only require one object, and in many of those cases only a small number of attributes are actually relevant to the test. (One of the advantages of factory tools is the ability to highlight just those relevant attributes). </p>
<p>Even search and report methods can often be unit-tested with only two models in the database -- one to be found, and one to be ignored. (You'll often need more than one test, but each individual test is small and focused on one unit).</p>
<p>Setup should be as close to the actual test as possible, granted that it often makes sense to group repeated patterns into setup methods.</p>
<h3>Single Assertion Style</h3>
<p>Shoulda has popularized a testing style where most of the test is in the setup and each individual testing method has a single assertion. I have mixed feelings about this style, though I use it sometimes.</p>
<p>Guidelines:</p>
<ul>
<li>If you are going to do single-line tests, definitely use a tool that optimizes single-line tests like <a href="http://github.com/giraffesoft/zebra/tree/master">Zebra</a> or <a href="https://github.com/noelrappin/testbed/tree">Testbed</a>.</li>
<li>I think single-assertion tests work best when setting up relatively simple model tests that don't require a lot of nested contexts.</li>
<li>Especially in controller tests, single assertion tests can lead to a lot of extra calls to the setup and a slower test suite, so that's something to keep an eye on.</li>
</ul>
<h3>When tests should be DRY and other fascinating questions?</h3>
<p>The key thing about tests is that they are also code, so pretty much every style issue that applies to regular code also applies to tests.</p>
<p>That said, tests do have a special place in your application in that they are the part of your code that doesn't actually have tests of their own. So there are some special guidelines for tests.</p>
<p>Don't get cute. There's an old programing truism that if debugging is harder than coding, then by definition any code that is as clever as you can write it is impossible to debug. Similarly, any test written at the edge of your ability is going to be impossible to verify. It's not that metaprogramming and other fancy stuff has no place in testing -- Shoula macros depend on metaprogramming, for example. It's that you probably don't want an individual test to depend on the subtleties of Ruby's object system.</p>
<p>You can repeat yourself a little. I place a higher value in tests on being able to read the whole test in one glance than I do in regular code (I expect regular code to be spread across various methods, I expect a test to be self-contained). As such, I tend to allow somewhat more code duplication in tests than I do in application code, especially in setups. That said, keeping setups short has a value as well, and when the setup is creating enough objects that it's obscuring the point of the test, I'll refactor the setup to a helper method and reuse that. But in application code, I'll generally blast duplication immediately, but in test code, I'll often wait until I have some pain. Is that a good thing? Not sure.</p>
<p>Your turn. Where am I wrong?</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/elements-of-testing-style/">Elements of Testing Style</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2009/09/ask-a-rails-tester-person/' rel='bookmark' title='Permanent Link: Ask A Rails Tester Person'>Ask A Rails Tester Person</a></li><li><a href='http://www.pathf.com/blogs/2008/10/elements-of-ruby-style/' rel='bookmark' title='Permanent Link: Elements of Ruby Style'>Elements of Ruby Style</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/07/elements-of-testing-style/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Asterisk-Java Testing with Groovy</title>
		<link>http://www.pathf.com/blogs/2009/07/asterisk-and-groovy/</link>
		<comments>http://www.pathf.com/blogs/2009/07/asterisk-and-groovy/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 14:03:28 +0000</pubDate>
		<dc:creator>Ivan Moscoso</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[telephony]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=2540</guid>
		<description><![CDATA[
Recently I have taken a bit of a detour into the world of telephony, working with Asterisk-Java, which by itself is a very valuable tool, and worth knowing a bit about if you are integrating a system with Asterisk.  While it is a Java-based library, I am integrating it into a Grails application.
We have [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/asterisk-and-groovy/">Asterisk-Java Testing with Groovy</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/12/gwt-testing-wit/' rel='bookmark' title='Permanent Link: GWT Testing With Groovy? (Heck yeah!)'>GWT Testing With Groovy? (Heck yeah!)</a></li><li><a href='http://www.pathf.com/blogs/2009/02/grails-delegating-to-gorm-persistence-in-java/' rel='bookmark' title='Permanent Link: Grails: Delegating to GORM Persistence in Java'>Grails: Delegating to GORM Persistence in Java</a></li><li><a href='http://www.pathf.com/blogs/2009/02/groovy-16-and-per-instance-metaclass/' rel='bookmark' title='Permanent Link: Groovy 1.6 and Per-Instance Metaclass'>Groovy 1.6 and Per-Instance Metaclass</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/07/asterisk1.png" alt="iPhone in Dock" width="140" height="163" /></p>
<p>Recently I have taken a bit of a detour into the world of telephony, working with <a href="http://asterisk-java.org/">Asterisk-Java</a>, which by itself is a very valuable tool, and worth knowing a bit about if you are integrating a system with Asterisk.  While it is a Java-based library, I am integrating it into a Grails application.</p>
<p>We have a fairly comprehensive suite of unit tests asserting that desired behaviors are triggered upon certain events initiated through the Event API.  This is made even easier, as usual, with Groovy-- specifically on the testing front.  Here I show two hypothetical test cases, followed by supporting code that works specifically with the Asterisk-Java classes...</p>
<p><span id="more-2540"></span></p>
<pre class="groovy">&nbsp;
<span style="color: #a1a100;">import org.gmock.GMockTestCase</span>
<span style="color: #a1a100;">import org.asteriskjava.manager.event.JoinEvent</span>
<span style="color: #a1a100;">import org.asteriskjava.manager.event.LeaveEvent</span>
&nbsp;
<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> queueObject = <span style="color: #808080; font-style: italic;">// .... some object representing an internal queue</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/*
 * Verifies caller entering a call queue will trigger behavior
 */</span>
<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20void"><span style="color: #993333;">void</span></a> testCallIAddedToQueue<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  mock<span style="color: #66cc66;">&#40;</span>queueObject<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'SIP/123'</span>, <span style="color: #ff0000;">'3125551234'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">once</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  dispatchJoinEvent<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>channel: <span style="color: #ff0000;">&quot;SIP/123&quot;</span>, callerId: <span style="color: #ff0000;">&quot;3125551234&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/*
 * Verifies caller leaving call queue will trigger behavior
 */</span>
<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20void"><span style="color: #993333;">void</span></a> testCallRemovedFromQueue<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    mock<span style="color: #66cc66;">&#40;</span>queueObject<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;SIP/123&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">once</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    dispatchLeaveEvent<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>channel: <span style="color: #ff0000;">&quot;SIP/123&quot;</span>, dateReceived: <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new"><span style="color: #000000; font-weight: bold;">new</span></a> <a href="http://www.google.de/search?as_q=Date&num=100&hl=en&as_occt=url&as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F"><span style="color: #aaaadd; font-weight: bold;">Date</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>
<span style="color: #808080; font-style: italic;">// ...</span>
&nbsp;</pre>
<p>The testcases above are fairly straightforward, hiding much of the details involved when working with Asterisk-Java.  The 'queueObject' can be anything, really, as long as it contains behavior which we wired into the event-handling system Asterisk-Java provides.  The important part here is how we can easily bind properties to the underlying Event types, and dispatch them so that our behavior is invoked.</p>
<pre class="groovy">&nbsp;
<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20private"><span style="color: #000000; font-weight: bold;">private</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> dispatchJoinEvent<span style="color: #66cc66;">&#40;</span>properties<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  dispatchEvent<span style="color: #66cc66;">&#40;</span>JoinEvent, properties<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20private"><span style="color: #000000; font-weight: bold;">private</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> dispatchLeaveEvent<span style="color: #66cc66;">&#40;</span>properties<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  dispatchEvent<span style="color: #66cc66;">&#40;</span>LeaveEvent, properties<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20private"><span style="color: #000000; font-weight: bold;">private</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> dispatchEvent<span style="color: #66cc66;">&#40;</span>eventType, eventProperties<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> event = eventType.<span style="color: #006600;">newInstance</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>:<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
  eventProperties.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20each"><span style="color: #663399;">each</span></a> <span style="color: #66cc66;">&#123;</span> name, value -&gt; event.<span style="color: #ff0000;">&quot;${name}&quot;</span> = value <span style="color: #66cc66;">&#125;</span>
  play <span style="color: #66cc66;">&#123;</span>
    asteriskService.<span style="color: #006600;">connection</span>.<span style="color: #006600;">dispatchEvent</span><span style="color: #66cc66;">&#40;</span>event<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>Here I have a 'service' class defined in Grails which I call 'asteriskService'.  It encapsulates access to the Asterisk-Java <a href="http://asterisk-java.org/latest/apidocs/org/asteriskjava/manager/ManagerConnection.html">ManagerConnection</a> instance, which in turn can dispatch specific events.</p>
<p>Of interest to those new with Groovy is the binding of properties within 'dispatchEvent()'.  It looks perhaps a bit more complex than one would hope, but unfortunately JoinEvent and LeaveEvent do not have default constructors, requiring the code to 'new' them up with a placeholder argument, and then set any properties on the fly.</p>
<p>Asterisk-Java is worth checking out, but particularly nice is using a bit of Groovy to tie it in nicely.  While this can benefit the application, you can see how it helps ease testing-- particularly as you start using more and more of what the library offers.</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/07/asterisk-and-groovy/">Asterisk-Java Testing with Groovy</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/12/gwt-testing-wit/' rel='bookmark' title='Permanent Link: GWT Testing With Groovy? (Heck yeah!)'>GWT Testing With Groovy? (Heck yeah!)</a></li><li><a href='http://www.pathf.com/blogs/2009/02/grails-delegating-to-gorm-persistence-in-java/' rel='bookmark' title='Permanent Link: Grails: Delegating to GORM Persistence in Java'>Grails: Delegating to GORM Persistence in Java</a></li><li><a href='http://www.pathf.com/blogs/2009/02/groovy-16-and-per-instance-metaclass/' rel='bookmark' title='Permanent Link: Groovy 1.6 and Per-Instance Metaclass'>Groovy 1.6 and Per-Instance Metaclass</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/07/asterisk-and-groovy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Return of the Cucumber</title>
		<link>http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/</link>
		<comments>http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 19:37:55 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=2684</guid>
		<description><![CDATA[





Same Photo by Nick Atkins Photography


I mentioned last week that the RubyMine post was replacing what I had meant to write about. Well, this week we finally get to it...
It's been about ten weeks since I wrote about Cucumber the first time and the second time. Since then, I've continued to use Cucumber and now [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/">The Return of the Cucumber</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li><li><a href='http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/' rel='bookmark' title='Permanent Link: Again With The Cucumbers'>Again With The Cucumbers</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right">
<a href="http://www.flickr.com/photos/nickatkins/527421404/"><br />
<img src="http://www.pathf.com/blogs/wp-content/uploads/2009/03/527abb18-6013-43cd-9cda-c5aaca7b20c1.jpg" alt="" border="0" alt="A Cucumber" width="240" height="232" /><br />
</a><br />
<br clear="all"/><br />
<span class="right" style="font-size: smaller"><br />
<a href="http://www.flickr.com/photos/nickatkins/527421404/">Same Photo by Nick Atkins Photography</a><br />
</span>
</div>
<p>I mentioned last week that the RubyMine post was replacing what I had meant to write about. Well, this week we finally get to it...</p>
<p>It's been about ten weeks since I wrote about Cucumber <a href="http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/">the first time</a> and <a href="http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/">the second time</a>. Since then, I've continued to use Cucumber and now seemed like a good time to update some thoughts on how and why it seems to be working for us.</p>
<p>The big headline, of course, is that I'm still using it after ten weeks. I'm pretty quick to abandon tools that aren't pulling their weight, so just the fact that Cucumber is still in the toolbox means that despite the time that it takes to write Cucumber tests and step definitions, I'm finding the process of writing the tests and the tests themselves to be valuable.</p>
<div style="border: thin solid blue; padding: 5px">
	<strong>Self-promotion alert:</strong> More details about Cucumber and anything relating to Rails testing can be found at <a href="http://www.railsrx.com">Rails Test Prescriptions</a>, there's a free getting started tutorial which contains an extensive section on Cucumber, and a <a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">nearly 300 pages and counting full book for $9</a>. Thanks. Also, follow <a href="http://www.twitter.com/railsrx">@railsrx</a> on Twitter for a testing tip every weekday.
</div>
<p><span id="more-2684"></span><br />
<h3>Where I'm using it</h3>
<p>Right now, I've been using Cucumber primarily on two different projects.</p>
<ul>
<li>An internal project that has a well-defined testing process, and 100% coverage for unit tests on models and for functional tests on controllers.</li>
<li>A client project that we took over from the original coders, who wrote no tests at all. All new features come in with tests, but we haven't </li>
</ul>
<p>Cucumber plays out a little differently in each case.</p>
<h3>How I'm Using it</h3>
<p>I struggled a bit with how to integrate Cucumber into the testing process, and eventually came to the following rule of thumb:</p>
<p>Just as all lines of code should be in response to a failing unit or functional test, all new unit or functional tests should be in response to a failing line of Cucumber.</p>
<p>The process seems to go something like this:</p>
<ol>
<li>
		In conjunction with a stakeholder of some kind, write the cucumber tests for the feature, usually this will be multiple scenarios. At this stage, don't worry about setting up data, and I think you're better off focusing on making the test as human-readible as possible, but see below for some thoughts in that direction.
	</li>
<p><br/></p>
<li>
		Start writing step definitions for the Cucumber tests, step by step. In many cases, you'll find yourself adding some steps to create data (especially to the background step of the feature). Especially on a mature project, you'll often be able to write several steps without needing new code in the app itself -- "Given I am a logged in user", "When I visit the project page"... in essence, the setup.
	</li>
<p><br/></p>
<li>
		In the fullness of time, you'll come to the meat of the feature, and you won't be able to make the Cucumber line pass without writing application code. At this point, you drop into a normal TDD process, with the goal of moving the application forward enough to make this line of Cucumber succeed.
	</li>
<p><br/></p>
<li>
		What happens here depends a little bit on personal taste and the project team. For the internal project, which has a goal of 100% functional test coverage, I do write functional tests even if they overlap the Cucumber test strongly. On the legacy project, I do sometimes drop do the model/unit tests from the Cucumber test if there doesn't seem to be a substantial difference between the acceptance and functional test.
	</li>
<p><br/></p>
<li>
		When I think the regular TDD process has gotten me enough code to pass the Cucumber line, then I run Cucumber again to verify, and move on to the next line.
	</li>
<p><br/>
</ol>
<p>This process has a lot going for it. The TDD part is always focused on a specific, definable goal -- the next line of Cucumber test. The cycles between acceptance and regular testing are short enough that the two feed into each other (sometimes the Cucumber tests change in response to the shape of the code, and sometimes vice versa), and they work together to keep the code simple, complete, and covered.</p>
<h3>Cucumber vs. Functional testing</h3>
<p>The big question is to what extent the Cucumber tests duplicate or replace functional tests. At the moment, my answer is somewhat, but not completely. I see the Cucumber tests as being the way to go for testing a work flow of more than one one action, but I still find it a little easier to set up data in the functional test framework. That said, I don't think that adding the functional tests has cost me that much more time, and there are still enough gaps in Cucumber/Webrat (most notably Ajax) that I'm reluctant to give up controller tests entirely. I expect my thinking on this will change as we have projects that had Cucumber from the very beginning.</p>
<h3>General vs. Specific</h3>
<p>I'm having a stylistic issue with the Cucumber tests between putting the specifics in the Cucumber or in the step definition. This came up most sharply in the legacy project. We were working on a feature that made a distinction between new users and old users. My first pass at the Cucumber test started off like this:</p>
<pre style="white-space: pre !important;">
Given a user named "Noel Rappin" who has been a member for 5 months
</pre>
<p>With a step definition that was something like this:</p>
<pre style="white-space: pre !important;">
Given /^A user named "(.*)" who has been a member for (.*) months$/ do |name, mo|
  @user = Factory.create(:user, :name => name,
      :created_at => mo.months.ago)
end
</pre>
<p>The idea was that "5 months" was just a stand in for "an old user", but the client, quite understandably, wanted to know what the deal was with five months -- the specificity of the rule seemed to imply that it was important functionally. Eventually, I changed the rule to be more like this:</p>
<pre style="white-space: pre !important;">
Given /^A user who is not a new member$/ do
  @user = Factory.create(:user, :created_at => 5.months.ago)
end
</pre>
<p>Once I saw this issue, I started seeing it everywhere. The second form has the advantage of being more general and more requirements like, and the disadvantage of hiding a lot of magic detail in the step definition. The original version has the advantage of putting specific data front and center and the disadvantage of not making it clear which details are important.</p>
<p>I'm not aware that there's a consensus on the style issue. My tendency, right now, is to favor the general form on the theory that it's a good thing to make the Cucumber test as readable as possible and let the step definitions sort it out. On the other hand, this seems like a good way to get really messed up by having the step definition not quite match what you expect, and have that be hidden.</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a>, <a href="http://www.pathf.com/services/how-we-do-it/">Agile Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/">The Return of the Cucumber</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li><li><a href='http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/' rel='bookmark' title='Permanent Link: Again With The Cucumbers'>Again With The Cucumbers</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</title>
		<link>http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/</link>
		<comments>http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 15:13:02 +0000</pubDate>
		<dc:creator>Jason Sendelbach</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Unit Tests]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=2665</guid>
		<description><![CDATA[I admit that cucumber is awesome.  It apparently was the big thing at Rails Conf this year.  I love that my BA can write the requirements, I can throw them into a feature file, and get feedback on my progress of the feature being done.  
Cucumber is also an excellent choice for [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/">Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li><li><a href='http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/' rel='bookmark' title='Permanent Link: Again With The Cucumbers'>Again With The Cucumbers</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I admit that cucumber is awesome.  It apparently was the big thing at Rails Conf this year.  I love that my BA can write the requirements, I can throw them into a feature file, and get feedback on my progress of the feature being done.  </p>
<p>Cucumber is also an excellent choice for getting coverage on a legacy code base.  Many of our clients have existing applications that were developed by cheap firms.  They finally realize that they should have gone with a development company that writes automated tests, and works in a true agile manner.  When initially looking at the code, we often get chills.  There are usually zero tests.  Most of the code sits in huge controller methods.  We generally will use cucumber to start to get coverage for the features that the client wants changes to.  We do write unit and functional tests, but we generally only assert the things we are changing.  Over time, the unit and functional test coverage increases, and when we make changes we generally will refactor lots of the existing code base.</p>
<p>With that said, I have seen the use of cucumber on some of our projects change the way some developers code.  They go from true TDD to crappy non-TDD.  Many methods on the model don't have unit tests! How can we call this TDD?  </p>
<p>I do admit that the functional tests can be a lot lighter, as you are getting coverage from the cucumber suite of tests.  However, It doesn't mean that you can skip writing unit and functional tests.</p>
<p>This is how I incorporate cucumber into my development, while still maintaining 100% code coverage.<br />
1. Write cucumber tests from the acceptance tests from the requirement<br />
2. See all of the tests fail<br />
3. Write unit tests, see them fail, write the code until the unit tests pass.<br />
4. Write functional tests, see them fail, write code until the functional tests pass<br />
5. Continue until I think the feature is fully implemented<br />
6. Run the cucumber tests and see if anything still fails. - Add unit/functional tests to address failing cucumber tests.  Once all tests pass, run the test coverage to ensure there are no holes (this generally doesn't happen, as I am practicing TDD).</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services/how-we-do-it/">Agile Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/">Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li><li><a href='http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/' rel='bookmark' title='Permanent Link: Again With The Cucumbers'>Again With The Cucumbers</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Again With The Cucumbers</title>
		<link>http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/</link>
		<comments>http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 13:22:55 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1769</guid>
		<description><![CDATA[



Same Photo by Nick Atkins Photography

My cucumber obsession continues unabated. I've spent a lot of the last week adding Cucumber to projects, writing about it in a very long section for the Rails Test Prescriptions book, and generally trying to figure out how to use this tool, not to mention trying to figure out why [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/">Again With The Cucumbers</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.flickr.com/photos/nickatkins/527421404/"><br />
<img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/03/527abb18-6013-43cd-9cda-c5aaca7b20c1.jpg" border="0" alt="A Cucumber" width="240" height="232" /><br />
</a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://www.flickr.com/photos/nickatkins/527421404/">Same Photo by Nick Atkins Photography</a><br />
</span></div>
<p>My cucumber obsession continues unabated. I've spent a lot of the last week adding Cucumber to projects, writing about it in a very long section for <a href="http://www.lulu.com/content/e-book/rails-test-prescriptions/6418439">the Rails Test Prescriptions book</a>, and generally trying to figure out how to use this tool, not to mention trying to figure out why this tool has been so interesting to me this week.</p>
<p>Some follow-up thoughts since <a href="http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/">last week's post</a>.<br />
<span id="more-1769"></span></p>
<ul>
<li>I'm really excited about the idea of using Cucumber as a way to bootstrap testing on a legacy project that has no tests. The normal problem is that you need to refactor in order to write good tests, but since you don't have good tests, you have no way to prove that your refactor didn't break anything. Cucumber's advantage here is that it can treat the Rails application as a black box, so you can throw in some Cucumber tests without touching the original code. This will give you some trip wires that will let you know if something gets really broken in your refactor. Plus, it's a good way to learn your way around an unfamiliar project.</li>
<li>For what it's worth, I seem to be getting a fair amount of reuse out of step definitions within the same feature. That is, after I've set up most of the baseline scenarios, if I think of a new oddball one, most of the steps that make it up are already defined.</li>
<li>After pointing out last week that my first real Cucumber example actually passed in Cucumber after failing in the browser, I need to mention that this week I had a big Cucumber success, where my unit tests passed, but the browser and Cucumber didn't behave correctly. In this case, the unit test was performing operations in a different order then the browser code, and created a false pass.</li>
<li>I'm not completely sure why, or even whether I'll feel this way in a few days, but Cucumber view tests feel much more readable than pure Test::Unit view tests, even with the indirection of the step definition. Even if Cucumber was just a DSL for creating readable view tests, I still think it'd be useful.</li>
<li>I don't think there's a definitive sense of what great Cucumber style is, but, at the moment, I'm skeptical of the advantages of bundling Cucumber steps into the step definitions. I appreciate the advantages of reducing duplication, but I think that Cucumber is most valuable if the actual feature page is as open and accessible as possible. I'd rather have more steps in Cucumber with short definitions than fewer steps and more complex definitions.</li>
</ul>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/">Again With The Cucumbers</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li><li><a href='http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/' rel='bookmark' title='Permanent Link: Using Cucumber for Acceptance Testing'>Using Cucumber for Acceptance Testing</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Cucumber for Acceptance Testing</title>
		<link>http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/</link>
		<comments>http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 18:18:35 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Custom Application Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1656</guid>
		<description><![CDATA[



Photo by Nick Atkins Photography

An consistent nuisance problem when testing Rails applications is the "unit test gap". This happens when the model test passes and the controller test passes, but the application as a whole fails because there's a mismatch between the output produced by the model and the input given to the controller test. [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/">Using Cucumber for Acceptance Testing</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/' rel='bookmark' title='Permanent Link: Again With The Cucumbers'>Again With The Cucumbers</a></li><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.flickr.com/photos/nickatkins/527421404/"><br />
<img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/03/527abb18-6013-43cd-9cda-c5aaca7b20c1.jpg" border="0" alt="A Cucumber" width="240" height="232" /><br />
</a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://www.flickr.com/photos/nickatkins/527421404/">Photo by Nick Atkins Photography</a><br />
</span></div>
<p>An consistent nuisance problem when testing Rails applications is the "unit test gap". This happens when the model test passes and the controller test passes, but the application as a whole fails because there's a mismatch between the output produced by the model and the input given to the controller test. In theory, Rails integration tests can solve this problem, but they aren't really designed for it, and nobody uses them much anyway.</p>
<p>An easy-to-use tool that solves that end-to-end testing would be great. Somebody should really write a blog post about that.</p>
<p>So, as I was saying. We continually run into an issue with our clients over defining requirements at the level that developers need to keep going, without getting bogged down in long stretches of design. There's a big gap between "users should be able to upload photos to their pages" and all the different details of permissions, validation and the like than need to be answered at some point. The Agile process suggests that those requirements be created as closely as possible to the code, which leads to the question of how best to keep the customer in the loop while the developers need these decisions to be made.</p>
<p>An easy-to-use tool that lets users read or create requirements that developers can build from and run as acceptance tests would be great. Somebody should definitely write a blog post about that.</p>
<p>Which brings us -- finally -- to <a href="http://cukes.info">Cucumber</a>, a tool for creating automated acceptance tests. It's flexible enough to solve both problems. It can be used as a developer tool to drive regular TDD testing, and as a client tool for managing requirements.</p>
<div style="border: thin solid; padding: 5px"><strong>Self promotion:</strong> If you want to read more about Cucumber and all kinds of Ruby testing, <a href="http://www.lulu.com/content/e-book/rails-test-prescriptions/6418439">buy the beta version of Rails Test Prescriptions</a>. Cucumber isn't in the book yet, but will be in the next release, schedule for the end of March. Buy now, and get all future updates free of charge.</div>
<p><span id="more-1656"></span>It's got loads of potential. And some pitfalls and tricks. The <a href="http://cukes.info">Cucumber</a> web site has great documentation on installing and using. I want to focus on how Cucumber can work within a development process.</p>
<p>Here's a Cucumber test:</p>
<pre style="white-space: pre !important;">  Background:
    Given I am logged in
    Given I am in a project

  Scenario: Make High Priority
    Given I have a task with medium priority
    And I am on a page that displays tasks
    When I click on "priority_up" for that task
    Then the task should display high priority</pre>
<p>The structure of a Cucumber test is pretty simple. You've got your "Given" lines, which specify prerequisites, then you've got your "When" lines which are user actions, finally the "Then" lines list results. The Background items are loaded before each scenario in the feature, and therefore consist primarily of "Given" lines.</p>
<p>This test is actually runnable as is, although Cucumber will just tell you that it doesn't know what any of the lines actually mean yet. The Cucumber test runner output, by the way, is outstanding. Color coded results of each step, tied to the line where each step is defined, a nice summary, and snippets of code to insert for undefined steps. The output goes a long way toward making Cucumber easy to use.</p>
<p>In order to make this test actually work, you have to define it. Cucumber gives you a handy file to place the definitions in. Cucumber task definitions are Ruby code. Here is the definition for the first step in the scenario above:</p>
<pre style="white-space: pre !important;">Given /^I have a task with (.*) priority$/ do |priority|
  @task = Task.make(:priority =&gt; priority, :project =&gt; @project,
      :feature =&gt; @feature)
end</pre>
<p>Let's break this down a little bit. The starting point of a Cucumber step definition is a definition line containing a regular expression and taking a block. Any group specified in the regular expression is passed as an argument to the block (and matching text is very helpfully presented in bold from the command line output).</p>
<p>In this particular case, the text "I have a task with high priority" matches this step definition, and passes "high" to the block, where it's used to create the new task (using <a href="http://github.com/notahat/machinist/tree/master">the Machinist fixture replacement plugin</a> -- Cucumber plays very nicely with all the fixture replacements).</p>
<p>Here are the definitions for the other three steps.</p>
<pre style="white-space: pre !important;">Given /^I am on a page that displays tasks$/ do
  visit("/tasks")
end</pre>
<p>This one is pretty straightforward, and uses <a href="http://github.com/brynary/webrat/tree/master">Webrat</a> to simulate a browser hit to that specific URL.</p>
<pre style="white-space: pre !important;">When /^I click on "(.*)" for that task$/ do |button|
  #click_link(dom_id(@task, button))
  if button == "priority_up"
    visit("/tasks/#{@task.id}/upgrade")
  elsif button == "priority_down"
    visit("/tasks/#{@task.id}/downgrade")
  end
end</pre>
<p>The commented line here is what I would do if it was a normal link -- again using Webrat to simulate the link. However, Webrat doesn't follow rails <code>link_to_remote</code> links (at least not yet), which is what I actually have in this project. So I'm faking it with a truly ugly hack. I'm assuming there's a better way to do this.</p>
<p>Finally, we get to the actual assertion.</p>
<pre style="white-space: pre !important;">Then /^the task should display (.*) priority$/ do |priority|
  response.body.should =~ /priority_task_#{@task.id}/
  response.body.should =~ /#{priority}/
end</pre>
<p>Since the response here is an Ajax response, all I can do is a match on the output. If it was ordinary HTML, I could use the full weight of <code>assert_select</code> and the like.</p>
<p>With these definitions in place, the tests will run and fail. You can then spin off into your regular TDD process to make everything work. In practice, I actually do this one step at a time. Write the step definition, then make it work, then on to the next step. Over time, this takes the place of some controller and (especially) view testing. Also, you should fine some ability to reuse step definitions.</p>
<p>I have several points to make about this.</p>
<ul>
<li>It seems like the Cucumber steps should be written from the user perspective in plain language as much as possible. So "I should see a high priority icon" rather than, "the page should contain high_priority.jpg". Along that line, thought the Given statements probably do need to touch the database, the When and Then statements should work entirely at the user action and HTML response level. Complete end-to-end testing is, to me, the place where Cucumber has the most to offer.</li>
<li>It's also clear that the amount of efficiency Cucumber adds or subtracts from your development process is largely dependent on how well you write the step definitions. The Given and When lines need to be as simple as possible, and everything relies on the Then lines giving an accurate representation of what the application is doing.</li>
<li>Cucumber tests have the same problems as view tests in general -- if they are detailed enough to be fully exact, then they are probably too brittle, but a more robust test (based on DOM ID, for example), could easily be fooled by a sloppily written view layer.</li>
<li>The exercise of creating the Cucumber tests is, all by itself, quite useful in specifying exactly what the application is going to do. Unlike a lot of other requirements definition languages, Cucumber is really low-ceremony and easy to generate. So far, I've mostly used Cucumber in projects where the developer, not a client is generating the tests. Even then, the process of thinking these scenarios through was very helpful in driving development. Having the tests be runnable was a bonus.</li>
<li>That said, it's not hard for the tests to basically lie to you. The batch of tests referenced here is from a feature I actually built using Cucumber. First time I tried it in a browser, with all the Cucumber tests passing, the browser failed. For an interesting reason. The priority column was a new addition, and the code assumed that the tasks would have one of three values. Existing tasks however had a nil value, which broke the code. A rake task to preset the existing tasks fixed the problem, though. So -- this is not a substitute for actual human testing.</li>
<li>Which leads to another question about Cucumber -- where to draw the line between Cucumber and existing tests. It seems to be that Cucumber is not the place to test all your error conditions (although if an error condition has a user-visible component than a generic error test is probably appropriate). I'm not sure I've completely found the groove as to when a test goes in Cucumber and when it goes into a controller or view test -- model tests still do seem to be completely separate, I had no trouble writing model tests off of my Cucumber scenarios. (I know that some people are using Cucumber to replace controller tests -- I'm not convinced yet that's the way to go.</li>
<li>I'd be very interested to see how this played out on a larger project. Would the number of feature files become unwieldy? Would multiple developers be continually re-inventing the step definition wheel? Would that matter?</li>
</ul>
<p>One thing that kept me from trying out Cucumber in the past was a variant on the same thinking that keeps people from testing in general - the fear that you're just going to be writing more code, and taking more time, to little or no benefit.</p>
<p>My experience so far, as I explore what Cucumber can do, has been largely positive. Where I was starting with Cucumber and only a vague idea of how the user interaction would play out, writing the scenarios at the Cucumber level felt very valuable and gave the development a clear path that I wouldn't have otherwise had. That said, there is extra code being written, and it's clearly possible to get really tangled in getting the step definitions right.</p>
<p>As developers, we're kind of conditioned to believe that if we're solving a complicated problem, we're doing something valuable. At it's worst, writing the step definitions felt like a complicated problem that wasn't adding much. Luckily, a lot of that was due to my own unfamiliarity with Cucumber. As I got better at it, most of the step definition part came quickly. Ultimately, I think I wrote better code as a result of starting with the Cucumber definitions -- it definitely kept me from writing unneeded code, since most everything flowed from a Cucumber step.</p>
<p>I definitely recommend giving Cucumber a try -- the potential for really cleaning up what is often the messy process of determining what a feature should do is very high. I'm really looking forward to reading (and writing) more details of what successful strategies with Cucumber look like.</p>
<p>Related Services:  <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a></p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/">Using Cucumber for Acceptance Testing</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/06/the-return-of-the-cucumber/' rel='bookmark' title='Permanent Link: The Return of the Cucumber'>The Return of the Cucumber</a></li><li><a href='http://www.pathf.com/blogs/2009/03/again-with-the-cucumbers/' rel='bookmark' title='Permanent Link: Again With The Cucumbers'>Again With The Cucumbers</a></li><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/03/using-cucumber-for-acceptance-testing/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Rails Test Prescriptions is now on sale</title>
		<link>http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/</link>
		<comments>http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 14:50:02 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Pathfinder News]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[Technologies and Platforms]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1558</guid>
		<description><![CDATA[



This is the cover

Rails Test Prescriptions: Keeping your Application healthy is now on sale. This is a beta, partial release.
Rails Test Prescriptions is a comprehensive guide to testing your Rails application, covering both the mechanics of writing tests and the style for writing good and useful tests.
I'm excited to be publishing this electronically in a [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/">Rails Test Prescriptions is now on sale</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/more-kudos-for-rails-prescriptions/' rel='bookmark' title='Permanent Link: More Kudos for Rails Prescriptions'>More Kudos for Rails Prescriptions</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions to be Published by Pragmatic'>Rails Test Prescriptions to be Published by Pragmatic</a></li><li><a href='http://www.pathf.com/blogs/2008/12/announcing-rails-prescriptions/' rel='bookmark' title='Permanent Link: Announcing Rails Prescriptions'>Announcing Rails Prescriptions</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439"><br />
<img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/03/front-cover.jpg" border="0" alt="front_cover.png" width="329" height="255" /><br />
</a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">This is the cover</a><br />
</span></div>
<p><em>Rails Test Prescriptions: Keeping your Application healthy</em> is <a href="http://www.lulu.com/content/e-book/rails_test_prescriptions/6418439">now on sale</a>. This is a beta, partial release.</p>
<p><em>Rails Test Prescriptions</em> is a comprehensive guide to testing your Rails application, covering both the mechanics of writing tests and the style for writing good and useful tests.</p>
<p>I'm excited to be publishing this electronically in a way that allows me to keep the book up to date as Rails changes over the upcoming months and years. Your $9 purchase entitles you to all updated versions for the life of the book.<br />
<span id="more-1558"></span>The current table of contents looks like this:</p>
<p>A basics section:</p>
<ul>
<li>Basics—creating test files, running tests</li>
<li>Model tests</li>
<li>Controller tests</li>
<li>Integration tests</li>
<li>View tests</li>
<li>Fixtures</li>
<li>Helper tests</li>
<li>Mocks and stubs</li>
</ul>
<p>The more detailed section currently has:</p>
<ul>
<li>Refactoring setups</li>
<li>Testing style guide (incomplete)</li>
<li>Fixture replacements</li>
<li>Testing with Date/Time</li>
<li>Faker</li>
</ul>
<p>Planned for the future:</p>
<ul>
<li>Third-party view testing</li>
<li>Security testing</li>
<li>route testing</li>
<li>Ajax testing</li>
<li>Mailer testing</li>
<li>File Upload Testing</li>
<li>Refactoring assertions</li>
<li>Shoulda</li>
<li>RSpec</li>
<li>Cucumber</li>
<li>Webrat</li>
<li>Dealing with legacy projects</li>
<li>Autotest</li>
<li>Tarantula</li>
<li>Heckle</li>
<li>RCov</li>
</ul>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/">Rails Test Prescriptions is now on sale</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/more-kudos-for-rails-prescriptions/' rel='bookmark' title='Permanent Link: More Kudos for Rails Prescriptions'>More Kudos for Rails Prescriptions</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions to be Published by Pragmatic'>Rails Test Prescriptions to be Published by Pragmatic</a></li><li><a href='http://www.pathf.com/blogs/2008/12/announcing-rails-prescriptions/' rel='bookmark' title='Permanent Link: Announcing Rails Prescriptions'>Announcing Rails Prescriptions</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agile Development for Product Managers: Why Agile Testing Rocks</title>
		<link>http://www.pathf.com/blogs/2009/03/agile-development-for-product-managers-why-agile-testing-rocks/</link>
		<comments>http://www.pathf.com/blogs/2009/03/agile-development-for-product-managers-why-agile-testing-rocks/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 03:24:46 +0000</pubDate>
		<dc:creator>Dietrich Kappe</dc:creator>
				<category><![CDATA[Custom Application Development]]></category>
		<category><![CDATA[Rich Internet Apps]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[Technologies and Platforms]]></category>
		<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Unit Tests]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1499</guid>
		<description><![CDATA[All software has bugs. I don't care if you're Apple, Microsoft, IBM, or a smaller, leaner ISV. Your software has bugs in it. Once you accept this fact, that into each software product a little crap must fall, it becomes clear that what differentiates one software development organization from another is how they manage those [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/agile-development-for-product-managers-why-agile-testing-rocks/">Agile Development for Product Managers: Why Agile Testing Rocks</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/05/agile-development-and-testing-unit-or-montecarlo/' rel='bookmark' title='Permanent Link: Agile Development and Testing: Unit or Montecarlo?'>Agile Development and Testing: Unit or Montecarlo?</a></li><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li><li><a href='http://www.pathf.com/blogs/2008/05/800-on-your-mat/' rel='bookmark' title='Permanent Link: 800 on Your Math SAT, Software Development and Bugs'>800 on Your Math SAT, Software Development and Bugs</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-1858" title="testingtag" src="http://www.pathf.com/blogs/wp-content/uploads/2009/03/testingtag.png" alt="testingtag" width="171" height="260" style="float:right;padding:10px" />All software has bugs. I don't care if you're Apple, Microsoft, IBM, or a smaller, leaner ISV. Your software has bugs in it. Once you accept this fact, that into each software product a little crap must fall, it becomes clear that what differentiates one software development organization from another is how they manage those bugs. What do you do to prevent them in the first place, find them, fix them, measure them, celebrate their squashing?</p>
<p>Most of the developers at Pathfinder Development are old hands. We've been around the block a few times. We've worked on quite a number of software projects over the years. We've all gravitated toward agile development not because it's the latest buzzword, or because it feels so good (though it does when it's done right), but because everything else feels so bad.</p>
<p>Take testing, for example. Testing girds you, the product manager, for the moment of truth -- deploying or shipping a new release. In the monolithic or waterfal processes, we would often wait until the end, after all of the development was done to "QA" the application. Often you'd throw in some performance testing to see if this monstrosity you'd just built would actually handle the load you were going to throw at it.</p>
<p>After weeks or months of testing, fixing, hoping, praying and integrating, you'd finally deploy. Odds are you'd ship with some pretty serious bugs. But the quality of the software, in terms of bugs and errors, was pretty poor and the expense and effort of the developers fixing the bugs was akin to the contractor applying spackle to a drywall that was more hole than whole.</p>
<p>Let me go through some of the testing we do today, what the previous alternative was, and what the benefit for your product is.</p>
<p><span id="more-1499"></span></p>
<p><strong>Continuous Integration Rocks</strong></p>
<p>Every time you check in some code, the entire system builds, is tested and deployed to a development environment, then tested some more. This is the heartbeat, the core of the Agile feedback loop. The alternative was building part of the application on you local environment, occasionally checking out code from other developers, and doing a painful build and integration at the time of deployment that could take weeks or months to work out the kinks. You would not discover basic compile time problems for days or even weeks.</p>
<p>For the product manager the equation is simple: bugs are more expensive to fix the farther they get from the time of original development. Automate your tests and you find things out right away.</p>
<p><strong>TDD and Unit Testing Rocks</strong></p>
<p>We work in OO languages for the most part, so Unit tests are a natural fit for the classes we develop. We practice test driven development -- writing the tests first -- since we know that writing tests afterwards is like making tea with a used tea bag. We strive for 100% line and branch coverage. Every time we identify a bug, we write a test for it.</p>
<p>Agile testing is cumulative, each iteration produces automated tests that protect your code from unintended side effects in the next iteration. Since most software has more development effort expended on it after it has been released than before, the cumulative tests act as an early warning system against those side-effects. I think of all those times that a change broke a test and therefore broke the build during an iteration. In the old way of doing things that was a bug that no one would have noticed and that likely would nevery have been detected or fixed.</p>
<p>For the product manager, automated, cummulative tests mean you can quickly and confidently modify your product to meet changing market demands without having to worry about and brittle and buggy code base.</p>
<p><strong>Releasing Working Code Every 2 Weeks Rocks</strong></p>
<p>In the old days we would wait until close to the end of the project or phase before bringing all of the code together in a working, useful system. That pretty much made testing something you could only do at the end. Now we release a system every 2 weeks that is useful in the business sense and can be tested and critiqued. Can this be done? Well, if you are designing an air traffic control system and you need all of the features at once -- you want both the take off safely and land safely user stories at the same time -- then Agile may not be for you. But for the other 99.9% of software applications, releasing every 2 weeks is very much doable.</p>
<p>For the product manager this means you can test and measure whether you application performs up to spec from the beginning and as the application grows and evolves. You can do usability testing throughout. You can do security testing throughout. Knowing whether you application <em>so far </em>meets the spec allows you to predict when you will be done with development to a much greater precision as you approach the end of development.</p>
<p><strong>Releasing Working Code Every 2 Weeks Rocks Again</strong></p>
<p>Traceability. How I love that word. In the old days, keeping track of whether you tested something was a major headache. On a project with 12 developers and several months of development you sometimes lost track whether something had been tested, even with spreadsheets and project plans. Today we automate and never bite of more than we can chew in 2 weeks. That means the tester and the developer work or even pair together to ensure that our little collection of features has all been tested.</p>
<p>For the product manager this means less headache verifying for compliance or auditing that everything that the team said it had tested has in fact been tested. More peace of mind. Fewer ulcers for the product manager.</p>
<p><strong>Is Sliced Bread Really so Wonderful?</strong></p>
<p>For those practicing Agile already, the benefits listed above may seem rather short (there are many other benefits beyond testing) and mundane. After all, this is all stuff you take for granted. But for those product managers still wallowing in big, monolithic processes or halfheartedly adopting aspects of Agile: jump in, the water's fine. You'll notice when the pain stops and then, hopefully like childbirth, you'll forget all about it.</p>
<p>I've only scratched the surface here on Agile testing. To my readers: any notes or observations on testing you'd like to share?</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/03/agile-development-for-product-managers-why-agile-testing-rocks/">Agile Development for Product Managers: Why Agile Testing Rocks</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/05/agile-development-and-testing-unit-or-montecarlo/' rel='bookmark' title='Permanent Link: Agile Development and Testing: Unit or Montecarlo?'>Agile Development and Testing: Unit or Montecarlo?</a></li><li><a href='http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/' rel='bookmark' title='Permanent Link: Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests'>Cucumber Rocks &#8211; But it&#8217;s not a replacement for unit tests</a></li><li><a href='http://www.pathf.com/blogs/2008/05/800-on-your-mat/' rel='bookmark' title='Permanent Link: 800 on Your Math SAT, Software Development and Bugs'>800 on Your Math SAT, Software Development and Bugs</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/03/agile-development-for-product-managers-why-agile-testing-rocks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Again With The Test Driven Development</title>
		<link>http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/</link>
		<comments>http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 19:10:14 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1404</guid>
		<description><![CDATA[



my economics final by "diabetesisfun"

So, if you're lucky, you've mostly missed another Internet pile-up about unit tests and so on, this one started by Joel Spolsky and some comments he made on his podcast.
I've already written a little bit about what Joel said, and I don't want to rehash that. But I have seen a [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/">Again With The Test Driven Development</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/08/test-driven-dev/' rel='bookmark' title='Permanent Link: Test-Driven Development As Part of the Process'>Test-Driven Development As Part of the Process</a></li><li><a href='http://www.pathf.com/blogs/2008/04/at-todays-web-2/' rel='bookmark' title='Permanent Link: Web 2.0 Expo: Behavior-Driven Development with Rails and RSpec'>Web 2.0 Expo: Behavior-Driven Development with Rails and RSpec</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.flickr.com/photos/diabetesisfun/2585698133/"><br />
<img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/02/e2999d43-f2f6-40f0-94b8-846bda09e1ec.jpg" border="0" alt="E2999D43-F2F6-40F0-94B8-846BDA09E1EC.jpg" width="240" height="160" /><br />
</a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://www.flickr.com/photos/diabetesisfun/2585698133/">my economics final by "diabetesisfun"</a><br />
</span></div>
<p>So, if you're lucky, you've mostly missed another Internet pile-up about unit tests and so on, this one started by <a href="http://www.joelonsoftware.com/items/2009/01/31.html">Joel Spolsky</a> and some comments he made on his podcast.</p>
<p><a href="http://blog.railsprescriptions.com/2009/02/04/i-suppose-i-should-talk-about-this">I've already written a little bit about what Joel said</a>, and I don't want to rehash that. But I have seen a recurring theme in <a href="http://agilesoftwaredevelopment.com/blog/janusz-gorycki/your-unit-tests-are-useless">arguments that testing is overrated</a> -- namely that the testing that those people are writing about doesn't seem to be related to the testing that I actually do.</p>
<p>I'm going to put the summary up front:</p>
<ul>
<li>"Unit Testing" and "Test Driven Development" are not identical concepts</li>
<li>It would seem, on the available evidence, that those of use who are TDD or BDD backers haven't done a great job of explaining this.</li>
<li>TDD has code quality benefits that are completely separate from whatever function it has as a code verification engine.</li>
<li>It would seem, on the available evidence, that those of use who are TDD or BDD backers have done a really poor job of explaining this.</li>
</ul>
<p><span id="more-1404"></span></p>
<p>In my head, Test Driven Development is a process where you write a short little test, write a short little bit of code to pass the test, refactor and move on. There's constant feedback between code and tests, and you move between the two freely.</p>
<p>This is probably an over-generalization, but it seems like "Unit Testing" often refers to a process where you write a lot of code -- days or weeks worth -- then go back and try to write tests against it. That does sound painful. You can never quite remember what the code was supposed to do, and retrofitting tests to existing code is never fun. If that was the only kind of testing I was familiar with, and some yahoo came around shouting about how I needed to test 100% of the time, I'd probably think that guy was crazy.</p>
<p>Luckily, that's not the way I test or the reason I test.</p>
<p>Put plainly, I write code test first because I write better code. And I write it faster. And when there are bugs, I find them quicker. And I enjoy coding more. Your milage may, of course, vary, but my milage from TDD is consistently good.</p>
<p><strong>I write better code</strong>: Code written using TDD has a very distinctive style and structure. Smaller methods, smaller classes, very strongly decomposed, not a lot of duplication, not a lot of side effects. Mostly, this is due to the way in which small methods that do one thing are easy to test -- the small structure evolves organically from the co-existence of the tests.</p>
<p><strong>I write code faster</strong>: Here's an idealized thought experiment. Let's say I'm writing a browser feature, and it takes, say, 30 seconds for me to exercise the feature in the app. Let's say it takes a full minute to write the initial test, but only a few seconds to run the test once it's written. How many times do I have to check what I've written before the test pays for itself? Plus, the test is always there when I need to come back to the feature.</p>
<p><strong>I find bugs faster</strong>: Even granted that TDD doesn't catch all possible bugs, my experience in TDD-developed systems is that bugs are easier to find and fix, largely as a result of the smaller, less duplicated structure. Generally, the bugs are more localized</p>
<p><strong>I enjoy coding more</strong>: Because it feels like a game. But hey, that's just me, right?</p>
<p>I leave you with this Rails testing Haiku, courtesy of Pathfinder's own Alice Toth:</p>
<p>flowing dots on screen<br />
unbroken but for an F<br />
my work is not done</p>
<p>Feel free to leave your own testing Haiku, or anything else, in the comments.</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/">Again With The Test Driven Development</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/08/test-driven-dev/' rel='bookmark' title='Permanent Link: Test-Driven Development As Part of the Process'>Test-Driven Development As Part of the Process</a></li><li><a href='http://www.pathf.com/blogs/2008/04/at-todays-web-2/' rel='bookmark' title='Permanent Link: Web 2.0 Expo: Behavior-Driven Development with Rails and RSpec'>Web 2.0 Expo: Behavior-Driven Development with Rails and RSpec</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/02/again-with-the-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>More Testing Interviews</title>
		<link>http://www.pathf.com/blogs/2009/01/more-testing-interviews/</link>
		<comments>http://www.pathf.com/blogs/2009/01/more-testing-interviews/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 18:01:53 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1375</guid>
		<description><![CDATA[Just a quick note that the next two testing interviews are up on the Rails Prescriptions Blog:
Geoffrey Grosenbach of PeepCode and Topfunky.
Gregg Pollack of Rails Envy, the Rails Envy Podcast and Rails Activist fame.
Enjoy!

Pathfinder Development - creating innovative software that builds business value. 
More Testing Interviews


Related posts:The Testing InterviewsGetting Started With Rails Testing Guide Now [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/more-testing-interviews/">More Testing Interviews</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/' rel='bookmark' title='Permanent Link: Getting Started With Rails Testing Guide Now Available'>Getting Started With Rails Testing Guide Now Available</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions to be Published by Pragmatic'>Rails Test Prescriptions to be Published by Pragmatic</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Just a quick note that the next two testing interviews are up on <a href="blog.railsprescriptions.com">the Rails Prescriptions Blog</a>:</p>
<p><a href="http://blog.railsprescriptions.com/2009/01/19/testing-interview-two-geoffrey-grosenbach">Geoffrey Grosenbach</a> of <a href="http://www.peepcode.com">PeepCode</a> and <a href="http://www.topfunky.com">Topfunky</a>.</p>
<p><a href="http://blog.railsprescriptions.com/2009/01/21/testing-practices-interview-3-gregg-pollack">Gregg Pollack</a> of <a href="http://www.railsenvy.com">Rails Envy</a>, the <a href="http://www.railsenvy.com/podcast">Rails Envy Podcast</a> and <a href="http://rubyonrails.org/activists">Rails Activist fame</a>.</p>
<p>Enjoy!</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/more-testing-interviews/">More Testing Interviews</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/' rel='bookmark' title='Permanent Link: Getting Started With Rails Testing Guide Now Available'>Getting Started With Rails Testing Guide Now Available</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-test-prescriptions-published-pragmatic/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions to be Published by Pragmatic'>Rails Test Prescriptions to be Published by Pragmatic</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/01/more-testing-interviews/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Testing Interviews</title>
		<link>http://www.pathf.com/blogs/2009/01/the-testing-interviews/</link>
		<comments>http://www.pathf.com/blogs/2009/01/the-testing-interviews/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 17:24:24 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1364</guid>
		<description><![CDATA[


These interviews will be just as important as Frost/Nixon

Over at the Rails Prescriptions blog, I'm going to be posting a series of interviews with various and sundry Rails folks -- I'm cross-posting the first one here. To get the series started off, I've decided to use myself as a guinea pig and see if I [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/the-testing-interviews/">The Testing Interviews</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/more-testing-interviews/' rel='bookmark' title='Permanent Link: More Testing Interviews'>More Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/' rel='bookmark' title='Permanent Link: Getting Started With Rails Testing Guide Now Available'>Getting Started With Rails Testing Guide Now Available</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://blog.railsprescriptions.com"><br />
<img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/01/cce2d523-3fff-47c4-993a-1222dda5b1b8.jpg" border="0" alt="CCE2D523-3FFF-47C4-993A-1222DDA5B1B8.jpg" width="292" height="164" /></a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://blog.railsprescriptions.com">These interviews will be just as important as Frost/Nixon</a><br />
</span></div>
<p>Over at the <a href="http://blog.railsprescriptions.com">Rails Prescriptions</a> blog, I'm going to be posting a series of interviews with various and sundry Rails folks -- I'm cross-posting the first one here. To get the series started off, I've decided to use myself as a guinea pig and see if I can hold up to the grilling.</p>
<p>A couple of quick notes before I get to it.</p>
<ul>
<li>The free e-book <a href="http://www.railsprescriptions.com">Getting Started With Rails Testing</a> is now available. Check it out.</li>
<li>Those of you lucky enough to be in the sub-zero Chicago area can come to the<a href="http://www.meetup.com/chicagoruby/">Chicago Ruby.org meetup</a> Saturday, January 17th to hear lots of interesting stuff, including me talking about testing and Rails some more.</li>
</ul>
<p>And on with the interview.<br />
<span id="more-1364"></span></p>
<h3>How did you get into writing tests regularly? Did you have a specific moment when you realized automated testing was valuable?</h3>
<p>I started with automated testing very shortly after reading Kent Beck's original XP book. The XP book came out at a time when I was very receptive to the ideas -- I had just come off a project that had suffered from a lot of regressions and all the other kinds of pain that XP promised.</p>
<p>It didn't take long for me to see how much better my code was when I did a lot of testing... what was more surprising was how much more fun writing code test-first turned out to be. The quick feedback and the ability to clean up code with confidence turned out to be really satisfying.</p>
<h3>What is your Rails testing process? What kinds of tests do you write, and what tools do you use to write them?</h3>
<p>When I'm adding a new feature, I tend to start with a skeleton controller test that validates that the controller sets the right variables. I don't put much code in the controller, so then I move to testing the model for the new functionality. If the view logic seems to require it, then I'll add view tests after I get the view in place. I go back and forth between test and code pretty quickly, but sometimes the code will get ahead of the tests, especially when doing view layer stuff. I don't use integration tests very much at the moment.</p>
<p>I seem to have moved back into the core Rails test features recently, although I still use <a href="http://www.thoughtbot.com/projects/">Shoulda</a> for contexts and for the additional assertions. My most recent project used core Rails plus <a href="http://github.com/jeremymcanally/matchy/tree/master">Matchy</a>. I've also been using the various factory replacements for fixtures, which I like quite a bit.</p>
<h3>What's the most interesting thing you've discovered about testing recently?</h3>
<p>The biggest change I've made recently is using factories for generating test data, which makes the tests much more readable and stable by keeping the setup closer to the actual test.</p>
<h3>Is there a tool you wish you had for testing that you don't think currently exists?</h3>
<p>I wish I had a really good way of validating view logic, none of the ones I've tried have been completely satisfying. It'd also be nice to have more sophisticated coverage reports. Of course, these things might actually be impossible...</p>
<h3>What advice would you give somebody looking to write more effective tests?</h3>
<p>Automated testing is much easier and more valuable if you keep a tight feedback loop between your tests and your code.</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/the-testing-interviews/">The Testing Interviews</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/01/more-testing-interviews/' rel='bookmark' title='Permanent Link: More Testing Interviews'>More Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/' rel='bookmark' title='Permanent Link: Getting Started With Rails Testing Guide Now Available'>Getting Started With Rails Testing Guide Now Available</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/01/the-testing-interviews/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting Started With Rails Testing Guide Now Available</title>
		<link>http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/</link>
		<comments>http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 17:52:40 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1361</guid>
		<description><![CDATA[
I'm pleased to announce that the getting started guide, conveniently titled "Getting Started With Rails Testing" is now available for download at the Rails Prescriptions site.
It grew to be a bit longer than I originally intended, but I'm very happy with how it turned out. It starts with an empty Rails application and walks through [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/">Getting Started With Rails Testing Guide Now Available</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2009/07/more-kudos-for-rails-prescriptions/' rel='bookmark' title='Permanent Link: More Kudos for Rails Prescriptions'>More Kudos for Rails Prescriptions</a></li><li><a href='http://www.pathf.com/blogs/2009/01/more-testing-interviews/' rel='bookmark' title='Permanent Link: More Testing Interviews'>More Testing Interviews</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="right" src="http://www.pathf.com/blogs/wp-content/uploads/2009/01/getting-started.png" border="0" alt="getting_started.png" width="277" height="193" /></p>
<p>I'm pleased to announce that the getting started guide, conveniently titled "Getting Started With Rails Testing" is now available for download <a href="http://www.railsprescriptions.com">at the Rails Prescriptions site</a>.</p>
<p>It grew to be a bit longer than I originally intended, but I'm very happy with how it turned out. It starts with an empty Rails application and walks through the first couple of feature additions, adding tests for controllers, models, views, and basic security.</p>
<p>Download, read, enjoy, tell all your friends, let me know what you think.</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/">Getting Started With Rails Testing Guide Now Available</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/03/rails-test-prescriptions-is-now-on-sale/' rel='bookmark' title='Permanent Link: Rails Test Prescriptions is now on sale'>Rails Test Prescriptions is now on sale</a></li><li><a href='http://www.pathf.com/blogs/2009/07/more-kudos-for-rails-prescriptions/' rel='bookmark' title='Permanent Link: More Kudos for Rails Prescriptions'>More Kudos for Rails Prescriptions</a></li><li><a href='http://www.pathf.com/blogs/2009/01/more-testing-interviews/' rel='bookmark' title='Permanent Link: More Testing Interviews'>More Testing Interviews</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/01/getting-started-with-rails-testing-guide-now-available/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Talking about Testing With Chicago Ruby on January 17</title>
		<link>http://www.pathf.com/blogs/2009/01/talking-about-testing-with-chicago-ruby-on-january-17/</link>
		<comments>http://www.pathf.com/blogs/2009/01/talking-about-testing-with-chicago-ruby-on-january-17/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 16:32:19 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Pathfinder General]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Development Best Practices]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=1356</guid>
		<description><![CDATA[I'll be doing a talk on Getting Started With Rails Testing and/or related testing topics this Saturday, January 17th at the monthly meeting of ChicagoRuby.org.
It's at 3pm, location and other information is available at their meetup.com site.
Looking forward to it -- see you there!

Pathfinder Development - creating innovative software that builds business value. 
Talking about [...]<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/talking-about-testing-with-chicago-ruby-on-january-17/">Talking about Testing With Chicago Ruby on January 17</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/08/why-chicago-is-rails-town-usa/' rel='bookmark' title='Permanent Link: Why Chicago is Rails-town, USA'>Why Chicago is Rails-town, USA</a></li><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2008/11/testing-various-roles-in-ruby-on-rails/' rel='bookmark' title='Permanent Link: Testing various roles in ruby on rails'>Testing various roles in ruby on rails</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I'll be doing a talk on Getting Started With Rails Testing and/or related testing topics this Saturday, January 17th at the monthly meeting of <a href="http://www.chicagoruby.org">ChicagoRuby.org</a>.</p>
<p>It's at 3pm, location and other information is available <a href="http://www.meetup.com/ChicagoRuby/">at their meetup.com site</a>.</p>
<p>Looking forward to it -- see you there!</p>
<p><hr>
<a href="http://www.pathf.com/">Pathfinder Development - creating innovative software that builds business value. </a>
<br/><br/><a href="http://www.pathf.com/blogs/2009/01/talking-about-testing-with-chicago-ruby-on-january-17/">Talking about Testing With Chicago Ruby on January 17</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/08/why-chicago-is-rails-town-usa/' rel='bookmark' title='Permanent Link: Why Chicago is Rails-town, USA'>Why Chicago is Rails-town, USA</a></li><li><a href='http://www.pathf.com/blogs/2009/01/the-testing-interviews/' rel='bookmark' title='Permanent Link: The Testing Interviews'>The Testing Interviews</a></li><li><a href='http://www.pathf.com/blogs/2008/11/testing-various-roles-in-ruby-on-rails/' rel='bookmark' title='Permanent Link: Testing various roles in ruby on rails'>Testing various roles in ruby on rails</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/01/talking-about-testing-with-chicago-ruby-on-january-17/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 12.860 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-21 03:21:24 -->
