Category Archives: TDD

Getting Started with Rails Testing

I gave a presentation at the January 2013 Boston Ruby Project Night on “Getting Started with Rails Testing”.

This talk aims at understanding the development workflow while using TDD and the Red-Green-Refactor loop.

We look at the different test types that you can write in a Rails application

  • Unit tests
  • Controller tests
  • Integration tests

We also look at some of the tools and frameworks that are available for testing, including RSpec, MiniTest, Test-Unit, Capybara, and FactoryGirl.

A simple example is used to show the test-driven development workflow.  The code for the example is on github at https://github.com/mdenomy/expense_tracker.

The github repository uses branches to capture a series of snaphots in the test-driven-development workflow.  See the Readme file for a list of the branches, or run the “git branch -a” command to see the full list from the terminal.

Advertisements

Stone Soup Development

I consider myself lucky to work in an environment that not only follows, but embraces, Agile and XP practices.  We follow test-driven development.  We pair program almost all the time, and we switch pairs frequently, usually at least once per day.  The benefits of these practices hit home this week during our iteration retrospective when the question was posed “What were you proud of this week”.

There were some interesting problems with very creative solutions that happened during the iteration, but the thing I was most proud of was a simple little piece of code.

Around the middle of the iteration I worked on a “calculator” that made some determination based on a set of rules.  We’ve all written code like this 1000 times before, it was not an especially difficult task.  But it was the kind of thing that could get ugly pretty quickly, and yet still “work”.  It was the kind of algorithm that could have easily morphed into a nasty tangle of boolean logic.

Instead, my pair and I started out with a few simple cases and applied a few brute force implementations in the “Calculate” method.  We continuously refactored as more tests were added and the complexity grew, reducing duplication and breaking the problem up into more digestible chunks.  At some point, my original pair swapped out and someone else swapped in for an hour.  It was late Friday, we improved some of the naming, added a few more test cases and supporting logic, then called it a day.  Energized work in action.

Monday morning, a new person swapped in.  Normally I would have swapped out since I had been on it the longest, but there were a few scheduling conflicts and so I stayed on.  We finished the class, ending up with very expressive names, a “Calculate” method that read like plain English, and small methods that did one thing, and did them right.  Again, this problem wasn’t rocket science, but it was done right.

Everyone brought something to the problem and helped refine the design.  We discussed trade-offs, avoiding traps like “my idea” and “your idea”.  After discussing it at the retrospective, it reminded me of a story that I learned as a kid called Stone Soup.  We started with nothing, everyone threw a little something in the pot, and we came out in the end with a nice little piece of code.

Why Katas

The Merriam-Webster dictionary provides the following definition for kata

Kata

a set combination of positions and movements (as in karate) performed as an exercise

Most people are probably familiar with katas as they are used in martial arts (come on, admit it, you liked the Karate Kid).  My introduction to katas in software was through the Software Craftsmanship movement, where they are often used as training exercises.

It is important to understand with coding katas that the idea is not to do the exercises the same way every time.  Katas are a great way to experiment with different techniques and styles.

  • Can I provide more descriptive naming
  • Does a terse syntax make the code easier or harder to understand in a particular place.  Would a more verbose, explicit approach be better.  For example, in the case of a complex ternary operator, would an explicit structured if/else construct be better?  Worse?  Try them out and decide for yourself.
  • Experiment with different syntax, e.g. the unless keyword in Ruby.  More or less readable?
  • Should I use a defensive programming style checking for nil/null in several places or a more confident programming style?
  • How am I naming my tests (yes you should be writing tests as part of your katas)

There are no right or wrong answers to these questions, the goal is to experiment and try out new ideas.  Understand where an idea works well and where it doesn’t work well.  Try a variety of approaches.  And the great thing about a kata, unlike your code base at your real job, is that you can blow it away when you are done and do it a little different the next time.

Katas and Interviews

I’ve been using pairing as a key part of the interview process for several years now, but a consistent challenge is to what to pair on.  It is unrealistic to assume that most developers are going to walk in the door and instantly grok your code base.  No matter how awesome you are or how descriptive the tests are, it’s just not gonna happen. Instead pick a problem set that a candidate can quickly get their head around and that you can discuss different design and implementation choices.

