Rspec 2 and Rails 3

January 12th, 2010

With the beta release of Rails 3 just around the corner, we’re planning a 2.0 release of Rspec, with an rspec-rails-2.0 gem for rails-3.0.

Late last week and through the weekend, Engine Yard, Relevance and Obtiva sponsored a meeting with Yehuda Katz, Carl Lerche, Chad Humphries, and me. The four of us laid out some groundwork and made some good progress toward what promises to be be a very friendly world for Rspec and Rails users and extenders.

Thanks to David Heinemeier Hansson and the rest of the Rails core team for embracing agnosticism without compromising convention over configuration.

I’ll follow up with details as things shape up, but here is a quick synopsis:

Rails users

Whether or not you use Rspec, you’ll see improvements in some of the built-in assertions, and other testing facilities that ship with Rails.

Rspec-rails users

If you do use Rspec, you’ll see a new rspec-rails plugin/gem that hooks into new features of rails-3 like the new rails generators. You’ll also see support for Merb-style request specs that wrap Rails’ integration tests.

Test framework authors

Rails’ testing APIs will be decoupled from the Test::Unit and Minitest runners. For authors of new testing frameworks, this means that you’ll be able to include a module in your framework’s objects instead of having to subclass TestCase. This will make it much easier to experiment with new ideas in the context of Rails, which clearly exposes those ideas to a wider audience than otherwise.

Welcome Chad Humphries

January 12th, 2010

I’d like to welcome Chad Humphries to the Rspec Development Team.

Chad wrote an Rspec-compatible framework named Micronaut, which runs specs written for Rspec. With Chad on board, we’re replacing Rspec’s runner with Micronaut’s runner for rspec-2.0, which is already in progress and should be released with a new rspec-rails-2.0 plugin/gem in time for the Rails 3.0 release.

Check back here for more details over the coming days, but in the mean time:

Welcome, Chad!

Beta 10????? When the hell are we going to start chopping down some trees? Well, first, here’s what’s new in Beta 10 of The RSpec Book:

Automating the Browser with Webrat and Selenium

This new chapter from Bryan Helmkamp shows you how to drive Cucumber scenarios right through your browser using Webrat and Selenium. You’ll type a single command and watch a browser fire up and walk through each scenario step by step right before your very eyes, and then see a standard Cucumber report in the shell. It’s a sight to behold, and a great way to drive out behaviour that requires JavaScript.

And now, for your reading pleasure … Read the rest of this entry »

let it be @-less

September 15th, 2009

If you use RSpec and you’re disciplined about the red/green/refactor of Test Driven Development, you probably find yourself doing this from time to time. We start off with a single example:

describe BowlingGame do
  it "scores all gutters with 0" do
    game = BowlingGame.new
    20.times { game.roll(0) }
    game.score.should == 0
  end
end

Then add second example:

describe BowlingGame do
  it "scores all gutters with 0" do
    game = BowlingGame.new
    20.times { game.roll(0) }
    game.score.should == 0
  end
 
  it "scores all 1's with 20" do
    game = BowlingGame.new
    20.times { game.roll(1) }
    game.score.should == 20
  end
end

Once we get the second example passing, we remove duplication in the examples, typically like this:

describe BowlingGame do
  before(:each) do
    @game = BowlingGame.new
  end
 
  it "scores all gutters with 0" do
    20.times { @game.roll(0) }
    @game.score.should == 0
  end
 
  it "scores all 1's with 20" do
    20.times { @game.roll(1) }
    @game.score.should == 20
  end
end

This last step involves copying the first line of each example to a before(:each) block, and then converting the references to game to an instance variable using an @ symbol. This is tedious and error prone, but we accept that in the interest of keeping things clean.

Read the rest of this entry »

release candidates

We’re using the new rubygems prerelease feature to do proper release candidates. This feature was introduced to rubygems a couple of versions back, but I’d recommend updating to rubygems-1.3.5 before installing the rspec prerelease gems.

For those unfamiliar with this new rubygems feature, you have to add the --prerelease flag in order to see and install these gems:

