Tag: bdd

Meet RSpec: Your Friendly, Neighborhood BDD Framework


Hope Ol’ Stan Lee doesn’t have that “friendly, neighborhood” bit trademarked… ah well… life is to short to worry about such things.

Welcome to your whirlwind tour of RSpec, a Behavior Driven Development framework for Ruby and Ruby on Rails. I debated with myself on how best to start this series of tutorials, and eventually decided to take a breadth-first approach, i.e. dump it all in your lap and break it down from there. So this first post we’ll cover just what RSpec is and what it can do for you and your code.

Since RSpec is simply an implementation of Behavior Driven Development, you’d be best served to read my previous post An Introduction to Behavior Driven Development first, if you don’t know what that is.

Getting back to RSpec. RSpec, in addition to being an implementation of BDD, is more specifically, a DSL, or Domain Specific Language. Which, itself, is a fancy way of saying that it is a programming language designed for a specific purpose or task: namely, the task of specifying the behavior of an application. The programming language part may be a bit obtuse in meaning; it’s not another C or Java or VisualBasic. However, it does introduce a new ‘language’ in Ruby that is specific to defining application behavior.

Now that you know what it is, let’s get to the fun stuff and see what it can do.

I’ve already stated that RSpec’s purpose is to specify the behavior of an application. More to the point, RSpec provides a way for us to set down in stone exactly what our application should do and how it should behave. Notice the emphasis on ’should’. ‘Should’ is a crucial focal point of BDD and it’s how RSpec makes its assertions.

For example, if I wanted to specify that a post should have a title, I would write something a little like this:

describe Post do
before(:each) do
@post = Post.new
end

it “should have a title” do
@post.title.should_not be_blank
end
end

There’s actually quite alot going on there, so let’s break it down.

We start with creating a describe block, which encapsulates our specification. The part right after describe is the name of the class we are describing, in this case: Post.

Then, we have a before(:each) block, which acts as a setup method or initializer for the specification. The :each specifies that we want the following instructions performed for every example. Inside this block, we store a new instance of the Post class in the instance variable, @post.

Next, we add an it block, which tells RSpec we’re starting an example. The example, itself, is everything between the do and end. The string after it, “should have a title”, is purely informational. You could even leave it out. In which case, RSpec would automatically generate a description of the example based on what is inside. In this case, that would end up being, “title should not be blank”.

Inside the it block, we have the real meat of our example. We access the title attribute and specify that it should_not be_blank.

should_not is a method RSpec extends the superclass Object with; should_not and it’s positive version should will both return true or false, resulting in either a pass or fail, respectively, for our example.

be_blank is bit of a different beast. It is not a method itself, but rather signals to RSpec to call the blank? method on our title attribute. blank?, by the way, is an innate method (exists out of the box) that returns true if the variable in question is either an empty string or nil.

Every example you code in RSpec will have at least one statement with should or should_not. The be_whatever part is just one of many different possible arguments (matchers) for these two methods. Let’s look at the full list:

Eql and Equal

RSpec has two levels of equality checks. First, you can use eql or the standard equality operator ==. For example:

"this string".should eql "this string" or "this string".should == "this string"

Second, you can check for equality at the object level with equal or the “three equals” operator ===. For example:

25.should equal 25 or 25.should === 25

However, note:

"this string".should equal "this string" and "this string".should === "this string"

Both of these will actually evaluate to false. To understand why you could run script/console and try the following:

$ ruby script/console
Loading development environment.
>> "this string".object_id
=> 106148390
>> "this string".object_id
=> 106145680

Even though it’s the same string, each instance has a unique object id. The example using 25 works because of the following:

$ ruby script/console
Loading development environment.
>> 25.object_id
=> 51
>> 25.object_id
=> 51

The technical explanation is that 25 is instantiated as a Fixnum, so every instance of 25 afterwards is actually a reference to the first instance of 25. However, strings and most other objects in Ruby receive unique ids for every instance.

Have

Quite often, you’ll want to ensure that a collection has at least a certain number of items: ensuring there are no validation errors on a particular field in a form, for example. RSpec provides an easy way to specify the behavior you want with have. For example:

day.should have(24).hours

It should be noted that in order for this to work, day would have to own a collection, hours, with 24 items. This is really just shorthand for the following:

