Yeah, i’m looking forward meeting so many insane peoples again this year at the RailsConf Europe 2008 in September.
Looking forward to the RailsConf Europe 2008
Ruby on Rails testing with Shoulda
When i went to last year’s Rails Conference in Berlin, there were several peoples talking about test, that should not be called test. It started with the first talk about A Half-day of Behavior-driven Development on Rails. They said that calling tests test was a bad idea.
It really took me a long time to understand, why this is their opinion. We do write tests, so why should we not call them test?
Everything is about developers. Not everyone has the same opinion about naming methods or tests. As most documentation is stored in tests, what would you think about a test in UserTest named “test_username”? You get no information about what username should be working like.
Of course it’s not just the name “test”, you could easily just rename the test method (using test in the method name) to “test_username_can_not_be_changed”, but it would be easier to always have “should” in the name.
I’m currently building a CRM-system. This is really a huge task. Several thousand customers, with special contract, special data and special treatment. There’s a huge need for tests.
Of course, we used the fixtures to create the data for our tests. But as developers are, you just create the data, you need for your tests. So many of the customers don’t have real valid informations about themself. The data in the fixtures does just not represent the data that actually could happen in the real system.
Now, what’s shoulda?
Shoulda is a testing Test::Unit AddOn. It gives you a really neat way to create the data environment you need for your tests, and also helps you in a naming conventional way to have good testing names.
Here’s an example:
class UserTest context "A User instance" do
@user = User.create! :first_name => 'John',
:last_name => 'Doe'
should "return its full name" do
assert_equal 'John Doe', @user.full_name
context "with a profile" do
@user.profile = Profile.create! :role => 'admin'
should "return true when sent #has_profile?" do
So, what does this easy example show me?
You first create the environment (so named “context”) you need for your test. You start with a small context, like i need a user. Now you already can define some expectations that should be computed in this environment, like the full name should be given with the method “full_name”.
Within this context you can now create a more specific context. You can have your context growing with the need of special contexts as you want.
I think this is really a great thing. It’s really easier to define the context you need for this special test and using “should” you are forced to really describe, what you do expect in this kind of context.