Katas and Pairing

I had an awesome pairing session yesterday with someone I had never worked with before, and we did some katas as a way to get to know one another, discuss approaches to coding, good naming, refactoring techniques.  It was a blast!

And the really great thing about katas and pairing is that it can be challenging to think of different ways to try something on your own.  But with a pair you have different perspectives baked-in.  And what you can learn may not be strictly code related: it could be keyboard shortcuts, different IDEs or editors, maybe even a wacky keyboard.  Don’t be afraid to experiment.

Resources for Katas

Cyber Dojo
Great resource for ideas for simple exercises.  Even if you don’t use the online collaboration tools, it has a great list of problems that can be used for a kata.  I used this yesterday for my leap year kata in Ruby

Dave Thomas’s Katas
This is the blog post that kicked off a lot of the talk about katas in the software craftsmanship movement. Again, great problem sets that you can get your head around quickly, but with enough meat for some interesting challenges to address.

Your Friendly Neighborhood Software Craftsmanship Group
Here in Boston we have Boston Software Craftsmanship. Great group, someone’s always willing to pair.  Find your local group, or start one yourself.

Another Developer on Your Team
Ask someone on your team if they’d be interested in brown bagging it some day and do some kata’s together.  You should do this especially if you are not pairing now or are not doing TDD.  You may find that you should really be pairing and you really should be doing TDD.  You should.  Really.

CodeRetreat.org
I had a great time at last year’s Global Day of Code Retreat.  Check it out.  Conway’s Game of Life is a great coding exercise.  This also introduces some great constraints and pairing ideas that really get you thinking.

Now get out there and start coding…

Season of Ruby – Things Are Starting To Click

The danger with doing any online tutorial, even one as good as the Michael Hartl Rails Tutorial, is that if you aren’t careful the only benefits you will have at the end is that your typing skills have improved and you have the marketable ability to cut-and-paste large snippets of code.  At some point you need to start driving the bus.  Today I felt like the Ralph Kramden of Rails.

Editor’s Note: I am not actually old enough to have seen the Honeymooner’s, I just remember in my college days the reruns were on at 11PM, just before Star Trek at midnight (also in reruns).

The last few chapters I have been making an effort to implement the code without looking at the solution from the tutorial.  Today I stepped it up a little further by taking more control of writing and defining the tests too.  It really paid off today as I felt like I took ownership of the app and the technical choices.

Chapter 10 starts out by defining the functionality needed for editing a user.  I looked over the wireframes and had a good idea about the functionality I wanted.  I glanced at the titles of the 1st three tests: get page successfully, has correct title, and includes link to change gravatar.

From a pure TDD approach, doing the simplest thing that works, I was able to get these tests to pass with the following code.

app/views/users/edit.html.erb

<h1>Edit User</h1>
<a href="http://gravatar.com/emails">change</a>
app/controllers/user_controllers.rb
 class UsersController < ApplicationController
    ...
    def edit
      @title = "Edit user"
    end
    ...

Obviously this is not enough to implement the final solution, but it is enough to get the tests to pass, and in my experience additional functionality should be driven by the tests.  From the perspective of a Rails noob I felt that these were valuable tests because they proved out the plumbing and set the table for more complex tests/functionality.  Now it was time to look at the tutorial’s solution.

I was surprised to see that the tutorial solution included the form and all its associated fields.  Now this is not a knock on the tutorial, it is a very good tutorial.  I love this tutorial, but while it introduces some concepts of TDD and its primary goal is not to teach TDD.  But clearly there was a disconnect between the solution and the tests.

So I added the tests for the fields, and now was happily back to red.  Yes Virginia, real developer’s love failing tests, they are a sign of progress.

spec/controllers/user_controllers_spec.rb

   it "should have a name field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[name]'][type='text']")
    end

    it "should have an email field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[email]'][type='text']")
    end

    it "should have an password field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[password]'][type='password']")
    end

    it "should have an confirmation field" do
      get :edit, :id => @user
      response.should have_selector("input[name='user[password_confirmation]'][type='password']")
    end

Getting to green was fairly trivial, and I was able to cut-and-paste a lot of the code from “new” and make a few minor mods.