day.hours.should have(24).items

RSpec provides some “sugar” with have so that both of the following will work without any further implementation:

[1, 2, 3].should have(3).items and "fun".should have(3).characters

Additionally, some things in RSpec exist simply for the purpose of readability. One example of this is have_exactly, which is just an alias for have. So, the code above could be be rewritten as:

day.should have_exactly(24).hours

Either way works; it’s simply a matter of preference.

Often, you won’t be entirely sure about how many items you should have, but you will know a minimum or maximum. Once again, RSpec comes through with have_at_least and have_at_most. For example:

blog.should have_at_least(1).post or question.should have_at_most(4).answer_choices

Include

Closely related to have, we have include. Whereas, have concerns itself with the number of items in a collection, include concerns itself with the collection’s values. For example:

{ :str1 => 'first string', :str2 => 'second string' }.should include('second string')

The above would pass because the value ’second string’ exists in the the collection. You can even specify multiple values as such:

[1, 2, 3, 4, 5].should include(1, 3, 5)

However, when you specify multiple values for the include all of those values must be present in order for the example to pass. The following would fail, since 6 is not present in the array:

[1, 2, 3, 4, 5].should include(2, 4, 6)

Match

RSpec provides the ability to match based on regular expressions through the match matcher. Like eql and equal before, there’s you can also the use the operator equivalent, =~. For example:

"sample string".should match(/sample/) or "sample string".should =~ /sample/

Predicates

The previous matchers have all been methods specific to RSpec. The true power of RSpec comes from letting you apply its behavior-specific language to your own methods. It does this via various prefixes. We encountered one of these earlier with be_blank. As we saw, the actual method being called is blank?, but by prefixing it with be_ we can not only instruct RSpec to call this method, but also maintain nicer readability. Here are some other common uses of the be_ prefix:

be_true
be_false
be_nil
be_blank
be_empty
be_an_instance_of(Class)
be_a_kind_of(Class)
be_close(expected, delta)

Each of the above rely on built in Ruby methods, but you can also apply this to any other predicate. What is a predicate? Predicates are methods that end with ?’s and return true or false. It could be one built into Ruby or Ruby on Rails, or it could be one of your own creation. Consider the following:

# method defined in User class
def admin?
self.role == ‘admin’
end

# example from User spec
@user.should be_admin # will pass if @user.role == ‘admin’

Also, notice the two matchers above, be_a_kind_of and be_an_instance_of. These respectively call the methods kind_of? and instance_of?. The prefixes be_a_ and be_an_ are aliases of be_, provided for better readability.

In addition to the be_ prefix, RSpec also provides the have_ prefix. Note, however, that this is not the same as the have matcher mentioned above. It’s also not a prefix in the truest since, but the best way to explain is with an example:

{:fun => 1, :times => 2 }.should have_key(:fun)

In this example have_key signals RSpec to call the predicate has_key? built into Ruby. This will work with any predicate starting with has_ as well. For example:

# defined inside a Chicken class
def has_feathers?
self.feathers > 0
end

# example inside the Chicken spec
@plucked_chicken.should_not have_feathers # passes if @plucked_chicken.feathers == 0

Is that it?

There’s a few other matchers that I have intentionally not mentioned yet: only because they are a little more abstract in nature. We’ll eventually get to all those as we continue through this series.

The next article up will detail the process of spec’ing a model. I haven’t completely decided on an example application yet, but I have a couple ideas.

  • Del.icio.us
  • Digg
  • Facebook
  • Google Bookmark
  • StumbleUpon
  • Technorati

Rails, RSpec, Autotest, Redgreen, and Snarl: Reasons I don’t like Windows

In preparation for an article I’m writing on RSpec, I decided to revisit setting up my preferred RSpec development environment in Windows. I was ever so quickly reminded of why I made the switch to Linux in the first place.

The Background

Let me get everyone caught up to speed. RSpec is of course a Behavior Driven Development framework for Ruby and Ruby on Rails. The Behavior Driven Development process itself involves writing a specification (test), running that specification (which will initially fail), writing the functionality to satisfy that specification, and finally running the specification again which should then pass. This process continues until you’ve implemented all the functionality in the application you are developing.

