If you focus on testing your classes, then the structure of your test code mirrors the structure of your production code. What happens when you re-factor and you change that structure? do you then rewrite your tests? If you focus on behavior you don’t have to. When you re-factor, the behavior of your application doesn’t change. Get away from state based testing. If you depend on specific variables in your code, the inner state of your application, it will be a barrier to refactoring. Instead of focusing on assertions, set expectations. One of the frameworks which uses this style of Behavior Driven Development is the Cucumber framework.
1.You will need to gem install cucumber on rails first.
> gem install cucumberrails
2. Cucumber needs capybara or webrat driver to work. Run the following command and the required cucumber environment will be installed:
> rake RAILS_ENV=cucumber gems:install
(For debian/ubuntu users) If the above line gives any error like “libxslt is missing, try port install libxslt
or yum install libxsltdevel“, then try the following command:
> aptget install libxml2dev libxslt1dev
3. Cucumber needs to add a few files to your application. If you are running these tests for unit testing then you need to add a testunit suffix. Also, give the capybara if capybara is installed
> script/generate cucumber capybara –testunit
If webrat is installed then run the following command:
> script/generate cucumber webrat –testunit
After installing cucumber for your application, you will see a new folder called features. This features folder has 2 subfolders named step_definitions and support. Testcases or features
must be written in a file inside the features directory with a .feature extension. These features include steps which are to be defined in a file inside the step_definitions folder. The step_definitions folder also contains a file called web_steps.rb which contains some predefined steps. The support folder contains 2 files namely env.rb which contains the various environments which are being used by the currently installed cucumber and paths.rb which maps a name to the path used by step_definitions.
Steps and Step Definitions:
A step is analogous to a method or function invocation in C,C++ and other scripting languages. Steps are declared in your features/*.feature files.
Given I have 93 cucumbers in my belly.
A step “calls” a step definition.
Step definitions are defined in ruby files under features/step_definitions/*_steps.rb
Given /^I have (\d+) cucumbers in my belly$/ do |cukes|
# Some Ruby code here end
A line starting with keyword Feature followed by free indented text starts a feature. A
feature usually contains a list of scenarios.
You can write whatever you want up until the first scenario, which starts with the word Scenario.
Every scenario consists of a list of steps, which must start with one of the keywords Given, When, Then, But or And. Cucumber treats them all the same, but you shouldn’t.
Given: A known state before the user (or external system) starts interacting with the system.
When: Describes the key action the user performs.
Then: Observes outcomes.
Eg: The following code must be entered in the feature/*.feature file:
Feature: Serve coffee in
order to earn money
Customers should be able to
buy coffee at all times
Scenario: Buy last coffee
Given there are 1 coffees left in the machine
And I have deposited 1$
When I press the coffee button
Then I should be served a coffee
For each step in the scenario, Cucumber will look for a matching step definition.
A step definition is written in Ruby. Each step definition consists of a keyword, a string or a regular expression and a block. The following code must be entered in the features/step_definitions/*_steps.rb file:
Given /there are (\d+) coffees left in the machine/ do |n|
@machine = Machine.new(n.to_i)
Then “I should be served coffee” do
@machine.dispensed_drink.should == “coffee”
The outcome of an application which was developed using Behaviour Driven Development may not be more efficient, nor can it have fewer bugs when compared to an application which was developed and well tested using the usual Test Driven Development. BDD only helps you keep track and plan on how the code you are going to write will or must behave.
Source: Railscarma Blog