$ gem search --remote --prerelease rspec

  *** REMOTE GEMS ***

  rspec (1.2.9.rc1)
  rspec-rails (1.2.9.rc1)

$ [sudo] gem install --prerelease rspec
$ [sudo] gem install --prerelease rspec-rails

This way only those who choose to install the prerelease gems will get them, while those who exclude the –prerelease flag will get the previous final release (rspec-1.2.8, rspec-rails-1.2.7.1).

Once you install the prerelease gems, Rubygems will treat 1.2.9.rc1 as a higher version than 1.2.8, but a lower version than 1.2.9. That way when we do the final release you’ll be able to just install 1.2.9 and it will take its rightful place ahead of 1.2.9.rc1 without you having to uninstall rc1.

I invite you to install these prerelease gems and report any issues you run into to http://rspec.lighthouseapp.com/rspec. Advanced thanks to those who help the rest by breaking these in.

changes

Here are the changelogs for both rspec and rspec-rails. I’ll post separately about some of the new features in more detail.

rspec-1.2.9-rc1

  • enhancements

    • manage backtrace-ignore patterns with Spec::Runner.configure (Martin Emde). Closes #870.
    • friendly mock argument expectation failure message (Tim Harper). Closes #868.
    • added double() as alias for stub() and mock()
    • failure messages for doubles, mocks and stubs use the right name
    • add let() method to assign memoized attributes (suggestion from Stuart Halloway). Closes #857.
    • add its method so you can say: describe Array do its(:length) { should == 0 } (Stephen Touset). Closes #833
    • spec command automatically uses spec/spec.opts if it is present (suggestion from Yehuda Katz)
    • rspec now adds PROJECT_ROOT/lib and PROJECT_ROOT/spec to the load path
    • determines PROJECT_ROOT by recursing up until it finds a directory that has a ./spec directory (thanks to Scott Taylor)
    • supports require ’spec_helper’
    • supports running specs from the PROJECT_ROOT or any directory below it
    • closes #733
  • not really a bug fix or enhancement

    • temporarily moved heckle feature to features-pending (waiting to see what happens with http://rubyforge.org/tracker/index.php?func=detail&aid=26786&group_id=1513&atid=5921)

rspec-rails-1.2.9-rc1

  • enhancements

    • added route_to and be_routable matchers (Randy Harmon). Closes #843.
    • Provide better failure message for render_template when redirected (Josh Nichols). Closes #885.
    • generated specs require ’spec_helper’
  • bug fixes

    • pass the correct args to super in controller#render depending on the rails version (Lucas Carlson). Closes #865.
    • use Rack::Utils.parse_query to convert query strings to hashes. Closes #872.
    • errors correctly bubble up when a controller spec in isolation mode requests a non-existent action/template
    • no error if either action or template exist
    • error if neither exist
    • Closes #888.
  • removals

    • spec_server has been removed in favor of spork.
    • You can still use the –drb flag, but you’ve got to install the spork gem.
    • Windows users who cannot use the spork gem can install the spec_server from http://github.com/dchelimsky/spec_server
  • http://rspec.info

  • http://rubyforge.org/projects/rspec
  • http://github.com/dchelimsky/rspec
  • http://github.com/dchelimsky/rspec-rails
  • http://wiki.github.com/dchelimsky/rspec
  • rspec-users@rubyforge.org
  • rspec-devel@rubyforge.org

Windy City Rails

July 18th, 2009

I’m presenting at Windy City Rails in September. This is just the second year of this exciting midwest Rails conference, but the schedule looks most impressive. Talks range from How To Test Absolutely Anything to Better Ruby through Functional Programming to a Rails 3 Update from Yehuda Katz, Rails core’s newest member and the man who is bringing the best of Merb to Rails 3.

Last year I did a presentation about BDD and, with such a wide subject, ran out of time before I got through most of it. This year, the organizers of the conference have given me the opportunity to talk for three full hours! Count ‘em. Three!

It’s actually not just me talking (whew!). It’s a tutorial entitled Behaviour Driven Rails with RSpec and Cucumber. I’m planning an intensive skills development workshop, taking attendees through the development of a feature in a Rails app from planning to writing Cucumber scenarios to driving out code with RSpec. This is going to be about as close as you’ll get to a BDD immersion in three hours, so I hope to see you there whether you’re just learning about BDD now or you’ve already been doing it for a while.

See you in September!

The RSpec Book: Beta 8.0

July 18th, 2009

The RSpec Book Beta 8.0 was just released. This release includes a number of fixed errata and one new chapter. Yes, only one chapter, but its a doozy:

Managing Complexity in Step Definitions

This chapter introduces a random generator to the Codebreaker game. This brings up several issues that can add complexity to Cucumber scenarios, RSpec code examples, and the code we’re driving out with the aid of these tools and the BDD process. We address these issues and offer strategies to manage the complexity they introduce.

RSpec works with test/unit

February 2nd, 2009

[Updated to Sept 5, 2009]

Did you know that rspec is interoperable with test/unit?

spec/rails (formerly rspec_on_rails) has always run on test/unit and rspec (core) has had t/u interop capability for over a year now.

Take, for example, this test in addition_test.rb:

require 'test/unit'
 
class TestAddition < Test::Unit::TestCase
  def test_add_1_and_2
    assert_equal 3, 1 + 2
  end
end

$ ruby addition_test

Loaded suite /Users/david/projects/ruby/tmp/tur/addition_test
Started
.
Finished in 0.000289 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

Now, simply require ’spec/test/unit’:

require 'rubygems'
require 'spec/test/unit'
 
class TestAddition < Test::Unit::TestCase
  def test_add_1_and_2
    assert_equal 3, 1 + 2
  end
end

Run it with the spec command that is installed when you install rspec:

$ spec addition_test

And tada!

.

Finished in 0.001451 seconds

1 example, 0 failures

RSpec is running your tests!

Read the rest of this entry »

In his blog entitled A case against Mocking and Stubbing, Brian Cardarella says

since I’ve been TATFT with TDD and some BDD I’ve come to believe that mocking/stubbing is a horrible idea and it can hurt the development process

Please take a minute to let that soak in. “a horrible idea” and “can hurt the development process”. In fact, please go read the post before you read on. I’d rather you read his words before you read my interpretation of them.

Back? Cool. Scary stuff, huh?

But never fear, because it’s not about you (unless you are Brian). What he is really saying is this:

since I’ve been TATFT with my own personal approach to testing Rails applications, which is a little bit different from what the TDD/BDD guys are doing and is largely based on Rails conventions which encourage you to couple layers together in your tests, I’ve come to believe that mocking and stubbing, two concepts that assist and encourage testing in isolation, which is the opposite of the kind of testing I like to do, is a horrible idea for me and can hurt my own personal development process

Before I defend my re-phrasing of Brian’s statement, let me say that he does have a couple of really good ideas in the post (specifically about the dilemma of databases), and I don’t intend to convince you that mocking and stubbing are inherently good ideas that will save the world, or that Brian’s process would be improved by adding mocks and stubs to it.

But Brian makes a broad generalization, attacking ideas that many view as inherently useful in the appropriate context, and I feel that the scope of his statement requires a bit of narrowing.

Read the rest of this entry »

Thoughts on the Dance-Off

June 7th, 2008

In his Great Test Framework Dance-Off at RailsConf 2008, Josh Susser compared rspec with test/spec and shoulda. All in all I’d say he was very fair in his comparisons and I’d recommend checking out his slides.

There were a couple of dings Josh handed rspec and I’d like to respond to them. This is not intended to sell you on using rspec if you’re not already using it. In fact, you’ll see that I agree with a some of Josh’s criticisms.

I’d much rather see developers using frameworks like test/spec and shoulda than not using anything more expressive than test/unit out of the box, but I also cringe when I hear that someone chose a different framework for reasons that are based on inaccurate or incomplete information. I take full responsibility for that. If you’re basing decisions on inaccurate or incomplete information it’s because I haven’t made the accurate and complete information available to you. This post is one step towards addressing that problem.

Read the rest of this entry »