app/views/users/edit.html.erb

<h1>Edit User</h1>
<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages', :object => f.object %>
  <div>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div>
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </div>
  <div>
    <%= f.label :password_confirmation, "Confirmation" %><br />
    <%= f.password_field :password_confirmation %>
  </div>
<div>
  <%= f.submit "Update" %>
</div>
<% end %>
<div>
  <a href="http://gravatar.com/emails">change</a>
</div>

My tests were passing but now I had quite a bit of duplicated code in my app/views/users/new.html.erb and app/views/users/edit.html.erb files.  It was time for the 3rd piece of the red-green-refactor cycle.

Thinking back to earlier chapters, I thought what I would like to do is to implement a partial view that encapsulated the user forms.  After some googling about how to pass parameters into a partial view I ended up with the following partial view

app/views/shared/_user_fields.html.erb

<div class="field">
  <%= f.label :name %><br />
  <%= f.text_field :name %>
</div>
<div class="field">
 <%= f.label :email %><br />
 <%= f.text_field :email %>
</div>
<div class="field">
 <%= f.label :password %><br />
 <%= f.password_field :password %>
</div>
<div class="field">
 <%= f.label :password_confirmation, "Confirmation" %><br />
 <%= f.password_field :password_confirmation %>
</div>

And the edit.html.erb was a lot cleaner now and my tests were still passing.
app/views/user/edit.html.erb

<h1>Edit User</h1>

<%= form_for(@user) do |f| %>
 <%= render 'shared/error_messages', :object => f.object %>
 <%= render 'shared/user_fields', :f => f %>
 <div class="actions">
 <%= f.submit "Update" %>
 </div>
<% end %>

<div>
 <a href="http://gravatar.com/emails">change</a>
</div>
<pre>

Making the necessary changes to new.html.erb completed the process.
app/views/user/new.html.erb

<h1>Sign up</h1>
<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages' %>
  <%= render 'shared/user_fields', :f => f %>
  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

Run the tests one more time…and still green.

It was a really good day in Rails land.  None of this was rocket-science, but I felt like I knew what I wanted to do and how to do it (with just a few minor hiccups related to syntax and mechanics).

I Hate Year End Lists

One of the things that drives me crazy about this time of year, is the never-ending set of lists for what happened in the last year, or resolutions for the new year.  Absolutely hate them.  So why am I writing one now, good question, I have no idea.  But if you hate lists and have stopped reading, oh well.  Anyway, here’s my lists of things to get done in 2012.

1. Set Up a GitHub Account – Really?!?!  It is the tail end of 2011 and I don’t have a GitHub account.  More and more it seems to matter less and less what is on your resume.  Show me what you’ve done.  Show me you can collaborate and play nice with others.

2.  Learn Ruby – I don’t mean dabble in Ruby.  I don’t mean write “Hello World” in Ruby.  I don’t mean write C# style code with Ruby syntax.  I’ve done that and it hasn’t mattered much.  Learn to write Ruby style code in Ruby.  Why?  Because maybe it will make me a stronger developer across the board by introducing me to different ways to write code and solve problems.  I also think the Ruby community as a whole are strong proponents of software craftsmenship.  Or at least the ones I run into are, and that can only be a good thing.

3.  Write More Code – The last few years I have spent a lot of energy working with Agile practices, and especially trying to help the teams I am on be more productive and write better, well-tested code through practices like pairing and TDD.  I am very proud of the end results, but a side effect of that has been that I write less code on a day to day basis.  That may require being creative and looking for new opportunities to write code outside of my day job.  But I really miss the challenges of solving technical problems on a regular basis.

4.  Read More Code – Participating in the Global CodeRetreat was a great opportunity to work with a lot of developers, all with different experiences and skill levels.  Being an experienced developer is great, but there is so much to be learned from seeing how other people solve problems.  Instead of just downloading some open source tool that makes my life easier, peek under the covers, run the tests,  I don’t know…maybe even contribute to the project.  At the very least get some new ideas.

