There’s been a bunch of hullabaloo about our recent deprecation of the Shoulda macros should_change and should_not_change. A lot of people have asked, “why remove it?” Short answer: we don’t use it anymore. Long answer: it’s confusing and may encourage bad programming practices.
Consider this example of should_change:
context "updating a post" do
setup do
@post = Post.create(:title => "old")
put :update, :post => {:title => "new"}, :id => @post.to_param
end
should_change("the post title", :from => "old", :to => "new") { @post.title }
end
This reads well and seems to be fairly straightforward. Sadly, this doesn’t work because of how should_change works internally (hence the confusing part). It would actually need to be written like this:
context "given a post" do
setup do
@post = Post.create(:title => "old")
end
context "updating" do
setup do
put :update, :post => {:title => "new"}, :id => @post.to_param
end
should_change("the post title", :from => "old", :to => "new") { @post.title }
end
end
The @post instance variable needs to be assigned a context above the context containing should_change. I told you it was confusing.
Now, onto the bad practice aspect. This tests that the post was saved! Come on, we don’t want to do that here. That’s why we write Cucumber scenarios! We’re testing the controller, right? If that’s the case, then we shouldn’t care whatsoever if update_attributes worked with specific data passed to it, just that it was called and that we handle the result accordingly.
context "updating a post" do
setup do
@post = Factory :post
Post.stubs(:find => @post)
end
context "when the update is successful" do
setup do
@post.stubs(:update_attributes => true)
put :update, :post => {:title => "new"}, :id => @post.to_param
end
should set_the_flash.to(/updated/)
should redirect_to(posts_path)
end
context "when the update is unsuccessful" do
setup do
@post.stubs(:update_attributes => false)
put :update, :post => {:title => "new"}, :id => @post.to_param
end
should render_template(:edit)
should assign_to(:post).with(@post)
end
end
This is more inline with what we really want to test; that the controller handled update_attributes correctly when the update worked and when it didn’t. Leave the model logic and whether it should save or not in the model (and its tests), and test the controller to ensure it handles whether the model was updated.
I mentioned before that Cucumber scenarios should cover overall integration. Something like these would work:
Scenario: Update a post successfully
Given I am signed in
And I authored a post titled "Great Scott"
When I go to edit the "Great Scott" post
And I fill in "Title" with "Willard Scott"
And I press "Update"
Then I should see the flash message "Your post was updated successfully"
And I should have authored "Willard Scott"
Scenario Example: Update a post unsuccessfully
Given I am signed in
And I authored a post titled "Great Scott"
When I go to edit the "Great Scott" post
And I fill in "<required field>" with ""
And I press "Update"
Then I should see error messages
When I fill in "<required field>" with "<valid value>"
And I press "Update"
Then I should see "Your post was updated successfully"
Examples:
| required field | valid value |
| Title | Awesome Post Name |
| Body | Awesome story |
I’m sure this isn’t the only way people were using should_change, but hopefully this clarifies how deprecating the methods will encourage better tests.
Do you use should_change and think it’s by far the best way to test certain pieces of code? I’d like to see some people who’ll sorely miss it post some real code (Pastebin or Gist).