Now, if you run all the specifications manually, this can get really bothersome very quickly. This is particularly aggravated in a Windows environment, since all the common Rails tasks (rakes, generations, migrations, etc.) seem to take twice as long as they do in a Linux or OSX environment. Even under Linux or OSX, though, the frequency of running specs tends to slow down the production cycle incredibly when run manually.

Thankfully, there’s ZenTest and more specifically the autotest functionality of ZenTest. Autotest watches for file changes and then automatically runs any specs or tests that have changed. Combine this with the color-coding provided by Redgreen and a notification system (Growl, KDENotify, Libnotify) and you have a very effective Behavior Driven Development environment.

The Specs

There is strong indication that all of the issues I have noticed are version dependent (i.e. broken in newer versions), so it makes sense, then, to provide the specs of the various gems and plugins I’m using for these tests:

  • Windows XP SP2
  • Ruby 1.8.6
  • Rails 1.2.3
  • ZenTest 3.6.1
  • RSpec 1.0.8
  • Spec:Rails 1.0.8
  • Redgreen 1.2.2
  • Ruby-Snarl 0.0.8
  • Snarl 1.6

The Issues

But then there’s Windows. On the surface, it looks as though the same should be possible here. We can develop Rails apps in Windows. RSpec, Autotest, and Redgreen are operating system agnostic. There’s even a fairly mature notification system for Windows in Snarl. So what’s the problem? Well, when you put all of these together, it explodes.

I did a good bit of trial and error debugging tonight trying to pin down the exact problem, and while I was ultimately unsuccessful, I was able to notice certain trends which, to a more apt Rubyist, may spark an idea for a solution. So, for posterity, I want to post my findings in the hope that someone can figure out what is wrong.

Autotest and Redgreen

A great deal of work has been done to integrate RSpec and Autotest, and in Linux and OSX, the two play very nicely together with little to no configuration. In Windows, however, Autotest initially hangs when trying to read the specs. The only way I could find to get Autotest to actually run the specs through, was to remove everything from the spec.opts file in the spec directory of the app in question.

Unfortunately one of the lines in the spec.opts file is the “–colour” option which sets up the color-coding of passes and failures. I did quite a bit of research online, and found many articles which tell you that you must install the redgreen gem in order to get color-coding on your tests. However, this seems to be outdated information since both Autotest and RSpec seem to come with this functionality out of the box, now (assuming you have installed the win32console gem to make it work in Windows). Indeed, even without the redgreen gem installed, if I simply ‘rake spec’ the color-coding is there.

So, after realizing that I could not rely on this out of the box functionality in Windows, I tried the alternate route of installing the redgreen gem and then requiring it in a ‘.autotest’ file in my RAILSROOT (require ‘redgreen/autotest’ along with require ‘Win32/Console/ANSI’). However, this resulted in autotest erroring-out on load complaining of an ‘Invalid Option: -O’.

I then realized that Autotest has a redgreen plugin of its own, which can be reference as flip-flop of the previous require for the redgreen gem (i.e. require ‘autotest/redgreen’). So I uninstalled the redgreen gem, changed the require in .autotest, and ran autotest again. This time it loads fine, but without color-coding still. Finally, just to be thorough, I reinstalled the redgreen gem in the hopes that it still somehow provided some functionality for the autotest plugin of the same name. However, this two proved fruitless. Autotest still ran successfully, but still without color-coding.

Autotest and Snarl

At this point, I gave up on having nice color-coded test results. Snarl, I thought, can be setup to provide all the visual indication necessary, so I began to work on the Snarl side of things. I already had Snarl installed, so I went ahead and installed the ruby-snarl gem which sets up the connectivity. Then, I opened my .autotest file once more and added the require for snarl (require ‘autotest/snarl’). Time to test it out, so I went to my command line, ran autotest once more, only to see Snarl pop up with a notification window saying all tests had passed, while autotest simultaneously informed me that I had two failures. This is pretty much where I stopped because I have no idea where to even begin to troubleshoot Snarl.

The Summary

In the end, the only thing I could get to work was plain-jane autotest, which is better than nothing but not by much. Through all the digging I have done online, the only thing I can determine definitively is that at one point it was possible to integrate all of this in Windows. However, this was before both Autotest and RSpec added in their own implementations of Redgreen. The Snarl issue is even stranger, and I’m not sure if it is a related issue or something entirely separate.

