<?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; Noel Rappin</title>
	<atom:link href="http://www.pathf.com/blogs/author/noel-rappin/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>A Pair of Kings Beats A Single Ace: Pair Programming, Agile Rails, and You</title>
		<link>http://www.pathf.com/blogs/2009/09/a-pair-of-kings-beats-a-single-ace-pair-programming-agile-rails-and-you/</link>
		<comments>http://www.pathf.com/blogs/2009/09/a-pair-of-kings-beats-a-single-ace-pair-programming-agile-rails-and-you/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 14:59:01 +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[agile]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=4158</guid>
		<description><![CDATA[
A lot of pair programming chatter this week. Starting with a New York times article describing pair programming at Hashrocket. It's an interesting article, with a tone that could be described as "anthropologist describing the strange, yet quaint customs of the native tribe"
Obie Fernandez followed up with a list of 10 reasons why pairing doesn't [...]<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/a-pair-of-kings-beats-a-single-ace-pair-programming-agile-rails-and-you/">A Pair of Kings Beats A Single Ace: Pair Programming, Agile Rails, and You</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/11/the-importance/' rel='bookmark' title='Permanent Link: The Importance of Pair Programming'>The Importance of Pair Programming</a></li><li><a href='http://www.pathf.com/blogs/2009/07/growing-into-pair-programming/' rel='bookmark' title='Permanent Link: Growing Into Pair Programming'>Growing Into Pair Programming</a></li><li><a href='http://www.pathf.com/blogs/2007/09/pair-programmin/' rel='bookmark' title='Permanent Link: Pair Programming with VNC'>Pair Programming with VNC</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.pathf.com/blogs/wp-content/uploads/2009/09/C34FF759-31EE-407B-A9E2-0A4611213735.jpg" alt="C34FF759-31EE-407B-A9E2-0A4611213735.jpg" border="0" width="200" height="211" class="right"/></p>
<p>A lot of pair programming chatter this week. Starting with <a href="http://www.nytimes.com/2009/09/20/jobs/20pre.html?_r=2">a New York times article describing pair programming at Hashrocket</a>. It's an interesting article, with a tone that could be described as "anthropologist describing the strange, yet quaint customs of the native tribe"</p>
<p>Obie Fernandez <a href="http://blog.obiefernandez.com/content/2009/09/10-reasons-pair-programming-is-not-for-the-masses.html">followed up with a list of 10 reasons why pairing doesn't work in most cases</a>. It's actually a list of the things that Hashrocket does to support pairing, although entries like "2. Most software developers just don't want to work that hard" and "1. Most software shops don't really care about excellence" do have a certain, "aren't we great" vibe to them, causing Mike Gunderloy <a href="http://twitter.com/MikeG1/status/4314308701">to dryly observe</a>: "Funny, Extreme Programming Explained never said anything about fancy hw or being awesome as a prerequisite for pair programming." </p>
<p>C'mon Mike -- everybody knows that being awesome is a prerequisite for <em>everything</em> in XP.</p>
<p>Josh Susser adds <a href="http://blog.hasmanythrough.com/2009/9/23/pair-programming-isnt-right-for-all-projects">that pair programming isn't right for all projects</a>, particularly projects that have long compile times that force the pair to stare blankly at the screen.</p>
<p>I'd also add this <a href="http://www.twit.tv/floss87">interview with Kent Beck</a> because a) every programmer could use some more Kent Beck in their life and b) because he talks about XP as being concerned with the the social context of programmers, with pairing being a part of that.</p>
<p>Now you are caught up. Here's the part where I talk. </p>
<p><span id="more-4158"></span>I've had a running debate with Dietrich for two years now. He thinks that Pair Programming is the number one most important part of an agile team. I think it's testing. That said, I do think pairing can be a nutritious part of your agile breakfast. But it's tricky to do right and easy to do wrong.</p>
<p><strong>Pairing is for the long haul</strong>. Like pretty much everything in the Agile toolkit, the real gain in pairing happens over time and is hard to quantify because it's the absence of friction later in the project. Code is cleaner and easier to change. System knowledge is more distributed, so you are less likely to freak out when Fred catches H1N1 a week before. </p>
<p>Actually, I'd describe most of the XP practices as "we thought we were trading short-term productivity for long-term productivity, then found that we got short-term gains as well." Certainly can apply to TDD. </p>
<p><strong>Project size and make up matters</strong>. A team of three developers, for example, is a challenge for an always-pairing environment. Even a team of two is a problem -- some tasks really don't lend themselves to pairing. If people on the team also has non-developer responsibilities, that's another challenge. </p>
<p><strong>Some people really don't like it</strong>. And I think it's glib to say "those people are lazy" or "those people don't care about excellence". Even I find pair programming really tiring, but in a "I worked hard today, plus I had to deal with another person all day." It's not unusual for programmers to be very strong Meyers-Briggs introvert-intuitives, and it's not surprising that personality type would find pairing a challenge. It's not insurmountable, but you do need to structure the pairing with people in mind -- the Hashrocket 25 minutes on/ 5 minutes off thing is a good start.</p>
<p>While I'm here, I think you can really overstate the "people work harder with somebody next to them" thing. Pairing is great and helpful because of the continual review and talking about what you are doing. Conceiving pairing as a way to use peer pressure to keep your coders off of Twitter is, I submit, not very much in keeping with the spirit of the Agile Manifesto.</p>
<p><strong>The physical layout is really important</strong>. A lot of Obie's piece is about this. I just want to emphasize first that pairing is a lot louder than solo programming, and this can be an issue in open office environments, and also that pairing really does work better on a neutral environment that isn't either developer's home machine.</p>
<p><strong>Pairing is hard to reconcile with offsite practices</strong> And I don't mean just when you're working with six guys in Krakow, but also any kind of work at home, flexible hours, programmer-friendly kind of time structure is a real challenge to integrate with pairing.</p>
<p>Hmm... A lot of challenges, not much guidance. Which matches my feelings. When put in the right context, pairing is fantastic. But the context can be elusive, even for people with the best of intentions and talent.</p>
<p>Would this have been a better blog post if I had paired with a co-worker?</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/a-pair-of-kings-beats-a-single-ace-pair-programming-agile-rails-and-you/">A Pair of Kings Beats A Single Ace: Pair Programming, Agile Rails, and You</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/11/the-importance/' rel='bookmark' title='Permanent Link: The Importance of Pair Programming'>The Importance of Pair Programming</a></li><li><a href='http://www.pathf.com/blogs/2009/07/growing-into-pair-programming/' rel='bookmark' title='Permanent Link: Growing Into Pair Programming'>Growing Into Pair Programming</a></li><li><a href='http://www.pathf.com/blogs/2007/09/pair-programmin/' rel='bookmark' title='Permanent Link: Pair Programming with VNC'>Pair Programming with VNC</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/09/a-pair-of-kings-beats-a-single-ace-pair-programming-agile-rails-and-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Corners of the Rubyverse: RVM and MacRuby</title>
		<link>http://www.pathf.com/blogs/2009/09/corners-of-the-rubyverse-rvm-and-macruby/</link>
		<comments>http://www.pathf.com/blogs/2009/09/corners-of-the-rubyverse-rvm-and-macruby/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 16:59:18 +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>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=4047</guid>
		<description><![CDATA[
Please continue reading after the next sentence.
I installed Snow Leopard a couple of weeks ago.
Wait -- don't stop reading. This isn't a post about how to install MySQL or a post about whether or not Snow Leopard is the Greatest Thing Ever. There are plenty of other places on the Internet where you can get [...]<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/corners-of-the-rubyverse-rvm-and-macruby/">Corners of the Rubyverse: RVM and MacRuby</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/03/keeping-up-with-the-joneses-keeping-rails-and-its-extensions-up-to-date/' rel='bookmark' title='Permanent Link: Keeping Up With The Joneses: Keeping Rails and its extensions up to date'>Keeping Up With The Joneses: Keeping Rails and its extensions up to date</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-development-on-windows-native-or-virtualize/' rel='bookmark' title='Permanent Link: Rails Development on Windows: Native or Virtualize'>Rails Development on Windows: Native or Virtualize</a></li><li><a href='http://www.pathf.com/blogs/2008/11/installing-edge-ferretacts_as_ferret/' rel='bookmark' title='Permanent Link: Installing Edge Ferret/acts_as_ferret'>Installing Edge Ferret/acts_as_ferret</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.pathf.com/blogs/wp-content/uploads/2009/09/C2418006-9AF1-4724-A2CF-27460658A115.jpg" alt="C2418006-9AF1-4724-A2CF-27460658A115.jpg" border="0" width="300" height="300" class="right"/></p>
<p>Please continue reading after the next sentence.</p>
<p>I installed Snow Leopard a couple of weeks ago.</p>
<p>Wait -- don't stop reading. This isn't a post about how to install MySQL or a post about whether or not Snow Leopard is the Greatest Thing Ever. There are plenty of other places on the Internet where you can get that information.</p>
<p>I wanted to talk about two cool corners of the Ruby universe that I started using as a result of my Snow Leopard installation: MacRuby and RVM<span id="more-4047"></span><br />
<h3>RVM: Ruby Version Manager</h3>
<p>One of the Ruby changes in Snow Leopard was an upgrade of the system Ruby version to 1.8.7. All fine, except that one of the projects I work on is on an older version of Rails that is not compatible. Clearly, I needed to get an 1.8.6 Ruby on my machine, ideally without messing up the system installation that other applications are using.</p>
<p>Enter <a href="http://rvm.beginrescueend.com">Ruby Version Manager</a> (RVM), a handy command line tool for installing and managing multiple Ruby interpreters on your system. In theory, usage is as simple as this:</p>
<pre style="white-space: pre !important;">
$ gem install rvm
$ rvm-install
</pre>
<p>At this point RVM asks you to make a slight change to your shell files. Then just this:</p>
<pre style="white-space: pre !important;">
$ rvm use 1.8.6
</pre>
<p>"But you didn't have 1.8.6", I hear you cry. True. RVM will go out, download, compile, and install Ruby 1.8.6 to my local machine without interfering with anything else on the system (it installs in ~/.rvm). You can install Ruby 1.8.x, Ruby 1.9.x, Ruby Enterprise, JRuby, Rubinius, and (I think) MacRuby.</p>
<p>(Okay -- that's the ideal. In practice, it took a little bit of system tweaks and command line tweaks. <a href="http://afreshcup.com/2009/09/02/migrating-to-snow-leopard-for-rails-development-a-definitive-guide/">Mike Gunderloy's Snow Leopard guide</a> was helpful here. Although I've been able to get all the main Ruby versions to install, I'm still struggling some of the more esoteric version. Once installation is done, the command line interface is really good and things just work.)</p>
<p>Now, the Ruby in my shell is the new 1.8.6. But any other running terminal shells are unaffected -- especially helpful if you are working on multiple projects. Each Ruby maintains its own Gem listing, although there's work ongoing to make it easy to share gems.</p>
<p>To get back to the system Ruby, just</p>
<pre style="white-space: pre !important;">
rvm use system
</pre>
<p>You can also specify any Ruby version as the default.</p>
<p>This is outstandingly cool, not just to solve my problem, but also as an easy way to create a harness to test your Ruby program or library against multiple Ruby setups. There are other useful features about setting different versions and managing shells, check it out.</p>
<h3>MacRuby</h3>
<p>Here's the thing. For the last several years I've had this script that communicates with iTunes via AppleScript, and creates a bunch of random playlists according to criteria that is a bit more complex that an iTunes smart playlist. For instance, it can create a playlist made up of two-song blocks by the same artist. Okay, it's wildly overdone, but I like it.</p>
<p>It broke in Snow Leopard. I don't know why. It seems like the Scripting Bridge framework occasionally decides to go out for a cup of coffee, and my script times out.</p>
<p>This seemed like as good a time as any to investigate MacRuby. <a href="http://www.macruby.org">MacRuby</a> is an implementation of Ruby in Mac OS X Objective-C. Unlike a lot of hybrid language/vm tools, MacRuby gives you direct access to the native objects. So, if you ask for a string, you get an object that acts as both a Ruby string and a Cocoa NSString, responding to methods of either. MacRuby uses Ruby 1.9 key/value arguments to translate Objective-C method names. </p>
<pre style="white-space: pre !important;">
[person name];
[person setName:name];
[person setFirstName:first lastName:last];
</pre>
<p>In Ruby (this example is from a tutorial on the MacRuby site)</p>
<pre style="white-space: pre !important;">
person.name
person.setName(name)
person.setFirstName(first, lastName:last)
</pre>
<p>Unlike regular Ruby, the order of the keyword arguments must match the Cocoa method selector.</p>
<p>For most people, this allows writing Cocoa applications in Ruby, including integration with XCode and Interface Builder. </p>
<p>That's extremely useful, and I plan on trying it soon. For my purposes, the point is that it uses the Scripting Bridge directly, and I hoped that would allow it to bypass whatever weirdness was breaking my original script. (The original script was in Python, but I had a 75% functional Ruby version that I never actually built the I/O on, so it was largely a matter of learning the MacRuby way to communicate with iTunes.) Here's a sample, cobbled together from various parts of the script:</p>
<pre style="white-space: pre !important;">
def itunes
  @itunes ||= SBApplication.applicationWithBundleIdentifier(
    "com.apple.itunes")
end

def library
  @library ||= itunes.sources.objectWithName("Library")
end

def all_music
  @all_music ||= library.userPlaylists.objectWithName("Music")
end

all_music.fileTracks.each_with_index do |track, index|
  # stuff here
end

def create_itunes_playlist
  playlist = itunes.classForScriptingClass(
      "playlist").alloc.initWithProperties(
      {'name' => name})
  library.playlists.addObject(playlist)
  playlist
end

#chosen_tracks are my object wrappers around Cocoa
#itunes_track is the actual cocoa object
playlist = create_itunes_playlist
chosen_tracks.each_with_index do |track, index|
  track.itunes_track.duplicateTo(playlist)
end
</pre>
<p>Overall, everything works as advertised (it seems as though MacRuby is better able to deal with whatever happens to cause the Scripting Bridge to take a nap. I'm using the pre-release MacRuby 0.5, so there's the occasional feature glitch (gem installation is a little dicey, for example). But the MacRuby team is actively, even furiously, pushing forward, and this looks like it'll be very useful, very soon.</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/corners-of-the-rubyverse-rvm-and-macruby/">Corners of the Rubyverse: RVM and MacRuby</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/03/keeping-up-with-the-joneses-keeping-rails-and-its-extensions-up-to-date/' rel='bookmark' title='Permanent Link: Keeping Up With The Joneses: Keeping Rails and its extensions up to date'>Keeping Up With The Joneses: Keeping Rails and its extensions up to date</a></li><li><a href='http://www.pathf.com/blogs/2009/08/rails-development-on-windows-native-or-virtualize/' rel='bookmark' title='Permanent Link: Rails Development on Windows: Native or Virtualize'>Rails Development on Windows: Native or Virtualize</a></li><li><a href='http://www.pathf.com/blogs/2008/11/installing-edge-ferretacts_as_ferret/' rel='bookmark' title='Permanent Link: Installing Edge Ferret/acts_as_ferret'>Installing Edge Ferret/acts_as_ferret</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/09/corners-of-the-rubyverse-rvm-and-macruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WindyCityRails: My Presentation Checklist</title>
		<link>http://www.pathf.com/blogs/2009/09/windycityrails-my-presentation-checklist/</link>
		<comments>http://www.pathf.com/blogs/2009/09/windycityrails-my-presentation-checklist/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 16:14:16 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technologies and Platforms]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=4009</guid>
		<description><![CDATA[WindyCityRails 2008
Sometimes I write these just for me.
As I've mentioned a couple of times, tomorrow I'll be speaking at WindyCityRails, and I need a checklist of all things I don't want to forget, and all thing things I want to do to make the talk great.

Preparing the Talk
Figure out what you want to say first. [...]<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/windycityrails-my-presentation-checklist/">WindyCityRails: My Presentation Checklist</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/06/artifacts-of-a/' rel='bookmark' title='Permanent Link: Artifacts of a Presentation'>Artifacts of a Presentation</a></li><li><a href='http://www.pathf.com/blogs/2008/07/1008/' rel='bookmark' title='Permanent Link: Ruby Code Audit Checklist'>Ruby Code Audit Checklist</a></li><li><a href='http://www.pathf.com/blogs/2008/09/windy-city-rails/' rel='bookmark' title='Permanent Link: Windy City Rails'>Windy City Rails</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href=""><img src="http://farm4.static.flickr.com/3097/2892206860_20c318941b_m.jpg" alt="WindyCityRails 2008" border="0" width="" height="" class="right"/></a><br clear="all"/><span class="right" style="font-size: smaller"><a href="http://www.windycityrails.org/">WindyCityRails 2008</a></span></div>
<p>Sometimes I write these just for me.</p>
<p>As I've mentioned a couple of times, tomorrow I'll be speaking at <a href="http://www.windycityrails.org">WindyCityRails</a>, and I need a checklist of all things I don't want to forget, and all thing things I want to do to make the talk great.<br />
<span id="more-4009"></span><br />
<h3>Preparing the Talk</h3>
<p>Figure out what you want to say first. The outline view in PowerPoint and Keynote is a great way to organize what you want to say without worrying about how it looks.</p>
<p>Determine a small number of things that you think are key items that you want the audience to walk away with. Mention them at the start, summarize them at the end.</p>
<p>The classic advice is not to put too much text on your slides, and avoid reading the text directly. A pragmatic way to manage this is to set your body text font pretty large (I use 44 point fonts for my body text if I can get away with it), and break up any slide that threatens to overrun.</p>
<p>That said, you can make the opposite mistake as well -- I find it tiring to go to a talk where all the slides are two-words and a non-sequitur picture. People may be viewing just your slides online, they need a little bit of context. Even people in the room often need a bit of context on the slides to help follow what you are saying.</p>
<p>Building up the slides during the talk point by point using animation can be a good way to keep from reading too much text on the slides. And it can help time a "punch line" by keeping it from the audience until you are ready. But don't use it everywhere. (I've always wanted to give a talk that used bullet points like Colbert does in The Word segment, as ironic commentary. But that's very hard, and I'm not sure it would work.)</p>
<p>I do like to separate off major sections of the talk with title-only slides. I've started tying these sections together by putting images on the title slide, and carrying those images in the background of the slides in the section at something like 20% opaque. It makes it easier for people in the audience to follow along.</p>
<p>Keep the number of moving parts to a minimum -- rather than switch to an editor to show code, copy the code into your slides. TextMate has a "Copy to RTF" bundle that preserves syntax highlighting, or take a screen shot.</p>
<p>Similarly, try to avoid having to run code during your talk. (Unless the interactivity is the point, as in a longer workshop).</p>
<p>Try not to depend on Internet access for a demo, you never know how flakey the Internet is going to be at a venue. At the very least, have a bunch of screenshots in hand as a plan B. </p>
<p>Practice. Do a dry run by yourself. If you see something wrong in your slides or missing in your talk, write it down. But do try and get a clean dry run at some point, so you get a sense of how long the talk is.</p>
<p>If possible, practice in front of other people. Nearly every talk that somebody at Pathfinder gives has a practice run as a company brown bag. This is invaluable feedback as to what is interesting in your talk and what is not.</p>
<p>In many situations, your last slide will be up for a while while you answer questions or something. Put something useful on there, generally either a summary or places to go for more information.</p>
<h3>Doing the Talk</h3>
<p>Make sure you bring everything you need. Laptop. Power Cord. Monitor Adapter. Remote Control. Don't assume that anything will be as you expect in the actual setup. As I type this I'm going to put my monitor adapter in my backpack. Put a copy of your talk on a thumb drive. Put a copy online using Dropbox or Gmail it to yourself. </p>
<p>If at all possible, scope out the space well before your talk. Where will you stand? Will you be able to see your own slides? Will you need a remote, or will you need to stand in front of your presentation machine?</p>
<p>Try and set up early if you can (if you are part of a conference program, you're limited because there's a previous speaker). Still, the less the audience sees you fumbling with cables the better off you are. It helps if you can check to see if the display resolution matches your slides.</p>
<p>Before the talk, shut down as many programs as you can on your laptop. Especially shut down notifiers -- you don't want an IM from your mom popping up in the middle. </p>
<p>I use a Mac utility called <a href="http://lightheadsw.com/caffeine/">Caffeine</a> to keep my computer from going to sleep in the middle of the talk, because it's annoying when that happens. </p>
<p>The point of all this is to reduce the amount of things that can go wrong so that you can be as relaxed and have fun during the talk.</p>
<p>Getting started can be awkward. Sometimes it helps to get the audience involved by asking a question or two right off the bat -- this can also help you gauge how much the audience already knows about your topic. It can also be an unobtrusive way to make sure that everybody can hear you.</p>
<p>At the end, if there's time, take questions. Get in the habit of repeating the question before you answer it. There's a good chance that most of the audience didn't hear the question. If you are miked and being recorded, the recording probably won't pick up the question unless you repeat it.</p>
<p>Stick around afterword if you can, often there will be one or two more people who have questions.</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/windycityrails-my-presentation-checklist/">WindyCityRails: My Presentation Checklist</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2007/06/artifacts-of-a/' rel='bookmark' title='Permanent Link: Artifacts of a Presentation'>Artifacts of a Presentation</a></li><li><a href='http://www.pathf.com/blogs/2008/07/1008/' rel='bookmark' title='Permanent Link: Ruby Code Audit Checklist'>Ruby Code Audit Checklist</a></li><li><a href='http://www.pathf.com/blogs/2008/09/windy-city-rails/' rel='bookmark' title='Permanent Link: Windy City Rails'>Windy City Rails</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/09/windycityrails-my-presentation-checklist/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>Bridging the Gap Between Rails Developers and HTML Designers</title>
		<link>http://www.pathf.com/blogs/2009/08/bridging-the-gap-between-rails-developers-and-html-designers/</link>
		<comments>http://www.pathf.com/blogs/2009/08/bridging-the-gap-between-rails-developers-and-html-designers/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 15:56:23 +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[User Experience Design]]></category>
		<category><![CDATA[uxd]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3817</guid>
		<description><![CDATA[<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/bridging-the-gap-between-rails-developers-and-html-designers/">Bridging the Gap Between Rails Developers and HTML Designers</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/07/a-new-workflow-for-web-designers/' rel='bookmark' title='Permanent Link: A New Workflow for Web Designers'>A New Workflow for Web Designers</a></li><li><a href='http://www.pathf.com/blogs/2008/05/down-with-html/' rel='bookmark' title='Permanent Link: Down with HTML + Code Markup!'>Down with HTML + Code Markup!</a></li><li><a href='http://www.pathf.com/blogs/2006/04/designers_on_jo/' rel='bookmark' title='Permanent Link: Designers on Joel'>Designers on Joel</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><img src="http://www.pathf.com/blogs/wp-content/uploads/2009/08/5E22427E-BAAE-41A1-B7A8-B1FF4D55753E.jpg" alt="5E22427E-BAAE-41A1-B7A8-B1FF4D55753E.jpg alt="Mind The Gap" border="0" width="" height="" class="right"/><br clear="all"/>
</div>
<p>To make a cheap joke and paraphrase a common quote, web developers and web designers are two groups separated by common languages. In our case, the languages are HTML and CSS, which are the output of both the web design process and the web development process. Developers and designers produce their HTML/CSS in different ways and with different goals. Here are some ideas for bridging the gap so that the developers and designers on your team can work together smoothly.</p>
<p>Designers and developers obviously have different goals for their HTML -- developers have issues of reducing duplication, organization, and performance that are largely not the designer's concerns. The designer is primarily concerned with how the HTML looks and behaves to the user.</p>
<p><span id="more-3817"></span>By the way, I'm absolutely not trying to make this some kind of left brain/right brain thing. It's more of a software needs vs. domain expertise thing. Once upon a time, I was writing scripts that outputted router configuration files, and I had exactly the same issues with the router domain experts -- my software engineering desire to structure the code without duplication conflicted with the way the router experts liked to structure their hand-written configuration instructions.</p>
<p>Our teams have had success with getting everybody on the team using common tools as much as possible. This means putting designs and code in the same code repository, and it means the development team supports the designers in creating a set up to run the current development version of the app locally. (By the way, <a href="http://www.viget.com/inspire/git-a-designers-perspective/">this article by Mindy Wagner</a> might be helpful if you are trying to convert everybody to Git.)</p>
<p>From the developer perspective, if you are working with HTML provided by designers, it's important to keep the view layer of your code accessible to the HTML providers. Exactly what this means is subject to negotiation. Left to my own devices, I'd be putting all kinds of HTML generation in Ruby via helpers or something more esoteric. That didn't work out well when the designer needed to go mucking about in metaprogrammed Ruby code to start changing CSS classes. We do better with putting pure logical stuff in helpers and using partials to split view logic. I'm pretty sure that if I were to suggest Haml for a project, the designers would veto it -- Haml barely meshes with the way I think of HTML, the designers I've shown it to have basically recoiled in horror.</p>
<p>That said, everybody likes <a href="http//lesscss.org">Less CSS</a>, which seems to augment CSS in ways that seem very intuitive to CSS designers, and which are very satisfying to coders. It does all the things that you would expect CSS to do if it was a real language, but vanilla CSS works just fine. It really caught on quickly here.</p>
<p>From the designer perspective, get everything out of photoshop and into HTML/CSS as early as possible. It's just too easy to put stuff into a photoshop image that represents hours of development work, leaving the developers in the position of trying to determine which parts of the impossible image are vital, and which are just chrome. Doing the wireframes in HTML/CSS keeps the design honest.</p>
<p>We use <a href="http://www.pathf.com/blogs/2008/08/integrating-design-drafts-into-your-rails-app/">this little hack</a> to integrate wireframes into the development app, which is really nice for developers when working with in-progress designs. </p>
<p>Ultimately what it comes down to is for everybody in the team to take some responsibility for making the team work together. The developers need to make the code base accessible to designers and to be alert to basic design issues and flexible in adapting wireframes into the site. Designers need to help place their deliverables in a format that keeps the developer from having to guess how things are supposed to work -- nobody wants that. </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/user-experience-design/">User Experience Design</a>, <a href="http://www.pathf.com/services/technology-expertise/ajax-and-rich-internet-applications/">Ajax Rich Internet Applications</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/bridging-the-gap-between-rails-developers-and-html-designers/">Bridging the Gap Between Rails Developers and HTML Designers</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/07/a-new-workflow-for-web-designers/' rel='bookmark' title='Permanent Link: A New Workflow for Web Designers'>A New Workflow for Web Designers</a></li><li><a href='http://www.pathf.com/blogs/2008/05/down-with-html/' rel='bookmark' title='Permanent Link: Down with HTML + Code Markup!'>Down with HTML + Code Markup!</a></li><li><a href='http://www.pathf.com/blogs/2006/04/designers_on_jo/' rel='bookmark' title='Permanent Link: Designers on Joel'>Designers on Joel</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/08/bridging-the-gap-between-rails-developers-and-html-designers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Testing First Look: Blue Ridge</title>
		<link>http://www.pathf.com/blogs/2009/08/rails-testing-first-look-blue-ridge/</link>
		<comments>http://www.pathf.com/blogs/2009/08/rails-testing-first-look-blue-ridge/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 16:26:46 +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>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3591</guid>
		<description><![CDATA[
Blue Ridge Mountains by eleda 1
So, I tried Blue Ridge for the first time yesterday and I thought I'd write down some quick impressions. Hence, Rails Testing First Look.
Disclaimer: We came into this tool so cold our toes froze. We fumbled, we made mistakes, we probably missed really great ways of doing things. I look [...]<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-testing-first-look-blue-ridge/">Rails Testing First Look: Blue Ridge</a></p>



Related posts:<ol><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><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://farm3.static.flickr.com/2009/1713780788_6ef00e9f1d_m.jpg"><img src="http://farm3.static.flickr.com/2009/1713780788_6ef00e9f1d_m.jpg" alt="" border="0" width="" height="" class="right"/></a><br clear="all"/><span class="right" style="font-size: smaller"><a href="http://farm3.static.flickr.com/2009/1713780788_6ef00e9f1d_m.jpg">Blue Ridge Mountains by eleda 1</a></span></div>
<p>So, I tried <a href="http://github.com/relevance/blue-ridge/tree/master">Blue Ridge</a> for the first time yesterday and I thought I'd write down some quick impressions. Hence, Rails Testing First Look.</p>
<p>Disclaimer: We came into this tool so cold our toes froze. We fumbled, we made mistakes, we probably missed really great ways of doing things. I look forward to being enlightened.</p>
<p>Let's do this question-and-answer style: <span id="more-3591"></span><strong>What is Blue Ridge?</strong> Glad you asked. It's an framework for testing JavaScript from inside a Rails application. For the most part, it's a cohesive bundle of existing JavaScript test tools, such as <a href="http://github.com/nkallen/screw-unit/tree/master">Screw.Unit</a>. The value-add of Blue Ridge is an easy installation and nice integration with Rails testing tasks.</p>
<p><strong>Why did we start using it?</strong> We had some simple JavaScript stuff to do, and thought it would be a good time to start out with what looks like a solid way to test.</p>
<p><strong>Is it easy to install?</strong> Very. Install as a plugin <code>./script/plugin install git://github.com/relevance/blue-ridge.git</code>, then generate the Blue Ridge files with <code>script/generate blue_ridge</code>. </p>
<p>Blue Ridge will install a <code>test/javascript</code> directory. In that directory will be a sample test file <code>application_spec.js</code>, a helper file, and a fixture directory. Each javascript test file is assumed to have a matching HTML file in the fixture directory which is loaded to provide a sample DOM for test purposes.</p>
<p><strong>Does it make any other assumptions?</strong> BlueRidge assumes you are using jQuery as your library. It's theoretically possible to use Prototype, but we ran into continual difficulties (possibly because we were doing it wrong), and actually wound up switching to jQuery for the project, easy enough to do since we just started.</p>
<p><strong>How do you write tests?</strong> Tests are written using Screw.Unit syntax, and if you are familiar with RSpec, the syntax will look pretty similar. Here's the final draft of the first couple of tests we wrote, for a search box with default text that goes away when focused. The TextMate Screw.Unit bundle was very helpful, but other than that, the tests are pretty straightforward.</p>
<pre style="white-space: pre !important;">
Screw.Unit(function() {
  describe("With my search box and default", function() {
    it("should switch the default", function() {
      search_focus($('#unified_search'));
      expect($('#unified_search').attr('value')).to(equal, '');
    });

    it("should switch a non-default", function() {
      $('#unified_search').addClass('search_entry');
      search_blur($('#unified_search'));
      expect($('#unified_search').attr('value')).to(equal, default_text);
    });

    it("should not switch if there is a value", function() {
      $('#unified_search').attr('value', 'Fred');
      search_blur($('#unified_search'));
      expect($('#unified_search').attr('value')).to(equal, 'Fred');
    });

  });
});
</pre>
<p><strong>How do you run tests?</strong> Two ways. Blue Ridge provides a <code>test:javascripts</code> Rake task that will run all your Javascript tests in the terminal, this is also suitable for including in your continuous integration build, for example. A very nice feature from Screw.Unit is the ability to run tests in browser by simply opening the fixture HTML file in the browser of your choice. As long as your choice isn't Safari, which isn't supported at the moment. The ability to run the tests in console and in browser is very useful.</p>
<p><strong>Any gotchas?</strong> Oy. We had what appeared to be some minor differences between the Rhino implementation that powers the console tests and the browser tests, leading to tests passing in the browser and failing in the console. We weren't quite able to do what amounted to integration tests -- we tried to trigger the JavaScript events so that the jQuery functions tested above were triggered, but couldn't get that to work. You have to be careful that the fixture HTML file actually has all the DOM elements you need, and remember that fixing the actual view doesn't change the fixture. Screw.Unit's error messages on failure aren't as helpful as they might be, there also seemed to be a thing where the fixture DOM wasn't actually being reset between tests, but I'm not 100% sure about that, we wound up working around it.</p>
<p><strong>And in the end?</strong> That said, I did feel better about my JavaScript after having tested it. Fixing the JavaScript code, it was nice to see that other functions hadn't broken. There's a lot to like here, and I'm hoping to get past my initial problems to a tool that will improve the JavaScript parts of my code.</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-testing-first-look-blue-ridge/">Rails Testing First Look: Blue Ridge</a></p>


<p>Related posts:<ol><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><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/08/rails-testing-first-look-blue-ridge/feed/</wfw:commentRss>
		<slash:comments>6</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>To Mock Or Not To Mock</title>
		<link>http://www.pathf.com/blogs/2009/07/to-mock-or-not-to-mock/</link>
		<comments>http://www.pathf.com/blogs/2009/07/to-mock-or-not-to-mock/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 22:55:59 +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>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3220</guid>
		<description><![CDATA[Today, bereft of post ideas, I asked my vast Twitter army (which, if you subtract the bots, probably numbers in the dozens...) for topics, and the leading (not to mention only) vote-getter was "a good rant on mocking vs not-mocking"... Well, I can't promise a good rant, but here goes nothin'
Here's my starting point: Mock [...]<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/to-mock-or-not-to-mock/">To Mock Or Not To Mock</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/05/comparing-ruby-mock-object-libraries/' rel='bookmark' title='Permanent Link: Comparing Ruby Mock Object Libraries'>Comparing Ruby Mock Object Libraries</a></li><li><a href='http://www.pathf.com/blogs/2008/10/walk-through-test-coverage/' rel='bookmark' title='Permanent Link: Walk-Through Test Coverage'>Walk-Through Test Coverage</a></li><li><a href='http://www.pathf.com/blogs/2009/08/using-mocha-for-activerecord-partial-mocks-with-finders/' rel='bookmark' title='Permanent Link: Using Mocha for ActiveRecord Partial Mocks with Finders'>Using Mocha for ActiveRecord Partial Mocks with Finders</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Today, bereft of post ideas, I asked my vast Twitter army (which, if you subtract the bots, probably numbers in the dozens...) for topics, and the leading (not to mention only) vote-getter was "a good rant on mocking vs not-mocking"... Well, I can't promise a <em>good</em> rant, but here goes nothin'</p>
<p>Here's my starting point: Mock objects are best used in the following 2 1/2 situations:<br />
<span id="more-3220"></span>1. To simulate an external object that would otherwise be prohibitive or impossible to use during testing. The classic example is a web service such as PayPal or an OpenId server or something.</p>
<p>2. As a shortcut to setting up a system state that would be difficult or impossible to set up step by step. My favorite example at the moment is Timecop, which is basically a specialized mock object package for setting and freezing the system time.</p>
<p>Here's the half situation:</p>
<p>2 1/2. Sometimes it's appropriate to use a mock object to fake a method call from another layer in the program, for example, mocking out model methods from controller tests. This turns around and bites me roughly half the time I try it.</p>
<p>The situation that I don't like using mocks is the one where you are just trying to isolate the method under test from the rest of the system, in what Martin Fowler called a behavioral test, rather than a state test. In my experience, I regret trying this about 110% percent of the time. I grant that some people really like and are successful with this style.</p>
<p>How do mocks not work for me? Generally, one or more of the following problems.</p>
<p>1. Philosophical. When I'm adding a lot of mocked methods to a test, I can't escape the feeling that the test knows too much about the underlying methods.</p>
<p>2. Practical. Typing in all the mock methods for a method under test that makes a lot of calls can be a real pain in the fingers. This is what turned me off RSpec the first time I tried it -- I felt like I was going so slowly.</p>
<p>3. Maintenance. Inevitably, the underlying API of the models changes, and the mocks have to change to keep up. For me, this has been a bigger maintenance drag than I normally have with tests.</p>
<p>4. Skin deep. One problem with faking a system state with the surface API is that eventually you may need to know about the object in more depth. For example, I recently was testing a message rate limiting system, and mocked just the boolean "can the user send messages" method. Inevitably, I actually needed to check the user's raw message count, which hadn't been set because it was beyond the facade. Essentially, I had to rewrite the entire test.</p>
<p>That's the gist of it -- I'm not a strong mock user by any means, but I do find them very helpful in certain spots. Next week, I'll dig deeper into that message system and talk about how I tested a real feature in practice.</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/to-mock-or-not-to-mock/">To Mock Or Not To Mock</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/05/comparing-ruby-mock-object-libraries/' rel='bookmark' title='Permanent Link: Comparing Ruby Mock Object Libraries'>Comparing Ruby Mock Object Libraries</a></li><li><a href='http://www.pathf.com/blogs/2008/10/walk-through-test-coverage/' rel='bookmark' title='Permanent Link: Walk-Through Test Coverage'>Walk-Through Test Coverage</a></li><li><a href='http://www.pathf.com/blogs/2009/08/using-mocha-for-activerecord-partial-mocks-with-finders/' rel='bookmark' title='Permanent Link: Using Mocha for ActiveRecord Partial Mocks with Finders'>Using Mocha for ActiveRecord Partial Mocks with Finders</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/07/to-mock-or-not-to-mock/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>What&#8217;s In Your Dock: iPhone edition</title>
		<link>http://www.pathf.com/blogs/2009/06/whats-in-your-dock-iphone-edition/</link>
		<comments>http://www.pathf.com/blogs/2009/06/whats-in-your-dock-iphone-edition/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 20:29:21 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone/Mobile]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.pathf.com/blogs/?p=3024</guid>
		<description><![CDATA[It's been a while since I've been desparate enough to had a chance to do a nice "what's in your toolbox" kind of post. In honor of the iPhone 3.0 upgrade, and Steve Jobs' liver, let's do an iPhone-toolbox post.
I'm unabashedly happy with my phone, because it's strengths and weaknesses mesh pretty well with my [...]<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/whats-in-your-dock-iphone-edition/">What&#8217;s In Your Dock: iPhone edition</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/07/developing-iphone-applications-using-ruby-on-rails-and-eclipse-part-3-developing-advanced-views-for-iphone-now-available-on-ibm-developerworks/' rel='bookmark' title='Permanent Link: &#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 3: Developing advanced views for iPhone&#8221; now available on IBM Developerworks'>&#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 3: Developing advanced views for iPhone&#8221; now available on IBM Developerworks</a></li><li><a href='http://www.pathf.com/blogs/2009/08/chiphone-meeting-chicago-iphone-user-group-tdd/' rel='bookmark' title='Permanent Link: Chiphone Meeting: Chicago iPhone user group gets its TDD on'>Chiphone Meeting: Chicago iPhone user group gets its TDD on</a></li><li><a href='http://www.pathf.com/blogs/2008/07/developing-iphone-applications-using-ruby-on-rails-and-eclipse-part-2-displaying-iphone-content-to-the-client-also-up-on-ibm-developerworks/' rel='bookmark' title='Permanent Link: &#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 2: Displaying iPhone content to the client&#8221; Also up on IBM Developerworks'>&#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 2: Displaying iPhone content to the client&#8221; Also up on IBM Developerworks</a></li></ol>]]></description>
			<content:encoded><![CDATA[<p>It's been a while since I've <strike>been desparate enough to</strike> had a chance to do a nice "what's in your toolbox" kind of post. In honor of the iPhone 3.0 upgrade, and Steve Jobs' liver, let's do an iPhone-toolbox post.</p>
<p>I'm unabashedly happy with my phone, because it's strengths and weaknesses mesh pretty well with my actual needs. It's not that great a phone, but I don't use the phone that much. On the other hand, there's never been a better gizmo for whiling away a long train commute.</p>
<p>So, here's some stuff I use:</p>
<h3>Instapaper (free light version, $9.99 pro version currently on sale for $4.99)</h3>
<p>Instapaper has probably changed my web reading habits more than any other app since I started using RSS readers. It's so simple that its almost hard to believe how useful it is. When I come across an article on the web I want to save for later, I click a bookmarklet. Later, launching Instapaper on the phone, the article shows up, with the images stripped away, and the text presented in a reader friendly format. (Sometimes you can help Instapaper out by invoking it from the printer-friendly version of a page...)</p>
<p>Using Instapaper has become kind of second nature -- I always have a few articles ready to go. The Pro version adds a few nice features, including control of the display font and the ability to scroll the article by tilting the phone. The tilt-scroll sounds like you'll need to be a gymnast or something to read an article, but in practice it's a super-clean interface for reading long articles and letting the text scroll at your reading speed. Great app.</p>
<h3>Birdhouse ($3.99)</h3>
<p>Very well designed little app for what seems like a dumb use case -- saving drafts of posts intended for Twitter. I mean, how much do you need to polish that tweet about the ham sandwich you had for lunch, amirite?</p>
<p>But, if you are trying to do a tip a day on Twitter (<a href="http://www.twitter.com/railsrx">@railsrx</a>), then having a nice place to store up ideas for future tips is great. The app also works as a slightly structured note-taking app, since it can email it's existing draft population back to you. </p>
<h3>Stanza / Kindle (Free)</h3>
<p>The two leading general-purpose eBook readers, both of them are easy to use, and manage the task of making text readable on an iPhone. It'd be nice if there was some consistency in formats between the two apps, and also if you could buy books directly from the Kindle App (presumably that's coming).</p>
<h3>MLB At Bat ($9.99)</h3>
<p>Obviously only if you are a baseball fan, but the app gives you access to live box score and play-by-play data, live audio stream of radio broadcast, video highlights, special goodies like condensed game videos a few hours after games and, plus live video streaming on a currently limited basis. That's a lot of stuff. Add in the fact that the app is pretty enough to have won an Apple Design Award, and it's a pretty fabulous package.</p>
<h3>Twitteriffic (Free lite, $3.99 no-ads)</h3>
<p>There are something like a zillion Twitter clients on the iPhone at last count, and which one to pick is basically idiosyncratic. It's a mark of how fast iPhone development is going that Twitteriffic 1.0 won an Apple Design Award in 2008 and was completely blown away by newer clients six months later before regaining strong status with the 2.0 release. I find this has a nice blend of features and interface. (Tweetie, which is my desktop client, is also very good on the iPhone).</p>
<p>Of course, this all sounds serious -- the big winners on the iPhone have all been games, there are all kinds of inexpensive, addictive little games I play. Here are a few: Defender Chronicles, The Creeps, Drop 7, Flight Control, Frenzic, Galcon, Peggle, Strategery.</p>
<p>Related Services: <a href="http://www.pathf.com/services/iphone-application-development/">iPhone Application 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/whats-in-your-dock-iphone-edition/">What&#8217;s In Your Dock: iPhone edition</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/07/developing-iphone-applications-using-ruby-on-rails-and-eclipse-part-3-developing-advanced-views-for-iphone-now-available-on-ibm-developerworks/' rel='bookmark' title='Permanent Link: &#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 3: Developing advanced views for iPhone&#8221; now available on IBM Developerworks'>&#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 3: Developing advanced views for iPhone&#8221; now available on IBM Developerworks</a></li><li><a href='http://www.pathf.com/blogs/2009/08/chiphone-meeting-chicago-iphone-user-group-tdd/' rel='bookmark' title='Permanent Link: Chiphone Meeting: Chicago iPhone user group gets its TDD on'>Chiphone Meeting: Chicago iPhone user group gets its TDD on</a></li><li><a href='http://www.pathf.com/blogs/2008/07/developing-iphone-applications-using-ruby-on-rails-and-eclipse-part-2-displaying-iphone-content-to-the-client-also-up-on-ibm-developerworks/' rel='bookmark' title='Permanent Link: &#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 2: Displaying iPhone content to the client&#8221; Also up on IBM Developerworks'>&#8220;Developing iPhone applications using Ruby on Rails and Eclipse, Part 2: Displaying iPhone content to the client&#8221; Also up on IBM Developerworks</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/06/whats-in-your-dock-iphone-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upcoming Pathfinder Appearances</title>
		<link>http://www.pathf.com/blogs/2009/06/upcoming-pathfinder-appearances/</link>
		<comments>http://www.pathf.com/blogs/2009/06/upcoming-pathfinder-appearances/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 14:14:15 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Pathfinder News]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

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



Windy City Rails is September 12, 2009

Here are a couple of upcoming Ruby and Rails-based appearances by Pathfinder personnel:
On Tuesday, June 23, Noel Rappin (referring to himself in the third person) will be the guest speaker at the Chicago Ruby.org monthly meeting. The meeting starts at 6:00 at Chicago Ruby's downtown loop meeting location, see [...]<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/upcoming-pathfinder-appearances/">Upcoming Pathfinder Appearances</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/2007/11/upcoming-no-flu/' rel='bookmark' title='Permanent Link: Upcoming No Fluff Just Stuff conference'>Upcoming No Fluff Just Stuff conference</a></li><li><a href='http://www.pathf.com/blogs/2009/05/pathfinder-launches-beer-hunter-a-new-flex-ruby-ria/' rel='bookmark' title='Permanent Link: Pathfinder Launches Beer Hunter,  A New Flex + Ruby RIA'>Pathfinder Launches Beer Hunter,  A New Flex + Ruby RIA</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right"><a href="http://www.windycityrails.org"><br />
<img class="right" src="http://windycityrails.org/images/badge_speaker.png" border="0" alt="" /><br />
</a></p>
<p><span class="right" style="font-size: smaller"><br />
<a href="http://www.windycityrails.org">Windy City Rails is September 12, 2009</a><br />
</span></div>
<p>Here are a couple of upcoming Ruby and Rails-based appearances by Pathfinder personnel:</p>
<p>On Tuesday, June 23, Noel Rappin (referring to himself in the third person) will be the guest speaker at <a href="http://www.chicagoruby.org/articles/2009/05/26/rails-test-prescriptions-downtown/">the Chicago Ruby.org monthly meeting</a>. The meeting starts at 6:00 at Chicago Ruby's downtown loop meeting location, see the link for details. The working title of my talk is "I'd Like To Start Testing. Now What?" and it'll be an informal discussion of testing tools and good practice.</p>
<p>The schedule for <a href="http://windycityrails.org/">WindyCityRails</a> was announced this week. The conference is September 12, 2009 at the Westin Chicago River North. <a href="www.pathf.com/blogs/author/john-mccaffrey/">John McCaffrey</a> from Pathfinder will be presenting "Super-easy PDF Generation with Prawn and Prawnto", and I'll be up there with "How To Test Absolutely Anything".</p>
<p>Other speakers include Ryan Singer from 37signals, Ben Scofield from Viget Labs, and Yehuda Katz from Engine Yard.</p>
<p>Registration through August 1st is $99, there are a couple of tutorial sessions also available for purchase.</p>
<p>This was a very well-run regional conference last year, and I'm excited for this year's edition. Hope to 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/06/upcoming-pathfinder-appearances/">Upcoming Pathfinder Appearances</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/2007/11/upcoming-no-flu/' rel='bookmark' title='Permanent Link: Upcoming No Fluff Just Stuff conference'>Upcoming No Fluff Just Stuff conference</a></li><li><a href='http://www.pathf.com/blogs/2009/05/pathfinder-launches-beer-hunter-a-new-flex-ruby-ria/' rel='bookmark' title='Permanent Link: Pathfinder Launches Beer Hunter,  A New Flex + Ruby RIA'>Pathfinder Launches Beer Hunter,  A New Flex + Ruby RIA</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/06/upcoming-pathfinder-appearances/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>Back To The Ruby Mines</title>
		<link>http://www.pathf.com/blogs/2009/06/back-to-the-ruby-mines/</link>
		<comments>http://www.pathf.com/blogs/2009/06/back-to-the-ruby-mines/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 19:33:29 +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>

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





RubyMine


This actually wasn't the post I was planning to write this week, but a couple of days ago I got it in my head to try the latest version of RubyMine, the Ruby and Rails IDE from JetBrains.
Now, I tried this with the beta version back in December, and thought it had a long way [...]<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/back-to-the-ruby-mines/">Back To The Ruby Mines</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/12/trying-out-rubymate/' rel='bookmark' title='Permanent Link: Trying Out RubyMine'>Trying Out RubyMine</a></li><li><a href='http://www.pathf.com/blogs/2008/12/my-ide/' rel='bookmark' title='Permanent Link: My IDE'>My IDE</a></li><li><a href='http://www.pathf.com/blogs/2008/05/ruby-internals/' rel='bookmark' title='Permanent Link: Ruby Internals: Overriding Object.require() to watch files as they are loaded'>Ruby Internals: Overriding Object.require() to watch files as they are loaded</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right">
<a href="http://www.jetbrains.com/ruby/index.html"><br />
<img src="http://www.pathf.com/blogs/wp-content/uploads/2009/06/jetbrains-rubymine-blog.png" alt="" border="0" width="" height="" class="right"/><br />
</a><br />
<br clear="all"/><br />
<span class="right" style="font-size: smaller"><br />
<a href="http://www.jetbrains.com/ruby/index.html">RubyMine</a><br />
</span>
</div>
<p>This actually wasn't the post I was planning to write this week, but a couple of days ago I got it in my head to try the latest version of <a href="http://www.jetbrains.com/ruby/index.html">RubyMine</a>, the Ruby and Rails IDE from JetBrains.</p>
<p>Now, I tried this with the beta version back in December, and <a href="http://www.pathf.com/blogs/2008/12/trying-out-rubymate/">thought it had a long way to go</a>. However, there's been a lot of online chatter about it over the last few months. (Gregg Pollack was particularly enthusiastic in his RailsConf talk), and I thought I'd go back and try again. And I started Twittering about it again, and got some responses, so I thought I'd do a longer write up.</p>
<p>The executive summary is that I started using this on Wednesday and haven't stopped yet. It's come a very long way, and although there are still annoyances, it felt better to me than the other Ruby IDE's. I think it's not quite as solid as my normal TextMate/termial prompt combination, but it's improving rapidly. Overall, this is the first time that JetBrains' Ruby IDE gave me that pleasant "this is like IntelliJ" feeling.</p>
<p>One thing I definitely learned from my years as a happy IntelliJ user back when I wrote more Java code, is that JetBrains releases often, their betas are usually very solid, and they add new stuff really, really rapidly. So my expectations are high that RubyMine will continue to improve.<span id="more-2638"></span>Here are some more specific comments. A lot of these are going to sound negative -- there a many cases where RubyMine has about 85% of the functionality I want, just enough to make me really miss the 15% that's not there:</p>
<h3>Navigating</h3>
<p>File navigation is very nice, one area where RubyMine just blows TextMate away. The fuzzy file search for file names is much crisper, you can click on a symbol to go to its definition, open file tab management is actually sensible. It works very nicely for getting around your project. Also, the search for symbol feature is outstanding.</p>
<p>I've also always loved the navigation bar that shows you the path to the current file.</p>
<h3>Features</h3>
<p>One of my favorite features is local history, so you can go back and check the file against all saved versions locally over the past few days, even if they were not separate checkins to source control. This is amazingly useful, and very easy to use.</p>
<p>The auto-completion is nice, but a little fragmented -- there are four different auto-completion commands, which is probably three too many. A unified approach would probably be better here. (I still miss the TextMate/RubyAMP complete against all open files command).</p>
<p>There's an integrated irb console which is nice -- I'd love to also see a regular command line.</p>
<p>I can't really say much about the git/subversion integration -- I have a long-standing, probably irrational aversion to the JetBrains UI for source control integration, so I stuck with my command line for git.</p>
<p>My all-time favorite JetBrains feature is the help menu item that shows you a whole bunch of JetBrains features and flags ones you haven't used. I browse that from time to time to try and pick up useful tricks.</p>
<h3>Test Support</h3>
<p>	As of RubyMine 1.1, it syntax colors and runs Cucumber files in the IDE, this is very nice.</p>
<p>Although there are commands to bounce between associated model, controller, view, and helper files, there's no way to bounce to the test file for an app file. That's a really annoying oversight. </p>
<p>You can run any file open file from its tab, including tests, which is great. It'd be really great if you could run a test file directly from its associated app file.</p>
<p>All though RSpec files are correctly parsed, and the file structure window lets you browse them, Shoulda files are not, and neither are the Rails tests that use <code>test "do something" do end</code>. </p>
<h3>UI</h3>
<p>A lot of the UI feels a little clunky, over designed, and kind of, dare I say, Java-y.  Examples:</p>
<ul>
<li>
		All the side decoration windows -- project window, test runner, etc, take up a lot of space. It's a problem on a laptop screen because eventually you don't have much room for code. All these windows can be detached, but in the detached state, as far as I can tell, they only float over the main window, they won't act like normal windows. This is a real pain.
		</li>
<li>
		The debugger is nifty, but a little hard to use, I had a little problem creating watches, and inspecting really introspective objects like ActiveRecord models is awkward at best.
		</li>
<li>
		It's the only application I use that has enough menu items that it blocks my system-side menu items on the right. That's annoying.
		</li>
<li>
		Similarly, I think the test result display window could use some polish.
		</li>
<li>
		The preference dialog is really, really complicated.
		</li>
</ul>
<h3>Intelligence</h3>
<p>The live templates and surround with templates are pretty good -- a hair behind what TextMate offers, but still pretty useful.</p>
<p>As nice as the autocompletion is, the warning and code intelligence systems still have a ways to go. Here's a partial list of things that triggered spurious code warnings from the IDE:</p>
<ul>
<li>Any call to a FixtureReplacement create method. I haven't tested on </li>
<li>All RESTful routes</li>
<li>Any call to one of the fixture methods</li>
<li>Dynamic find methods</li>
<li>Anything of the form <code>model.association.select</code></li>
<li>Any call to <code>Timecop.freeze</code> comes up as an error, not a warning.</li>
</ul>
<p>That's a lot of stuff, and it's a lot of stuff I use regularly -- the problem being that having a lot of spurious warnings makes it difficult to recognize a real one. I realize it's a challenge to verify methods that are created dynamically. I'd at least like an option to say "hey, this method is really there", or better, have the IDE say "you just passed a test that covered this warning -- I guess that method is there, I'll shut down the warning. </p>
<p>That said, it does a decent job flagging syntax errors.</p>
<h3>Conclusion</h3>
<p>I've got a tough decision coming up when my demo runs out. Right now, I still think my TextMate workflow is a little more efficient. But give me a few months of RubyMine getting better, and me getting back acquainted with the key shortcuts and what's there -- I dunno. It'd be really close. </p>
<p>Meantime, there's no reason for you not to try the 30-day free trial and use it for a day or two. </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/back-to-the-ruby-mines/">Back To The Ruby Mines</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2008/12/trying-out-rubymate/' rel='bookmark' title='Permanent Link: Trying Out RubyMine'>Trying Out RubyMine</a></li><li><a href='http://www.pathf.com/blogs/2008/12/my-ide/' rel='bookmark' title='Permanent Link: My IDE'>My IDE</a></li><li><a href='http://www.pathf.com/blogs/2008/05/ruby-internals/' rel='bookmark' title='Permanent Link: Ruby Internals: Overriding Object.require() to watch files as they are loaded'>Ruby Internals: Overriding Object.require() to watch files as they are loaded</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/06/back-to-the-ruby-mines/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Comparing Ruby Mock Object Libraries</title>
		<link>http://www.pathf.com/blogs/2009/05/comparing-ruby-mock-object-libraries/</link>
		<comments>http://www.pathf.com/blogs/2009/05/comparing-ruby-mock-object-libraries/#comments</comments>
		<pubDate>Fri, 29 May 2009 18:23: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 Best Practices]]></category>
		<category><![CDATA[rails development]]></category>

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





Masks by exfordy


Continuing on the theme of comparing similar things that I started last week, this week I'll be taking on Mock Object libraries.
The purpose of a mock object library is to allow you to create "fake" objects that can take the place of the regular objects in your application during testing (you'll sometimes see [...]<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/05/comparing-ruby-mock-object-libraries/">Comparing Ruby Mock Object Libraries</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/to-mock-or-not-to-mock/' rel='bookmark' title='Permanent Link: To Mock Or Not To Mock'>To Mock Or Not To Mock</a></li><li><a href='http://www.pathf.com/blogs/2008/05/ruby-internals/' rel='bookmark' title='Permanent Link: Ruby Internals: Overriding Object.require() to watch files as they are loaded'>Ruby Internals: Overriding Object.require() to watch files as they are loaded</a></li><li><a href='http://www.pathf.com/blogs/2009/08/using-mocha-for-activerecord-partial-mocks-with-finders/' rel='bookmark' title='Permanent Link: Using Mocha for ActiveRecord Partial Mocks with Finders'>Using Mocha for ActiveRecord Partial Mocks with Finders</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right">
<a href="http://www.flickr.com/photos/exfordy/128576390/"><br />
<img src="http://farm1.static.flickr.com/1/128576390_8f4a9e9fee_m.jpg" alt="" border="0" width="" height="" class="right"/><br />
</a><br />
<br clear="all"/><br />
<span class="right" style="font-size: smaller"><br />
<a href="http://www.flickr.com/photos/exfordy/128576390/">Masks by exfordy</a><br />
</span>
</div>
<p>Continuing on the theme of comparing similar things that I <a href="http://www.pathf.com/blogs/2009/05/factory-tools-for-fixture-replacement-a-comparison/">started last week</a>, this week I'll be taking on Mock Object libraries.</p>
<p>The purpose of a mock object library is to allow you to create "fake" objects that can take the place of the regular objects in your application during testing (you'll sometimes see them called "test doubles", by analogy with a stunt double, another kind of stand-in).</p>
<p>There are a several reasons why you might want to use a test double in your tests, the two most common are probably these:</p>
<ul>
<li>To take the place of a hard to create or expensive to access object or method call, such as a web services call. Using the test double lets the test system pretend that the expensive object is there, but at a much lower time cost.</li>
<li>To isolate an object being tested from the details of the rest of the system. In Rails, for example, a controller test might create test doubles for methods in the model so that the controller test can pass or fail separately from whether the model implementation is correct.</li>
</ul>
<p>Ruby's open object model and duck-typing makes creating test double objects relatively easy compared to stricter languages like Java. There are four major mock objects packages in Ruby:</p>
<ol>
<li><a href="http://flexmock.rubyforge.org/">FlexMock</a> is the original Ruby mock object package</li>
<li><a href="http://github.com/floehopper/mocha/tree/master">Mocha</a> is quasi-official in that the Rails team uses it for their tests.</li>
<li><a href="http://rspec.info/documentation/mocks/">RSpec</a> defines its own mock package</li>
<li><a href="http://github.com/btakita/rr/tree/master">RR</a>is the newest entry, with shorter syntax and a couple of new features</li>
</ol>
<p>Here's a tour of what each package looks like, and when you might use each feature.</p>
<div style="border: thin solid blue; padding: 5px">
	<strong>Self-promotion alert:</strong> More details about mocks, stubs, test doubles, 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, 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.
</div>
<p><span id="more-2557"></span>Before we start, some important points:</p>
<ul>
<li>This is in no way a comprehensive look at any of these libraries.</li>
<li>Some of these libraries have advanced or other features that don't really map to anything the other ones do (especially RR), check the full docs for each package for full info.</li>
</ul>
<p>The first step is installing and integrating with Test::Unit. The RSpec mocks, of course, can't be integrated with Test::Unit, however, any of the other packages can be integrated with RSpec by adding the line <code>config.mock_with :rr</code> or :flexmock, or :mocha in the spec_helper.rb file. </p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Installation with Test::Unit<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code>sudo gem install flexmock</code><br />
			<br/><br />
			Then, in test_helper.rb:<br/><br />
			<code>require 'flexmock/test_unit'</code>
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			<code>sudo gem install mocha</code><br/><br />
			Then, in test_helper.rb:<br/><br />
			<code>require 'mocha'</code>
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			<code>sudo gem install rr</code><br />
			<br/><br />
			Then, inside the test case declaration in test_helper.rb:<br/><br />
			<code>include RR::Adapters::TestUnit</code>
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			N/A
		</td>
</tr>
</table>
<p><br/></p>
<p>The most basic thing any of these packages can do is create a single dummy object that you can specify one or more methods with return values. When those methods are called, the specified values are returned. If the methods are not called, nothing happens. In general, once these objects are created, they are treated exactly the same as pre-existing objects, and all the later filters and expectation methods apply.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Creating a simple test double with a stubbed method<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code><br />
				mock = flexmock("name", :method => result)<br/><br />
			</code>
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			<code>object = stub(:method => result)</code><br />
			<br/><br />
			Methods can also be specified in a block, using the <code>stubs</code> as below.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			<code>double = stub!.method { value }</code><br/><br />
			Which is a shortcut for<br/><br />
			<code>double = stub(Object.new).method { value }</code>
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			double = stub("name", :method => value)
		</td>
</tr>
</table>
<p><br/><br />
Most of the time, though, you'll want to replace methods on existing objects. In Flexmock and RR, this involves calling a special method with the object as an argument, as in Flexmock's <code>flexmock(object)</code>, while in Mocha and RSPec, this involves calling a method on the object, as in <code>object.stubs</code>. In either case, further information about the method being stubbed and its return value is usually chained after the declaration of the stub.</p>
<p>Remember, classes are just another kind of object in Ruby, so class methods can be treated like any other method <code>stub(User).should_receive(:find)</code>.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Creating a test double from a real object<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code>mock = flexmock(project)</code><br />
			<br/><br />
			If the object is a string or symbol, then to prevent a confusion with the simple test double, use <code>mock = flexmock(:base, object)</code>. Also, <code>mock = flexmock(:safe, project)</code> does not add extra methods to the existing object -- this must be called with any expectations defined in an attached block.<br/><br />
			To set return values:</br><br />
			<code><br />
				mock.should_receive(:method).and_return(value)<br />
			</code><br />
			Also<br/><br />
			<code><br />
				mock = flexmock("name") { |m| m.should_receive(:method).and_return(value) }</code><br/><br />
			<br/><br />
			Shortcuts: <br/><br />
			<code><br />
				mock = flexmock("name", :method => value)<br/><br />
				mock = flexmock("name").should_receive(:method => value)<br />
			</code><br />
			<br/><br />
			Other:<br/><br />
			<code>and_raise(exception)</code> can be used.<br />
			Multiple values in the <code>and_return</code> method will be returned one at a time for each call. The last value will be repeated over and over, if needed. Also <code>and_return</code> can take a block, but this is not recommended.
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			<code>project.stubs(:method).returns(value)</code><br/><br />
			Or<br/><br />
			<code>project.stubs(:method, value)</code><br />
			To specify errors, use <code>raises(exception)</code> instead of <code>returns</code>. Multiple values in the returns method are as flexmock, and can also be written <code>returns(1).then.returns(2)</code>.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			<code>stub(project).method { value }</code><br />
			<br/> is equivalent to <br />
			<code>stub(project).method.returns(value)</code>
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			<code>project.stub!(method).and_return(1)</code><br/><br />
			<code>and_return</code> can also take a block, or a list of values, which is treated as Mocha or FlexMock. Use <code>and_raise</code> to raise an error.
		</td>
</tr>
</table>
<p><br/><br />
All these packages allow you to set an expectation that the method being replaced will actually be called one or more times. This is typically called a <strong>mock</strong>, as opposed to a stub. If a method is set up with an expectation that it will be called, then if that method is not called during the test, the test will fail.</p>
<p>The biggest difference here is that FlexMock does not have a separate syntax for creating objects with expectations, any doubled object can have an expectation added by appending a method like <code>once</code> to the description chain. In Mocha, RR, and RSpec, test doubles that will have expectations must be declared as such, using <code>mock</code> or (in Mocha) <code>expects</code>. In those libraries, specifying an method with <code>mock</code> implicitly assumes that the method will be called exactly once. </p>
<p>Each library offers options to change the expected number of times a method will be called.</p>
<p>RR has this unique feature called a proxy, where the method is actually called (as opposed to the return value being set by RR), but you can still specify an expectation on how many times the method is called.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Set an expectation for number of times called<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code>mock.should_recieve(:method).and_return(value).once</code><br/><br />
			Other options include: zero_or_more_times, twice, never, times(n). Can also do <code>at_least.once</code> or <code>at_most.twice</code>.
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			Bare mock objects are just like bare stub objects, except all methods are expected to be called once<br/><br />
			<code>mock = mock()</code><br/><br />
			Existing objects use <code>expects</code><br/><br />
			<code>project.expects(:method)</code><br/><br />
			The default is exactly one call, equal to <code>project.expects(:method).once</code>. Other options include: twice, at_least_once, at_most_once, at_least(x), at_most(x), times(x), times(x..y), never.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			This sets an expectation for a single call: <br/><br />
			<code>mock(project).method { value }</code><br/><br />
			To set an expectation for no calls:<br/><br />
			<code>do_not_call(project).method</code><br/><br />
			To set an expectation for a different number of calls:<br/><br />
			<code>mock(project).method.times(n) { value } </code><br/><br />
			RR also has the concept of a proxy, which is like a mock, but it actually calls the method. You can set an expectation that the method is called, and specify a block to filter the output.<br/><br />
			<code><br />
			  mock.proxy(project).method { |actual| "#{actual}_mocked" }<br />
                </code>
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			The default expectation is that the method will be called once<br />
			<code>project.should_recieve(:method).and_return(1)</code><br/><br />
			If the method should never be called: <br/><br />
			<code>project.should_not_recieve(:method)</code><br/><br />
			Other method count expectations can be set with once, twice, exactly(n).times, at_least.once, at_least(n).times, at_most.once, at_most(n).times, any_number_of_times.
		</td>
</tr>
</table>
<p><br/><br />
All four libraries offer similar syntax for specifying arguments that must match for the doubled method to be invoked. This allows you to specify different return values based on the arguments. For example, you could specify multiple stubs of the find method, each returning a different model object. In addition to matching based on the exact value of the arguments, each library offers some more generic matchers based on class, or matching a regular expression or whatnot.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Filtering methods by arguments<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code>mock.should_recieve(:method).with("a")</code><br/><br />
			Also <code>with_any_args</code>, <code>with_no_args</code>. If the argument to <code>with</code> is a class, then any instance of the class matches. If it's a regex, then any string matching the regex matches. There is also a mechanism for more complex logic.
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			For a stub or a mock:<br/><br />
			<code>project.expects(:method).with(1)</code><br />
			<br/><br />
			If <code>with</code> is passed a block, then the method matches if the block returns true. Several other matchers including instance_of, Not, any_of, and regexp_matchers.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			Just set the arguments to the method when defined:<br/><br />
			<code>mock(project).method(1) { value }</code><br/><br />
			There are special matchers that can be placed as an argument, including anything, is_a, numeric, boolean, duck_type. You can also put in a range or a regular expression.
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			<code>project.should_recieve(:method).with(1)</code><br/><br />
			Other filters include, anything, any_instance_of, hash_including,<br />
			boolean, duck_type(:message), or a regular expression.
		</td>
</tr>
</table>
<p>I said a little bit ago that classes can be doubled just like any other object. Three of the libraries also have special syntax that allow you to specify stub or mock behavior for any instance of the class that is created subsequently to that declaration. (Be careful, instances of the class previously created will not have the double behavior). Typically, after the method declares that this double applies to all new instances, any other filter or expectation can be applied. </p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Create doubles for all instances of a class<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code>flexmock(Project).new_instances.should_recieve(:save => false)</code><br/><br />
			After, <code>new_instances</code> any expectation can be written.
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			<code>Project.any_instance.expects.save.returns(false)</code><br/>
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			<code>mock.instance_of(Project).save(false)</code>
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			N/A? The work around is something like this:< br/><br />
			<code><br />
				Project.stub!(:find).and_return(mock_model(Project, :update_attributes => false))</code>
		</td>
</tr>
</table>
<p><br/><br />
A couple of the libraries offer special features for ActiveRecord.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		ActiveRecord specific mocks<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
			<code>flexmock(:model, Project)</code><br />
			<br/>After that, as normal, but id, to_params, new_record?, errors, is_a?, instance_of?, kind_of?, and class are already stubbed.
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			N/A
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			N/A
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			With the rspec-rails plugin:<br/><br />
			<code>mock_model(Project, :method => value)</code> <br/><br />
			Stubs id, to_param, new_record?, and errors.
		</td>
</tr>
</table>
<p><br/><br />
Also, and this is a little more advanced, some of the libraries offer the ability to set a stub or mock on an entire chain of method calls in one line, without having to explicitly set the intermediate mock object.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Replacing a chain of method calls<br />
     </strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Flexmock</strong></td>
<td>
		  <code><br />
			flexmock(project).should_receive("project.leader.address.city")<br />
		  </code><br/><br />
		 Then as any other mock.
		</td>
</tr>
<tr>
<td><strong>Mocha</strong></td>
<td>
			N/A
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>RR</strong></td>
<td>
			<code>stub(project).leader.stub!.address.stub!.city { "Chicago" }
		</td>
</tr>
<tr>
<td><strong>RSpec</strong></td>
<td>
			<code><br />
				stub_chain(project.leader.address.city).and_return("Chicago")			</code>
		</td>
</tr>
</table>
<h3>Conclusions</h3>
<p>I sure hope that made sense, I find the terminology surrounding mock objects to be hopelessly and needlessly confusing. Please discuss confusion in the comments, and I'll change the text as needed.</p>
<p>All of these tools are very solid, flexible, and providing functionality above and beyond what you are likely to need in your testing. I think it's perfectly reasonable to make a choice based on liking a particular syntax or needing one particular feature.</p>
<p>I've personally used FlexMock the most, but recently switched to Mocha on the theory that it was almost a Rails default. I think RR is very cool in concept, but I've found it hard to get used to in practice, it's almost too succinct. </p>
<p>Related Services:<br />
<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/05/comparing-ruby-mock-object-libraries/">Comparing Ruby Mock Object Libraries</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/07/to-mock-or-not-to-mock/' rel='bookmark' title='Permanent Link: To Mock Or Not To Mock'>To Mock Or Not To Mock</a></li><li><a href='http://www.pathf.com/blogs/2008/05/ruby-internals/' rel='bookmark' title='Permanent Link: Ruby Internals: Overriding Object.require() to watch files as they are loaded'>Ruby Internals: Overriding Object.require() to watch files as they are loaded</a></li><li><a href='http://www.pathf.com/blogs/2009/08/using-mocha-for-activerecord-partial-mocks-with-finders/' rel='bookmark' title='Permanent Link: Using Mocha for ActiveRecord Partial Mocks with Finders'>Using Mocha for ActiveRecord Partial Mocks with Finders</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/05/comparing-ruby-mock-object-libraries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Factory tools for fixture replacement: a comparison</title>
		<link>http://www.pathf.com/blogs/2009/05/factory-tools-for-fixture-replacement-a-comparison/</link>
		<comments>http://www.pathf.com/blogs/2009/05/factory-tools-for-fixture-replacement-a-comparison/#comments</comments>
		<pubDate>Fri, 22 May 2009 16:49:15 +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>

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





Assembly line picture by harry_nl


Continuing on the general theme of blog posts that people actually asked me to do... this week, I'll be taking a comparative look at fixture replacement tools. The general request was to have one place that compared the features of the various libraries so that a prospective fixture replacer might make [...]<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/05/factory-tools-for-fixture-replacement-a-comparison/">Factory tools for fixture replacement: a comparison</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/02/review-of-fixture_replacement2-plugin/' rel='bookmark' title='Permanent Link: Review of fixture_replacement2 plugin &#8211; Update'>Review of fixture_replacement2 plugin &#8211; Update</a></li><li><a href='http://www.pathf.com/blogs/2009/06/chicagoruby-meeting-test-prescriptions-recap/' rel='bookmark' title='Permanent Link: ChicagoRuby meeting &#8216;Test Prescriptions&#8217; recap'>ChicagoRuby meeting &#8216;Test Prescriptions&#8217; recap</a></li><li><a href='http://www.pathf.com/blogs/2007/11/live-ruby-testb-2/' rel='bookmark' title='Permanent Link: Live Ruby: Testbed, part 1'>Live Ruby: Testbed, part 1</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right">
<a href="http://www.flickr.com/photos/harry_nl/3030267182/"><br />
<img src="http://farm4.static.flickr.com/3018/3030267182_701b2ae939_m.jpg" alt="" border="0" width="" height="" class="right"/><br />
</a><br />
<br clear="all"/><br />
<span class="right" style="font-size: smaller"><br />
<a href="http://www.flickr.com/photos/harry_nl/3030267182/">Assembly line picture by harry_nl</a><br />
</span>
</div>
<p>Continuing on the general theme of blog posts that people actually asked me to do... this week, I'll be taking a comparative look at fixture replacement tools. The general request was to have one place that compared the features of the various libraries so that a prospective fixture replacer might make a more informed choice.</p>
<p>So here goes, I'll try to keep the editorializing to a minimum, but no promises.</p>
<p>Fixture replacement or factory tools replace the global nature of Rails fixture data with the ability to easily create new objects based on sample valid data previously defined by the developer. Factory tools have several advantages, including keeping each test independent of other tests, since you are no longer using global fixtures, and allowing the important data for each test to be defined in that test.</p>
<p><strong>Updated to correct some errors caught in the first few comments.</strong></p>
<p>Self-promotion alert: A full description of why to use fixture replacements and an in-depth look at one of these tools is available in the full version of <a href="http://www.railsrx.com">Rails Test Prescriptions</a> available wherever fine PDF books are sold as long as you think the only place fine PDF books are sold is <a href="http://www.railsrx.com">http://www.railsrx.com</a>.<br />
<span id="more-2506"></span><br />
<h3>The competitors</h3>
<p>As I write this, there seem to be four factory tools that have some user base:</p>
<ul>
<li><a href="http://github.com/thoughtbot/factory_girl/tree/master">Factory Girl</a>, from Thoughtbot, at version 1.2.1 right now</li>
<li><a href="http://replacefixtures.rubyforge.org/">Fixture Replacement</a>, by Scott Taylor, version 2.1</li>
<li><a href="http://github.com/technoweenie/machinist/tree/master">Machinist</a>, from Pete Yandell, currently at version 0.3.1</li>
<li><a href="http://github.com/flogic/object_daddy/tree/master">Object Daddy</a>, by Rick Bradley and Yossef Medelssohn, currently at version 0.4.1</li>
</ul>
<p>Each of these tools has subtle or more advanced features that are outside of the scope of this quick guide -- be sure and check out the tools that look appealing to you.</p>
<h3>Defining Factories</h3>
<p>The basic structure of each of these tools is similar. You create a file made up of factories, each of which defines the basic data for a model. First, let's discuss that file. Each tool places it in a different location.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong>Location of factory data</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>Autoloaded if in: test/factories.rb or spec/factories.rb or test/factories/*.rb or spec/factories/*.rb, otherwise manually loaded.</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>db/example_data.rb, automatically loaded by module. Also,  code in that file must be declared inside module FixtureReplacement. Commentator says that factories can be defined inline in your tests as well, but I don't see docs for that feature.</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>test/blueprints.rb, by convention, but could probably go anywhere.</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>Typically, in /spec/examplars/model_exemplar.rb. Object Daddy puts the factories inside the ActiveRecord model class definition, so this is a place that monkey patches the model and will be auto loaded during testing, however the data can be placed in the actual definition in app/models. </td>
</tr>
</table>
<p><br/><br />
Just as a note, my personal preference here is to keep the tools in the test directory -- the placement for FixtureReplacement in the db directory bugs me. Object Daddy is the only tool that doesn't expect the factories to be defined outside the model.</p>
<p>Within the factory file, the general idea is that multiple blocks are defined, one to each model, more or less. This table contains the syntax for creating a block -- we'll cover what goes inside that block in a moment. Let's assume here a model called Project</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Creating an individual factory<br />
	</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>
<div>To define a factory matching a model name:</div>
<p>			<code>Factory.define :project do |p| ... end</code><br />
			<br/></p>
<div id="" class="">Or, to define a factory and assign it to an<br />
				arbitrary class:
			</div>
<p>			<code><br />
				Factory.define :active_project, :class => Project do |p| ... end<br />
			</code>
		</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>
			<code><br />
				attributes_for :project do |p| ... end<br />
			</code>
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>
			<code><br />
				Project.blueprint do end<br />
			</code><br />
			<br/></p>
<div>For a blueprint with a label:</div>
<p>			<code><br />
				Project.blueprint(:active) do end<br />
			</code>
		</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>N/A. Since Object Daddy puts the generators in the actual ActiveRecord model class, it doesn't need an explicit block.</td>
</tr>
</table>
<p><br/><br />
There's a slight difference in structure here. Since Factory Girl and Fixture Replacement are essentially defined in their own namespaces, the factory blocks take a single argument, which is the model being created. Machinist adds a class method to ActiveRecord base, so it doesn't need that argument -- the block will be evaluated inside the class that the blueprint method is called on.</p>
<h3>Defining Attribute Defaults</h3>
<p>Within each factory block, individual attributes can have default values specified. Typically these are either static values, or random values (the Faker gem is very helpful here). Each tool has a slightly different syntax for defining basic attribute defaults. </p>
<p>Unless otherwise specified, these lines defining the defaults would go inside the factory blocks listed above. Also, unless otherwise specified, you can do other arbitrary code inside the factory definition to calculate any intermediate values you want.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Default attribute data<br />
	</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>
<div>For static defaults:</div>
<p>			<code>p.name 'Test Project'</code><br />
			<br/></p>
<div>For dynamic defaults</div>
<p>			<code>p.name { some_dynamic_code }</code><br />
			<br/></p>
<div>Attributes can depend on earlier defined ones, if the block takes an argument</div>
<p>			<code><br />
			 	p.long_name { Faker::Company.name }<br/><br />
				p.short_name { |a| a.long_name[0, 2] }<br />
			</code>
		</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>
			<code>p.name = "Test Data"</code><br />
			<br/></p>
<div>The right hand side can be an arbitrary expression, and can, I think, reference previously defined attributes.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>
			Static data is declared simply:<br />
			<code>name "Test Data"</code><br />
			<br/></p>
<div>Dynamic data can take a block</div>
<p>			<code>name { "Test Data" }</code><br />
			<br/><br />
			Previously defined attributes can be referenced. All dynamic random data should be described in a Sham, see next section.
		</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>
<div>Inside the active record model, four forms.</div>
<p>			<code>generator_for :name, "Test Name"</code><br />
			<br/><br />
			<code>generator_for :name do "Test Name" end</code><br />
			<br/><br />
			<code>generator_for :name, :method => :fake_name</code><br />
			<br/><br />
			<code>generator_for :name, :class => NameGenerator</code><br />
			<br/><br />
			See next section for how to use these in sequence.
		</td>
</tr>
</table>
<p><br/><br />
Some slight difference here between Fixture Replacement's use of an assignment statement, Machinist using a method that takes a block, and FactoryGirl using a method that takes a value or a block. Object Data does everything a little differently</p>
<h3>Defining Sequences of data</h3>
<p>One nice feature of these factory tools is the ability to create sequences of related non-repeating data, whether that's just calling projects "Test 1", "Test 2" and so on, or a more complex sequence. Here is how to define a data sequence in each tool. Note that even though these examples take an index and are sequential, they can also be used with just random data.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Defining sequences<br />
	</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>
<div>Outside the define block</div>
<p>			<code><br />
				Factory.sequence :name do |n| "Test Project #{n}" end			</code><br />
			<br/></p>
<div>Inside the define block:</div>
<p>			<code>p.name { Factory.next(:name) }
		</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>No explicit support, but does define a 'random_string' method</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>
<div>Outside the blueprint block</div>
<p>			<code>Sham.name { |index| "Test Project #{index}" }</code></p>
<div>Inside the blueprint index</div>
<p>			<code>name { Sham.name }</code></p>
<div>But, if the Sham and the attribute have the same name, this can<br />
				be written as just</div>
<p>			<code>name</code><br />
			<br/><br />
			And Machinist will make the right connection
		</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>
			The generator_for method takes a :start option to define the initial value of the sequence. The block and method versions take an optional argument, prev, which is the previous value of the sequence which can be used to generate the next value. The class version can maintain it's own sequence, as long the class provides a 'next' method.
		</td>
</tr>
</table>
<p><br/></p>
<h3>Defining Associations</h3>
<p>A factory also allows you to define default associations with dependent objects. This isn't always what you want -- my experience is that you are frequently better off specifying the associations in the actual test. For the purposes of the example, let's assume that the Project belongs to a Client, and again, all this code is in the block defining the example, unless otherwise specified. These also assume that there is a separate factory definition for Client.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Support for associations<br />
	</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>
			<code>p.client { |a| a.association(:client) }</code><br />
			<br/></p>
<div>Which can be abbreviated:</div>
<p>			<code>p.association :client</code><br />
			<br/><br />
			In each case, extra arguments are treated as overrides to the default<br />
			data of the other object.
		</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>
			<code>p.client = default_client</code><br />
			<br/><br />
			Additional arguments to the method are treated as overrides.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>
			<code>client { Client.make } </code><br />
			<br/></p>
<div>Again, additional arguments can be specified as overrides. If the attribute and the blueprint have the same name, this can be shortened to:</div>
<p>			<code>client</code>
		</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>
			A belongs_to association is automatically created (by calling generate on the associated class) when needed.
		</td>
</tr>
</table>
<p><br/></p>
<p>Also note that has_many style relationships can not be created directly in any of these tools, because ActiveRecord needs the object to be saved first. These relationships need to be created in the actual test.</p>
<h3>Creating Instances</h3>
<p>Having spent all this time defining attributes, you are probably going to want to actually declare some in your tests.</p>
<p>First, you actually need to include or require some things to allow your tests to be aware of the factory replacement tool.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Steps needed to load factory data<br />
	</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>No further steps once installed, unless you want to include a factory file from a non-standard location</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>
			In Test::Unit, Test::Unit::TestCase must <code>include FixtureReplcement</code>. In RSpec, the Spec::Runner.configure block must have the line <code>config.include FixtureReplacement<code>
		 </td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>
			The blueprint file must be required in test_helper.rb or spec_helper.rb. You must add a setup or before block called before each test containing the line <code>Sham.reset</code>
		</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>No further steps once installed, unless you include generator files in a non-standard location.</td>
</tr>
</table>
<p><br/></p>
<p>Then you need to actually write the lines in your test that will create your data.</p>
<p>In general, all these methods allow you to override the defined default values by passing them as key/value attributes to the method creating the object. In general, this works for attributes as well as associations. The examples below will show creating the object with the name field overridden, just to give a sense of the syntax. Some of the tools have different options depending on whether you want the object saved to the database or not.</p>
<table border="10"  cellspacing="5" cellpadding="5">
<tr>
<th colspan="2" style="text-align: center"><strong><br />
		Steps needed to load factory data<br />
	</strong></th>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Factory Girl</strong></td>
<td>
			Create and save:<br />
			<code>Factory.build(:project, :name => "New Project")</code><br/><br />
			Create, don't save: <code>Factory.create(:project, :name => "New Project")</code><br/><br />
			Create as as series of stubs: 				<code>Factory.stub(:project, :name => "New Project")</code><br/><br />
			Return the attributes as a hash:<br />
			<code>Factory.attributes_for(:project, :name => "New Project")</code><br/>
		</td>
</tr>
<tr>
<td><strong>Fixture Replacement</strong></td>
<td>
			Create and save: <code>create_project(:name => "New Project")</code><br/><br />
			Create and don't save: <code>new_project(:name => "New Project")</code><br/><br />
			Already saw "default_project" for creation as a dependent object.
		</td>
</tr>
<tr style="background-color: #cccccc">
<td><strong>Machinist</strong></td>
<td>
			Create and save: <code>Project.make(:name => "New Project")</code><br/><br />
			Create and don't save: <code>Project.make_unsaved(:name => "New Project")</code><br/><br />
			Return the attributes as a hash: <code>Project.plan(:name => "New Project")</code><br/><br />
			Named blueprints can be invoked by having the name be the first argument to any of the above methods. <code>Project.make(:active)</code>
		</td>
</tr>
<tr>
<td><strong>Object Daddy</strong></td>
<td>
			Create and save: <code>Project.generate(:name => "New Project")</code><br/><br />
			Create and save, but raise exception if invalid: <code>Project.generate!(:name => "New Project")</code><br/><br />
			Create and don't save: <code>Project.spawn(:name => "New Project")</code><br/>
		</td>
</tr>
</table>
<p><br/></p>
<p>To me the biggest difference here is that Object Daddy and Machinist call new class methods of the actual class, while Fixture Replacement creates methods of Test::Unit, and Factory Girl uses its own object.</p>
<h3>And In Conclusion, I'm Done</h3>
<p>That's a quick look at the available tools for using factories to replace fixtures. I've had personal success using Fixture Replacement, Factory Girl, and Machinist -- I haven't had a chance to use Object Daddy yet. I slightly prefer Machinist, but not by enough that you should take that seriously if one of the others looks good to you. (I should mention that Factory girl will allow you to use some of the syntax from the other tools if you've taken a liking to it). </p>
<p>The biggest thing to remember when using these tools is to avoid setting up large amounts of data for each test -- that'll slow things down a bit. Instead, you want focused unit tests that create a minimal amount of data for each test.<br />
<br/></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/05/factory-tools-for-fixture-replacement-a-comparison/">Factory tools for fixture replacement: a comparison</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/02/review-of-fixture_replacement2-plugin/' rel='bookmark' title='Permanent Link: Review of fixture_replacement2 plugin &#8211; Update'>Review of fixture_replacement2 plugin &#8211; Update</a></li><li><a href='http://www.pathf.com/blogs/2009/06/chicagoruby-meeting-test-prescriptions-recap/' rel='bookmark' title='Permanent Link: ChicagoRuby meeting &#8216;Test Prescriptions&#8217; recap'>ChicagoRuby meeting &#8216;Test Prescriptions&#8217; recap</a></li><li><a href='http://www.pathf.com/blogs/2007/11/live-ruby-testb-2/' rel='bookmark' title='Permanent Link: Live Ruby: Testbed, part 1'>Live Ruby: Testbed, part 1</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/05/factory-tools-for-fixture-replacement-a-comparison/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Rails Testing Frequently Asked Questions &#8212; The Non-Code Version</title>
		<link>http://www.pathf.com/blogs/2009/05/rails-testing-frequently-asked-questions-the-non-code-version/</link>
		<comments>http://www.pathf.com/blogs/2009/05/rails-testing-frequently-asked-questions-the-non-code-version/#comments</comments>
		<pubDate>Fri, 15 May 2009 17:50:03 +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>

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




Test-Taking Robot picture by slavin fpo

Between my sessions at RailsConf, and the book promotion at Ruby Learning I've been fielding a lot of questions about Test-Driven Development and Rails. Here are five of the most common general questions.
Self promotional note: many of these questions and more are covered in detail in Rails Test Prescriptions, only [...]<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/05/rails-testing-frequently-asked-questions-the-non-code-version/">Rails Testing Frequently Asked Questions &#8212; The Non-Code Version</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/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/09/ask-a-rails-tester-person/' rel='bookmark' title='Permanent Link: Ask A Rails Tester Person'>Ask A Rails Tester Person</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right">
<a href=""><br />
<img src="http://farm3.static.flickr.com/2038/2164395741_590ce74e6a_m.jpg" alt="" border="0" class="right"/><br />
</a><br />
<br clear="all"/><br />
<a href="http://www.flickr.com/photos/slavin_fpo/2164395741/sizes/s/in/photostream/">Test-Taking Robot picture by slavin fpo</a>
</div>
<p>Between my sessions at RailsConf, and the <a href="http://rubylearning.org/class/mod/forum/view.php?id=1237">book promotion at Ruby Learning</a> I've been fielding a lot of questions about Test-Driven Development and Rails. Here are five of the most common general questions.</p>
<p>Self promotional note: many of these questions and more are covered in detail in <a href="http://www.railsrx.com">Rails Test Prescriptions</a>, only $9 dollars for a book that covers all kinds of testing topics...<br />
<span id="more-2453"></span><br />
<h3>What test tools should I use? Should I use RSpec?</h3>
<p>This is, I think, an increasingly common question as the number of available Rails testing tools increases. Most of these tools were created to fill specific needs that were unserved by the Test::Unit and fixture tools provided as the default by Rails.</p>
<p>The important thing is not to get hung up on finding the absolute best test stack before you start -- for one thing, you won't know which tools are best for you until you get going. For another, the big frameworks don't have all that much functional difference any more.</p>
<p>If you are new to testing in Rails, I recommend you start with the default stack -- it's easiest to install, simplest to use, and has the most documentation. Eventually, you will discover the same limits that led people to move to new tools. </p>
<p>At that point, if you start hitting the limitations of fixtures, you can move to FactoryGirl or Machinist. If you start wanting groups of tests with the same setup, you can add Shoulda or Matchy. If you want mock objects, you have choices. You can also go to RSpec to get most of these features as well. But you'll get the most out of the extension tools if you come to them from a position of genuine need rather than a position of "all the cool kids are using this".</p>
<h3>I have an entire app with no tests, what should I do now?</h3>
<p>Start your TDD process on new features immediately. Don't worry so much about going back and fixing the rest of the program in one fell swoop -- it'll wind up being a huge time sink and the risk of adding errors is high. (This advice also applies if you have tests, but think you can do better now...)</p>
<p>Do start using TDD on new code. Also add tests to cover any reported bugs, this will help you build up coverage throughout the program. Use mock objects to keep the part of the code you are testing separate from the untested parts.</p>
<p>If you want to get some coverage on the legacy parts of the code, try using a more black-box tool like Rails integration tests or Cucumber to try and verify high-level features from the level of user interaction. Since these tests aren't as dependent on the structure of the code, they may be easier to manage.</p>
<h3>Why should I test? Won't I still need human testers?</h3>
<p>Test-Driven Development is not a substitute for human acceptance testing or review by a domain expert. Just because the tests pass is no proof that the tests are testing the right functionality.</p>
<p>However, TDD has a lot of benefits. Code written using TDD tends to be simpler, easier to manage, and easier to debug and maintain going forward. I develop much more quickly using tests then when I am not writing tests. This is in part, but only in part, because I execute the code in the browser less frequently. It's also because the TDD process focuses my activity efficiently. A program written with tests also has a lot of protection against introducing bugs or breakage in later development.</p>
<h3>When should I test? Is there such a thing as too much testing?</h3>
<p>You can always overdo a good thing, and it's certainly possible to spend time writing tests beyond the point where you are getting much benefit from it. I think that most of the code and developers I see are, to put it mildly, not near that point.</p>
<p>My feeling is that you should test any code whose correctness matters to you. Sometimes, the correctness doesn't matter -- you know it's a one-off script, or you are just experimenting, or who knows what. <strong>Added</strong>Sometimes it's genuinely the case that it's not worth the time to add a test for some weird corner case or something.</p>
<p><strong>EDITDED SLIGHTLY</strong><br />
Remember, though, when you do write tests, it's much easier to write the tests first. Easier to write the tests, easier to write the code.</p>
<h3>I don't know what to test. How do I start?</h3>
<p>The great part about TDD is that it doesn't matter all that much where you start. So pick one specific thing about your program that you know it needs to do. You can start at the controller level: "When the activate controller method is called, the user is activated", or at the model "The user model updates when it's activate method is called" or at the user level "When the admin clicks the activate check box, then the associated user can log in". Some of those are higher-level then others, but all of those will lead you in the direction of the other ones as you move forward.</p>
<p>Things to keep in mind.</p>
<ul>
<li>No matter where you start, start with one simple test. One assertion, if you can manage it.</li>
<li>Write the code to make that test pass</li>
<li>Then refactor -- this part is critical, this is where the creative design is with a TDD process.</li>
<li>Then write the next test.</li>
<li>In Rails, you'll often start in the controller then realize that code needs to be written in the model (or vice-versa). Write a separate test for the model -- testing models from the controller makes it hard to test all the model logic.</li>
<li>It's okay to plan the tests in advance, but you should only work on one test at a time. (Sometimes I'll write the series of tests, then comment out all but one)</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/05/rails-testing-frequently-asked-questions-the-non-code-version/">Rails Testing Frequently Asked Questions &#8212; The Non-Code Version</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/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/09/ask-a-rails-tester-person/' rel='bookmark' title='Permanent Link: Ask A Rails Tester Person'>Ask A Rails Tester Person</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/05/rails-testing-frequently-asked-questions-the-non-code-version/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>RailsConf &#8216;09: After the RailsConfening</title>
		<link>http://www.pathf.com/blogs/2009/05/railsconf-09-after-the-railsconfening/</link>
		<comments>http://www.pathf.com/blogs/2009/05/railsconf-09-after-the-railsconfening/#comments</comments>
		<pubDate>Fri, 08 May 2009 20:52:05 +0000</pubDate>
		<dc:creator>Noel Rappin</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>

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




RailsConf attendees patiently await my session. They have no idea what they are in for...


A rambling set of notes and things while it's still in my head.
			
Overall Notes
Starting with the positive... I had a great time. There's nothing like getting to be around hundreds of people who share the same excitement for programming, Rails, learning [...]<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/05/railsconf-09-after-the-railsconfening/">RailsConf &#8216;09: After the RailsConfening</a></p>



Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/04/railsconf-2009-the-railsconfening/' rel='bookmark' title='Permanent Link: RailsConf 2009: The RailsConfening'>RailsConf 2009: The RailsConfening</a></li><li><a href='http://www.pathf.com/blogs/2008/06/railsconf-2008-a-belated-look-back/' rel='bookmark' title='Permanent Link: RailsConf 2008: A Belated Look Back'>RailsConf 2008: A Belated Look Back</a></li><li><a href='http://www.pathf.com/blogs/2008/05/welcome-to-railsconf/' rel='bookmark' title='Permanent Link: Welcome To RailsConf'>Welcome To RailsConf</a></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="right">
<a href="http://en.oreilly.com/rails2009/public/schedule/detail/7846"><br />
<img src="http://www.pathf.com/blogs/wp-content/uploads/2009/05/me1.jpg" alt="me.jpg" border="0" width="500" height="172" class="right"/><br />
</a><br />
<br clear="all"/><br />
<a href="http://en.oreilly.com/rails2009/public/schedule/detail/7846">RailsConf attendees patiently await my session. They have no idea what they are in for...</a>
</div>
<p><br clear="all"/></p>
<p>A rambling set of notes and things while it's still in my head.</p>
<p>			<span id="more-2392"></span><br />
<h3>Overall Notes</h3>
<p>Starting with the positive... I had a great time. There's nothing like getting to be around hundreds of people who share the same excitement for programming, Rails, learning new things, and doing things well. The sessions were quite good overall, it was great to meet several people I had only interacted with online. There are always things to grumble about, but overall it was well-organized and exciting and fun.</p>
<p>Attendance was definitely down. I don't have exact numbers, but it was about 1/3 less then last year. The exhibit hall seemed down even further. On the other hand, there seemed to be an unusually large percentage of first time attendees. Not sure how to explain that, although it did seem like the Las Vegas location turned people away.</p>
<p>Insecurity over doing things "the right way" was a common concern, from the tutorials, to DHH saying in his keynote that even he doesn't know all the Rails internals any more, to the questions I was getting on testing, etc...</p>
<p>On the plus side, <a href="http://railsconf.blip.tv/posts?view=archive&nsfw=dc">all the keynotes were recorded professionally</a>, and are being turned around very quickly. DHH's keynote Tuesday morning, the Tim Ferris interview Tuesday night, and Chris Wanstrath's talk Wednesday morning are online as I write this. Robert Martin's just went up.</p>
<p>On the down side, unlike a lot of the regional conferences, the individual sessions were not recorded. O'Reilly tried to organize the community to record sessions, but there was nothing like enough of a critical mass of people with Flip cameras to make that work. Although, who knows, maybe things will trickle in.</p>
<p>All available session presentation slides are available at <a href="http://www.railsconf.com/presentations">http://www.railsconf.com/presentations</a>.</p>
<h3>Rails 3</h3>
<p>Rails 3 was a common topic, although an alpha version was not released. New features discussed included:</p>
<ul>
<li>Brand new router, with a cleaner DSL and the ability to be more modular</li>
<li>A change in output to where the new default is to escape output to prevent XSS attacks, and raw output must be explicitly specified</li>
<li>New, unobtrusive JavaScript and Ajax handlers.</li>
<li>Easier support for different ORM and template engines</li>
</ul>
<p>DHH assured everybody that the Rails defaults will still "kick ass" (Kathy Sierra fan alert!), but that developers with specialized needs will find it easier to meet their needs.</p>
<p>The JavaScript mechanism looks particularly nice. Using the new HTML 5 "data-" prefix for custom attributes, a remote call like the following:</p>
<pre style="white-space: pre !important;">
&lt;%= link_to &quot;Delete&quot;, @comment, :remote =&gt; true, :method =&gt; :delete %&gt;
</pre>
<p>Would be turned into the following HTML</p>
<pre style="white-space: pre !important;">
&lt;a href=&quot;/comments/1&quot; data-remote=&quot;true&quot; data-method=&quot;delete&quot;&gt;Destroy&lt;/a&gt;
</pre>
<p>From there, it's easy to see how an unobtrusive JavaScript library like jQuery could latch on to those custom attributes. In fact, the plain is for Rails to provide adapters for common JavaScript toolkits in the same way that adapters for databases are provided.</p>
<h3>Rack</h3>
<p>Lot of discussion of Rack, Rails Metal, and Sinatra this year, including two sessions that had very similar focuses, plus a significant section of the Rails Envy session (which dug into the actual Rails core Rack middleware code), plus the announcement that next year's Rails Rumble will be open to any Rack-based application.</p>
<p>There's a general consensus that Rack is very powerful stuff, and that we are just starting to see the beginnings of very cool tools. At the same time, it seems like nobody is quite sure what web applications will look like when everything that can be refactored to Rack is refactored to Rack.</p>
<h3>Testing</h3>
<p>Testing was a big theme, with a lot of sessions on testing tools and processes, including my own. Bob Martin's keynote, which you should definitely check out, was very emphatic on the idea that testing is part of what makes programming a profession. (It was also an interesting counterpoint to recent discussions about "professionalism" in the Rails community).</p>
<p>Cucumber was very prevalent. In addition to a dedicated session from tool maintainer Aslak Hellesøy, it was mentioned in several other talks, including mine. </p>
<p>I learned about some new tools. </p>
<p>Dave Chelimsky announced <code>stubble</code>, a new API for stubbing ActiveRecord objects away from the database for the purpose of testing. Pretty cool.</p>
<p>I only saw part of the talk, but Relevance presented <a href="http://github.com/relevance/blue-ridge/tree/master">Blue Ridge</a>, a plugin for testing JavaScript code.</p>
<h3>Non Rails-Core keynotes</h3>
<p>Tim Ferris... <a href="http://www.railsinside.com/events/285-tim-ferriss-railsconf-2009-keynote.html">I'm sure you may have seen some of the reaction</a> online to this talk. While I appreciate the general idea of bringing in speakers from outside our little bubble, and I can understand the potential appeal of Ferris from a lifestyle or productivity standpoint. I think the nicest thing I can say about the talk was that it didn't work. The conversation format veered off into topics of dubious relevance, and worse, Ferris veered between low-energy and coming off as kind of arrogant. And not in a good way.</p>
<p>Robert Martin, on the other hand, was outstanding. I was just skimming through that talk again for the purposes of pulling out the best parts to show people here, and it's hard to limit it. Smart, funny, and inspiring in the sense of uplifting the daily programmer routine into something professional and profound.</p>
<h3> Entrepreneurship </h3>
<p>Side projects and entrepreneurship were less of an explicit theme this year than last.</p>
<p>I went to both Obie Fernandez' session on being a successful Rails consulting company as well as the panel on entrepreneurship prominently featuring him and DHH. I appreciated Obie's willingness to give out actual numbers, that was very useful, and the interaction between him and DHH on how much a dedicated business person is needed was interesting, but probably more reflective of those two specific personalities than general guidelines.</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/05/railsconf-09-after-the-railsconfening/">RailsConf &#8216;09: After the RailsConfening</a></p>


<p>Related posts:<ol><li><a href='http://www.pathf.com/blogs/2009/04/railsconf-2009-the-railsconfening/' rel='bookmark' title='Permanent Link: RailsConf 2009: The RailsConfening'>RailsConf 2009: The RailsConfening</a></li><li><a href='http://www.pathf.com/blogs/2008/06/railsconf-2008-a-belated-look-back/' rel='bookmark' title='Permanent Link: RailsConf 2008: A Belated Look Back'>RailsConf 2008: A Belated Look Back</a></li><li><a href='http://www.pathf.com/blogs/2008/05/welcome-to-railsconf/' rel='bookmark' title='Permanent Link: Welcome To RailsConf'>Welcome To RailsConf</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.pathf.com/blogs/2009/05/railsconf-09-after-the-railsconfening/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 5.370 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-20 03:06:25 -->