factory_girl has always had little Rails-specific code. It only depends on Ruby, and in order to use it in your application, it asks three things of your models:
#save! (this is only necessary for the “create” strategy)However, despite this simple API, there’s one feature in factory_girl that has traditionally caused some issues with Rails: automatic factory definition loading.
The definition loader has simple rules: if it finds any of test/factories.rb, spec/factories.rb, test/factories/**/*.rb, or spec/factories/**/*.rb, it will load those files in no particular order. For most applications, this just makes things a little nicer.
In early versions of factory_girl, it looked for definitions as soon as you loaded factory_girl.rb. Unfortunately, this broke down when Rails 2.1 introduced gem dependency management. Loading factory_girl during the application initialization phase meant that the factory definitions might reference your models before all the gems and plugins they depended on were fully loaded. Contributer technicalpickles fixed that by detecting Rails and deferring definition loading until Rails was initialized. This solution worked effectively for the entire Rails 2.x series of releases.
The upcoming Rails 3 release uses a new library for managing application dependencies: bundler. Bundler’s behavior is more predictable and understandable than Rails 2’s dependency manager ever was. However, with the introduction of Bundler, two important changes were introduced that impacted many libraries that integrate silently with each other:
Yehuda Katz, the author of Bundler, discussed this topic in depth on his blog. In his discussion, he suggests a solution that could be added to Rubygems:
s.integrates_with "rails", "~> 3.0.0.beta2", "haml/rails"
However, this functionality doesn’t exist yet, so we’ve decided to create a separate factory_girl_rails gem. This way, we can declare an explicit dependency on Rails, including the version, and automatic definition loading still takes place for Rails apps without any additional application code.
This doesn’t change much for an application that uses factory_girl. It boils down to this:
rails/init.rb and load your definitions.I originally added this feature to factory_girl because it was convenient, and seemed easy to add. However, this trivial feature has turned out to be the most difficult to maintain part of factory_girl, and is the single feature that is most likely to outright break an application. I plan on maintaining this feature because we’re used to having it and we’ve worked out most of the kinks at this point, but next time you consider adding an “easy” feature to your own library, also consider whether or not it’s essential to your library’s core mission.
We recently decided our CI server needed an overhaul. I really enjoyed Integrity as a build server, but after trying out Hudson it’s hard to say I want to go back. Hudson has several huge advantages:
Here’s the details of what I went through to get our new CI server up and running. Be warned, these are probably specific to our projects and needs, but the general process can definitely help anyone who’s looking to get started.