The ironic part is that it appears that it has been so for quite some time, and no one is either using Windows to notice it, or cares enough to fix it if they have noticed it. Which gives even greater weight in my mind to simply abandon Windows for Rails development, preferring Linux or OSX. Obviously, OSX would be the optimum choice, but for those of us still on PCs, Linux is as close as you can get.

  • Del.icio.us
  • Digg
  • Facebook
  • Google Bookmark
  • StumbleUpon
  • Technorati

An Introduction to Behavior Driven Development

The logical starting point would be to define what Behavior Driven Development is, but it’s difficult to jump right out and explain exactly what it is, until you first explain what it is not. To do that, I’ll have to digress a bit, and discuss Test Driven Development.

Some of you who read this will likely already have a good grasp of what Test Driven Development is, so you can skip on to the next section. However, for those who, like me, put the cart before the horse on a regular basis, read on.

Test Driven Development

Test Driven Development is a programming methodology, which has gained quite a bit of ground in the software development world. The old practice was to jump into your code, develop all the features of your application, and assume that you are a coding god and did everything correctly. Those who were wise enough to recognize their mortality, would test their code at the end of the development process, but there were still problems inherent in this approach. First, since testing was at best an afterthought, many times it was never completed or not every aspect of the system was tested. Second, testing was expensive, both in terms of dollars and time. Good code went through planning and implementation phases already, so testing simply added a third layer to the process requiring further resources. Test Driven Development counters this old rationale by saying let the test define the system, rather than the system defining the tests. Essentially, then, planning becomes merged with testing, saving an extra phase in development.

So, the heavenly choir sings out in loud chorus and all is right with the world, correct? Not exactly. While the ideal of Test Driven Development was brilliant, its implementation left much to be desired. Everything still centered around the idea of a test, and because of that, the tests were still at least partly defined by the system. Put another way, although tests were being used to define the system, they were still tied to the system itself. If for some reason, the system had to change, any associated tests would start to fail. At that point, the developer is forced to rewrite the tests and we’re right back where we started, testing after implementation.

Behavior Driven Development

Enter Behavior Driven Development. Behavior Driven Development is not a departure from Test Driven Development, but rather, a refactoring thereof. Where Test Driven Development is about proving a piece of code works, Behavior Driven Development is about describing what a piece of code should do. It’s a subtle difference, but an important one. It’s a move from verification to specification, from testing state to testing interactions.

Process

So how does Behavior Driven Development work? It begins with a specification. A specification is an executable description of some functionality in a system. The term “executable” is used here because specifications are in fact written via executable code. However, I like to think of it based on a close synonym: actionable. A specification is an actionable description of some functionality in a system.

I should be able to take my specification and write the code for that functionality in the system with no further information required. More to the point, anyone should be able to take my specifications and implement the same system I have created. We are in fact “specifying” what our application does, how it acts, and how it behaves.

Once our specification is in place, it can be run, resulting in a failure. Failure has a negative connotation in most areas, but in Behavior Driven Development, a failure is a good thing. Nothing has been implemented yet, so the specification fails. This is a call to action. Now it’s time to implement the behavior. Having done so, the specification is run again, and this time it passes. Hooray!

The approach sounds simplistic, but it is in fact extremely powerful. Because we have developed in this way, we can now make some confident assertions. First, we have accomplished something. Our application now has functionality where before it had none. Second, we know that the code is correct and bug free. Finally, and most importantly, we know that our application does exactly what it should do.

With that surety firmly in place, we write another specification, watch it fail, implement the behavior, watch it pass, and so on. Not only does this process grant confidence every step of the way, it also serves to break down our application into manageable bits. The focus shifts from developing an entire application to developing pieces of functionality that come together to make an application.

In Conclusion

That does it for my introduction to Behavior Driven Development. I have intentionally tried to stay away from both a technical and a philosophical approach to discussing this concept for two reasons. First, others have already done that better than I can, and second, I wanted to convey the true value of using the methodology. In my next post, I’ll begin looking at rSpec, a Ruby framework for Behavior Driven Development.

  • Del.icio.us
  • Digg
  • Facebook
  • Google Bookmark
  • StumbleUpon
  • Technorati