5. Get Out of My Comfort Zone – Over the years I have developed a set of skills and practices that work well for me and that I have been successful with.  I wouldn’t say it is easy, but it is a little safe.  I have experience with problem domains I work in, I am comfortable with the languages I use, and I have developed a set of practices that are well ingrained in me.  That’s all well and good, but there is a potential for a lot of growth to be found outside your comfort zone.

6. Buy a Mac – Windows and Microsoft have been good to me, and I have used Windows for work for the past 20 years or so.  I will probably still do my day job work on a Windows machine, but in the spirit of learning new languages and getting out of my comfort zone, maybe it is time to see how life is from the other side.  I could do all these things on a Windows box, but it’s time for a little change.  Plus I can hang out with the cool kids at developer events.

So I am seeing a theme here for 2012.  Hopefully I can make it all happen.

Have a safe and happy new year!

Vermont Code Camp

Just got back from a road trip to Burlington VT for Vermont Code Camp 3. It was a great code camp, lots of good sessions and speakers, well-organized, and generally a lot of fun.

The first session I attended was Dane Morgridge’s talk on ASP.NET MVC3: A Gateway to Rails. I was really interested in this talk, because as a TDD junkie, I was curious if part of the “gateway to Rails” involved embracing testing. I still feel like the .NET community is behind the curve on TDD and BDD, and I wanted to hear Dane’s perspective on making the switch from .NET to Rails. His presentation was very much an overview of the goodness in Rails and ASP.NET MVC3, like convention over configuration and how having a separation of concerns with MVC allows for a more testable system. Afterwards I was able to catch up with Dane between sessions and he showed me a few things he is doing with Cucumber and BDD. I have to say the readability of Cucumber makes it look very appealing and we talked about how BDD tests can be more maintainable than TDD/unit level tests. There is a right time to use one and the right time to use another.

Next up was David Howell’s Tackling Big Data with Hadoop. I knew very little about Hadoop, but had heard a few good things about it and was looking to learn a bit more. David’s talk focused on using Hadoop’s Map-Reduce capabilities to handle large data sets. We also talked a bit about what constitutes “big data”. If you are not familiar with Map-Reduce, check out Google’s 2004 paper on it. David went over the basics of a hadoop cluster and showed how it could be used in a distributed architecture to tackle a big data set. He also touched on how some of the fault tolerance could be implemented using the cluster and distributing the same job to multiple nodes. To wrap up he ran a simplified Map-Reduce demos on a small data sets that was appropriate scaled for the time that we had available.

I would have to say the third session was one of my favorites, Functional Programming on the JVM. This talk was given by Jonathan Phillips and another developer named Jack (sorry Jack, missed your last name), both from Dealer.com. As someone who has spent the last….well lets just say a lot of years doing OO programming, I struggle with the shift to functional programming, especially when state and immutablility come into play. I have been to several functional programming and F# presentations that have left me confused, but 5 minutes into their talk Jonathan and Jack went over closures and recursion as they apply to functional programming and it was like a light going off. Suddenly immutability made more sense. After the overview of functional programming they went into 3 different languages that can be used to do functional programming on the JVM: Groovy, Scala, and Clojure. The used a simple example, comparing the amount and clarity of code that you would write using pure Java versus each of the 3 other languages. They also went over some of the pro’s and cons about Groovy, Scala, and Clojure. It left me with a lot to think about, and I am eager to experiment with all 3 languages.

Another great talk was Free and Open Source Software (FOSS) in the Enterprise by Kevin Thorley, also from Dealer.com. Kevin laid out what you need to consider using FOSS software. What is the community support, how many contributors are there, how robust is it, how easy is it to use and what documentation exists, do you really need it or do you want to use it because you just read some great blog post about NoSQL. One thing that Kevin said really rang true when he said that open source is not free and that we need to understand and accurately assess what the cost is to use and maintain it. Kevin went over how they use MongoDB, RabbitMQ, Spring, and Solr at Dealer.com. Don’t misinterpret Kevin’s statement about it not being free. Obviously they rely heavily on FOSS at Dealer.com, but you have to be honest about why you are using it and what is the cost going to be to your organization to use “free software”.

I give a lot of credit to the guys from Dealer.com for their participation at the code camp. They are a Burlington based company and they had a significant presence at the code camp. It is one thing to say that you are passionate about software, it is another to do something about it. Developers from Dealer.com did 4 of the 26 total sessions. I followed up with a few of them after the sessions and you can tell they are really into the technologies that they were presenting.