We started with a fresh Ubuntu 9.04 LTS install. First up was a basic iptables setup, all the commands you need are on this SliceHost article.
Next up we needed to install Hudson. Follow the instructions here: http://hudson-ci.org/debian/
The nice part about this install (instead of custom compiling it) is that it comes with an init script that is really handy to stop/start the server. There’s more tips on installing here.
If apt-get starts whining, just run sudo apt-get install -f. The hudson package should install the Java dependencies you’ll need for now.
Let’s also install some other basics we’ll need eventually. You may disagree with my choices here, but too bad, I’m the one maintaining CI:
sudo apt-get install zsh vim git-core build-essential postfix ack-grep
curl
chsh /usr/bin/zsh
The postfix install will prompt you for your server’s host name, we’ll want it eventually for emails. If you’re confused, check this article out.
By now you should be able to visit http://YOUR_SERVER_IP:8080 and Hudson should be alive and kicking.
That’s annoying though, we want to serve requests on port 80. Supposedly doing this with Hudson itself is a bad idea, since it would need to run as root. Apache does a better job, and this tutorial goes over the reasons why.
Here’s what I had to do to get this working:
sudo apt-get install apache2 libapache2-mod-proxy-html
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2dissite 000-default
That will install apache2, get the proxy mod enabled to forward requests along to hudson from the root domain, and disable the default site. Next step is editing /etc/apache2/apache2.conf and adding the following directive to the bottom:
# where your server lives!
ServerName ci.thoughtbot.com
Next up we’ll need to actually make a virtual host for apache to serve (thanks to this StackOverflow question for the right incantations). Create /etc/apache2/sites-available/hudson with the following:
<VirtualHost *:80>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyRequests Off
# Local reverse proxy authorization override
# Most unix distribution deny proxy by default
# (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)
<Proxy http://localhost:8080/*>
Order deny,allow
Allow from all
</Proxy>
</VirtualHost>
And the final touch to enable hudson and fire up apache:
sudo a2ensite hudson
sudo /etc/init.d/apache2 restart
Port 80 is much better. Now to continue with the configuration! We’re just using a standard security setup with one user. The process is a bit confusing, you have to enable authorization, then go out and sign up to set the password. After that, make sure you set the anonymous user permissions so they can see jobs on the home page.
If you’re an idiot like me and locked yourself out while doing this, disabling security is pretty simple.
As for plugins, we chose so far:
After installing the plugins and restarting, I disabled a bunch we didn’t need too, like Maven, CVS, etc. I would also check the “Prevent CSRF” button, that’s just a ridiculous option not to have on.
Let’s get mysql and postgres installed first.
sudo apt-get install mysql-server mysql-client libmysqlclient15-dev
sudo apt-get install postgresql postgresql-client postgresql-contrib
Redis is up next. We’re running the release candidate of 2.0, which is a bit of a pain to set up so far since make install was removed. I came up with an upstart scriptto run it instead.
sudo adduser redis
sudo su - redis
curl -O http://redis.googlecode.com/files/redis-2.0.0-rc1.tar.gz
tar zxvf redis-2.0.0-rc1.tar.gz
cd redis-2.0.0-rc1.tar.gz
make
logout
sudo bash -c "curl http://gist.github.com/raw/444033/9784f426402d5bece09894fcc6f98a33db5f5d15/redis.upstart > /etc/event.d/redis"
sudo start redis
Now that RVM exists, we can completely isolate projects from each other using gemsets. First we’re going to need even more system packages to deal with ruby and the other gems we’ll be installing eventually (nokogiri, paperclip, etc):
sudo apt-get install bison openssl libreadline5 libreadline-dev zlib1g zlib1g-dev libssl-dev libsqlite3-0 libsqlite3-dev sqlite3 libreadline5-dev libreadline6-dev libxml2-dev subversion autoconf libxslt-dev imagemagick
Jump in as the hudson user now and set up RVM:
sudo su - hudson
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
echo "[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm" > .profile
echo "---\ngem: --no-ri --no-rdoc" > .gemrc
Install the rubies you need now. Our starting lineup:
rvm install 1.8.6
rvm install 1.8.7
rvm install ree
rvm install jruby
We’ll need to get the hudson user set up with git and github too. Make sure to upload your public key ~/.ssh/id_rsa.pub to github so you can start cloning repos.
ssh-keygen -t rsa
git config --global user.email "hudson@thoughtbot.com"
git config --global user.name "hudson"
For each app, create the gemset, databases, and get the gems you need. Bundler would make this easier, but we’re not on it for all projects yet.
sudo su - hudson
rvm gemset create hoptoad
rvm gemset use hoptoad
mysql -u root
> create database hoptoad_development;
> create database hoptoad_test;
gem install mysql nokogiri json
Make a new Hudson job, check from SCM periodically, enable the post build notifications you want. Here’s the build script we’re using for hoptoad so far:
bash -l -c "rvm use 1.8.6-p287 && rvm gemset use hoptoad && rake db:migrate db:test:prepare default"
Debug, rinse, and repeat until it’s green.
RVM made this process a lot easier, I used to have to compile multiple versions of Ruby on my own and it was just a pain to manage. Gemsets are a killer feature too, and it’s easy to move them around to another Ruby version with the copy command:
rvm gemset copy 1.8.6@factory_girl 1.8.7@factory_girl
Overall the process was pretty smooth, and like any CI solution this took a while to set up and has its share of annoyances:
I hope these guidelines help those new to continuous integration with Hudson or otherwise. Of course, there’s plenty of other options in the Ruby-verse, but hopefully you won’t pass up what Hudson has to offer.


Shoulda has long been one of our most useful and popular open source projects, and it continues to serve us well as we use it daily. However, there have been some changes over the past year in the way that we use Shoulda, and these changes have led to some decisions about its future. In our post about the Rails 3 roadmap, we briefly covered the changes we made in Shoulda 2.11 as well as our intentions for Shoulda 3. However, we wanted to go over these changes in depth and explain some of our motivation.
Shoulda has two main components: a test context framework, and a set of helpers for testing Rails applications. The context framework was written because we found the method-based style of Test::Unit tedious, but certain objections were raised to the way RSpec was implemented, and we had existing test suites that could not easily be converted to RSpec. The Rails helpers were written in the form of Shoulda-based “macros” for convenience.
While this approach worked great for those of us using Test::Unit, this meant that the Rails helpers were only accessible in Shoulda-based test suites despite relying on very little in Test::Unit or the Shoulda context framework. In order to bring Shoulda’s Rails helpers to a wider community, they were rewritten as a set of RSpec-compatible matchers, and the existing “macros” were rewritten to use them.
As things in the Cucumber and RSpec community started to pick up, we found more and more that Test::Unit users weren’t getting the latest and greatest. Most of the new assertion libraries we found were written as RSpec expectations, and several improvements to RSpec’s context and matcher DSL made it look too appealing to ignore. We tried out RSpec on a few projects, and found that we really didn’t have to give anything up - Shoulda’s macros were fully supported as matchers - and we found ourselves enjoying RSpec more than Test::Unit.
It was at this point that we decided that Shoulda’s future would focus on RSpec. However, we weren’t going to ditch Test::Unit. We had many existing projects that used Test::Unit and Shoulda, and we certainly didn’t want to abandon the fantastic Shoulda community. After several experiments, we decided not to convert our existing Shoulda test suites to RSpec, largely because they didn’t take advantage of all that RSpec had to offer and didn’t come out any better in the end. This meant that we wanted to keep the context framework functioning. However, we also found ourselves reluctant to spend time and effort on a context framework that we didn’t want to use. Therefore, we needed to come up with a way to keep the matchers working with Test::Unit and make sure the context framework continued to function reasonably, but prevent the overhead of maintaining compatibility with two frameworks.
Rails 3 presented another challenge. Although some of the existing matchers just worked, the general strategy for testing them had to change with Rails 3, and some matchers required conditional forks in the implementations and tests. This was more complicated in the existing macro test suite, and maintaining two test Rails roots for backwards compatibility could potentially slow us down and make it harder to add new features. We preferred the unit-style tests in place for the matchers, and wanted to avoid the rails_root-style test going forward if possible.
After refactoring all of the macros to use matchers, we found that the macros all followed a basic pattern: convert a number of hash options into RSpec’s “fluid” syntax, and then create a test that performed one assertion based on a matcher. Based on this discovery, we changed Shoulda’s should method so that it could accept a matcher instead of a test name:
# macro style
should_have_many :users
should_ensure_length_at_least :name, 3
should_not_allow_values_for :isbn, "bad"
should_set_the_flash_to /thank you/i
should_not_assign_to :user
# matcher style
should have_many(:users)
should ensure_length_of(:name).is_at_least(3)
should_not allow_value("bad").for(:isbn)
should set_the_flash.to(/thank you/i)
should_not assign_to(:user)
Converting to this syntax would mean that we no longer needed to support both a set of macros and a set of matchers - all matchers essentially function as macros. In fact, this includes most non-Shoulda macros. We currently support both syntaxes, but you’ll receive a deprecation warning for the older macro style. We’ll also be removing the macros entirely starting with version 3, so now is definitely the time to start embracing matchers.
We’re committed to using RSpec, so we don’t want to spend time adding features to Shoulda’s context framework. However, we need it to continue to function for our older test suites, and we understand that some users still prefer the lighter weight Test::Unit framework.
Therefore, we plan on separating Shoulda’s context framework into a separate library starting with version 3. The contexts will still function as always, but we have no plans to further improve this aspect of Shoulda.
There are a lot of changes here, but they’re not too hard to understand:
We’re looking forward to Rails 3 and RSpec 2, and we hope you’re looking forward to Shoulda 3.