The last 2 presentations were familiar ground for me, but I still learned a few things. Vincent Grondin’s talk on mocking and mocking frameworks. Vincent gave a very good discussion of mocking and the two type of mocking frameworks available: those based on dynamic proxies, and those based on the .NET Profiler API‘s. Examples of frameworks based on dynamic proxies are Moq and NMock3. Examples of .NET profiler based frameworks include Telerik’s JustMock and Typemock Isolator. The .NET profile based mocking frameworks have some significant advantages in being able to mock out static methods and even system calls. I have been using Moq (and previously NMock2) and I have had to write custom wrapper classes to work around problems mocking static methods and system calls.

The day wrapped up for me with Josh Sled’s talk on dependency injection. Josh gave a good overview of why you would want to use DI, but also gave an honest assessment of pros and cons of using them. I think any time we decide to take on a new framework we need to understand what the cost is (similar to what Kevin Thorley said). I am a big fan of DI and IOC frameworks, but you need to be aware of what the cost is to using that framework. We touched on a few IOC frameworks that you can use like Spring (Java), Castle Windsor (.NET), and StructureMap (.NET).

All in all it was a great code camp. It is usually hard to justify spending a beautiful late summer day in the basement of UVM, but it worked in this case. I am really looking forward to all the slides being available to I can check out some of the sessions I couldn’t make.

Thanks to Julie Lerman, Rob Hale, and all the other organizers, volunteers, and sponsors for putting together a great event.

Introduction to Test Driven Development at Nashua Scrum Club

I had the opportunity to give a talk “Introduction to Test-Driven Development” at the Nashua Scrum Club this week.  It is a great group of folks, and if you are interested in learning more about Scrum and Agile practices you should check them out.  They are a diverse, engaging group of folks covering the full spectrum of roles in a Scrum organization.

The talk was targeted for all the roles on a Scrum team, and my goal was to give a small taste of what TDD can bring to a software project.  I have been using TDD for about 5-6 years, and I have definitely become “test infected”.  I can’t imagine developing production code any other way.

I wanted to stress the importance of working iteratively, and getting through the Red-Green-Refactor loop quickly, adding more and more functionality with each new test.  One of the areas new teams may struggle with TDD is to try and do too much in a single pass through the loop.  If you get bogged down and are in the loop for more than 15-30 minutes you may be biting off too much in this test and should look to a smaller incremental step.

Given the broad spectrum of roles that were at the meeting (Scrum Masters, coaches, QA/test, developers, managers, product owners) I also wanted to show how tests can be used to get the team to collaborate more.  I think tests can be a great mechanism for developers to collaborate with product owners to make sure the behavior is as intended.  There are also opportunities for QA/test to work with developers to understand what is tested at the unit and integration level.  Finally tests are a great mechanism for developers to share knowledge.  When I am looking at a code that I may not be as familiar with, I find the tests to be a great place to start to understand what functionality is provided.  In essence, the tests become an executable specification of the system.

We also spent some time talking about TDD and design, which I know has been something of a hot-button topic lately.  Does TDD guarantee a good design?  Is it a good design methodology?  In and of itself, I would say no.  But what I would say is that TDD encourages good design practices and to do it well, i.e. not have brittle tests, you need good design practices.  I had almost 20 years experience before starting TDD and felt I was a good object-oriented designer.  TDD helped me step up my game in terms of design and developing more modular, loosely-coupled code.  We touched on design practices like SOLID, YAGNI, DRY, separation of concerns, how design patterns like MVC allow better, more thorough testing.

Finally we talked about the challenges of adopting TDD.  Change is hard, and a switch to TDD can be a difficult and frustrating experience.  TDD requires strong design practices.  There is also the battle to fight about writing “all that test code”, to which I always like to ask “How much were you writing before”.  Jim Shore summed it up well when he said that you should expect 2-3 months to make the adjustment.

I had a great time at the Nashua Scrum Club, and want to thank everyone there for making it a fun (and hopefully informative) evening.  I look forward to a return visit soon.