Being at RailsConf 5 has given us the opportunity to finalize a lot of the work we’ve done to prepare our plugins and gems for Rails 3. Thankfully, for many of the most popular gems, we’ve been able to maintain both Rails 3 and Rails 2.3.x compatibility in one gem. However, we’re taking this opportunity to say goodbye to some of our less widely used plugins, and some we plan on dropping Rails 2 support for altogether.
Obviously, Rails 3 isn’t actually out yet, so what we’re talking about here is Rails 3 beta 4. We’ll continue to keep things up to date and tested as we all move toward the release of Rails 3. Your help and patches are more than welcome.
So here is a comprehensive overview of the current status of the projects for both Rails 3 beta 4 and Rails 2.
We released Paperclip 2.3.3 a few days ago. This new version of Paperclip will work with Rails 3. Thanks to the investigation of nragaz and help from isaac and joeljunstrom on github, we worked out the kinks and it should be working with the Rails 2.3.x line, and Rails 3-beta 4. For the latest version of Paperclip, we’re no longer officially supporting Rails 2.0.x. The earliest version that will work is Rails 2.1.0. If you need support for an older version of Rails than that, you can use Paperclip 2.3.1.1.
A few days ago we released hoptoad_notifier 2.2.6 with includes support for Rails 3-beta 4 as well as all versions of Rails 2.x and Rails 1.2.6.
We just released shoulda 2.11. Along with Rails 3 support, we’re maintaining support for Rails 2.3.x in this latest release. However, the latest version of shoulda will not support versions of Rails less than 2.3. If you need support for a version of Rails older than that, you can use a previously released version.
In addition to the Rails 3 support, shoulda 2.11 introduces some dramatic changes to shoulda, including a new way of interacting with all shoulda macros. The previous way has been deprecated and will be removed in shoulda 3.0. We’ll make a separate blog post detailing many of the very cool changes to shoulda and more details about the future of shoulda soon, but for now, take a look at the README for the latest information on setting up and using shoulda.
We just pushed factory_girl 1.3 and factory_girl_rails 1.0. This new version adds Rails 3 support. Because of the way that Rails 3 loading has changed, we’ve decided to make a separate factory_girl_rails gem that will be used for when you want to use factory_girl with Rails. The existing factory_girl gem is used by factory_girl_rails and would be used if you’re using factory_girl outside of Rails. If you want to use factory_girl with Rails 2 you can continue to use the base factory_girl gem.
We just released Clearance 0.9.0.rc1. This is a release candidate for Clearance 0.9.0. This new version adds support for Rails 3 but drops support for Rails 2. Don’t fret, if you won’t be upgrading to Rails 3, you can use a previously released version of the gem (0.8.8). We’re doing this one as a release candidate because of the dropping of backwards compatibility and the fact that we haven’t had a chance to test the new version in a variety of Rails 3 apps using clearance.
Please flex this release candidate with your Rails 3 apps and let us know how it goes.
Suspenders is currently at 2.3.5 (we haven’t been able to upgrade to 2.3.8 because of bugs we’ve seen with mongrel, webrat, and rack). We anticipate that Suspenders will be upgraded to Rails 3 a little after Rails 3 final comes out. But to be honest, we’re actually not sure yet what the upgrade path will look like for applications that are currently tracking Suspenders. It may be impossible to do without so many conflicts that its not worthwhile. We’re going to have to work on this more and keep you posted. Additionally, we’re in the process of making some fairly dramatic changes to Suspenders. Watch it on github and stay tuned here for more.
Fire in the Disco! We’ve also released High Voltage 0.9.0 which supports Rails 3 and is now a gem (it was previously just a plugin). The new version also drops support for Rails 2. If you need the previous, Rails 2 plugin there is a rails2 branch you can retrieve it from.
We also just released Pacecar 1.3 which supports Rails 3 and drops support for Rails 2. As in the other cases where we’ve done this, you can use the previous version of the gem, version 1.2.0 with Rails 2, or track the rails2 branch.
Squirrel was born out of a desire to make a new query syntax that was dynamic while being clean and simple. With Rails 3’s introduction of the New Active Record chainable query language, that goal has now been achieved in Rails. As a result, we’ll no longer be maintaining Squirrel. It was a fun ride.
Over time, our workflow slightly changed for how we built applications and we haven’t used Mile Marker ourselves for some time now. As a result, we’re taking this opportunity to cease maintenance of this plugin and bid it farewell.
We’ve gotten more and more familiar with Rails 3 during moving all these gems to it. Many of the new features it offers are great, and existing features have been improved and cleaned up. We’re looking forward to Rails 3 finally being released in the coming weeks. Now that our plugins are up and running it should help us all to transition smoothly and quickly.
Thanks to the core team and various other railsconf attendees for spending time with us this week working on some of this - we’re looking forward to the final version of rails3!