Friday, August 31, 2012

Cucumber more deeply ...

Cucumber's strength is the ability to write the feature descriptions in plain text and also possible in your native language. Feature is usually a user story. When all scenarios in a feature file is passing, it tells that the story is done. The format of the feature file is:

feature: <short description>

<full description>

background:

scenario:

...

scenario outline:

examples:

...


The feature file starts with a description of the feature. The format of the description is free, but usually e.g. following template is used:

In order to ...
as a ...
I need to ...

For example:

Feature: Application sign-in

In order to sign in
as an end user
I need to enter valid credentials

After the description comes the background. The background contains the preconditions for all scenarios. The format of the background is similar to the format of the scenarios, but the only difference is that the steps in the background will be executed before each scenario. It could for example, be like this:

Background:
   Given a registered user

Then comes the scenarios or scenario outlines. A scenario is like one test case. A scenario is made up of three steps: Given, When and Then.

Given is the precondition for the test case.
When is the action to be taken.
Then is the verification / what should happen.

For example:

Scenario: Successful sign-in
   Given sign-in page to the application
    When I enter valid credentials
     And click on the sign-in button
    Then I'm successfully logged in
     But no error text should be displayed

Notice that And or But can be given in any of these three steps.

The other possibility is to use a scenario outline. It could look like this:

Scenario outline: Application sign-in
   Given  sign-in page to the application
    When I enter username <username> and password <password>
     And click on the sign-in button
    Then I'm <loginstatus> logged in

Examples:
| username    | password   | loginstatus  |
| validuser   | validpwd   | successfully |
| invaliduser | validpwd   | not          |
| validuser   | invalidpwd | not          |

When running the feature, the scenario will be repeated with the values in each row in the examples table. So in this case the scenario will be repeated four times.

You could also have many examples tables for one scenario outline e.g.

Examples: Successful logins
| username    | password   | loginstatus  |
| validuser   | validpwd   | successfully |

Examples: Failed logins
| username    | password   | loginstatus  |
| invaliduser | validpwd   | not          |
| validuser   | invalidpwd | not          |

Now if you save your feature file and run it, you will get an output similar to this:

1 scenario (1 undefined)
5 steps (5 undefined) 

You can implement step definitions for undefined steps with these snippets: 

Given /^sign-in page to the application$/ do 
 pending 
end 

When /^I enter username validuser and password validpwd$/ do
 pending 
end

When /^I enter username invaliduser and password validpwd$/ do
 pending 
end

...

This tells that there are five missing step definitions i.e. you need to have matching step definitions for each line in the feature file in your step definition file. To get started with your step definitions file, copy the above pending step definitions to your step definitions file. The next thing I would do is to combine / group step definitions. As you can notice the step definitions:

When /^I enter username validuser and password validpwd$/ do
 pending 
end

When /^I enter username invaliduser and password validpwd$/ do
 pending 
end 

... are very close to each other. They could be combined to one step definition:

When /^I enter username (.*) and password (.*)$/ do |user,pwd|
end 

After this you need to insert the actual test script code in each step definition. It is also possible to call another step definition from within a step definition e.g.

When /^I enter username (.*) and password (.*)$/ do |user,pwd|
   step "I enter valid credentials"
end 

There are still a couple of things that you need to / is good to know - tags and hooks


Tags


In your feature file you can add tags. Tags are strings starting with @ e.g.

@highpriority
Scenario: ...

If you now wan't to run all scenarios tagged with @highpriority, you can do it like this:

cucumber --tags @highpriority

If you wan't to run all scenarios, except those ones tagged with @highpriority:

cucumber --tags ~@highpriority


Hooks

With the help of hooks you can run some specific script code in different places during the test runs. There are many predefined hooks available in Cucumber. Hooks are defined in files in the support folder, usually env.rb or hooks.rb.

To do something before starting to run any scenario, put that code at the top of the file. To do something when the run ends, use the at_exit hook. To run some code before or after a scenario, use the Before or After hooks. You can also execute some specific code after each step with the AfterStep hook. It is also possible to run different code if scenario passes or fails:

Before do
 # Do something before each scenario
end
 
After do |scenario|
   if(scenario.failed?)
      # Do something if scenario failed
   end
   if(scenario.passed?)
      # Do something if scenario passed
   end 
end 

Then there is also possibility to use tagged hooks i.e. just execute some code for tagged scenarios. For example.

After('@highpriority', '@mediumpriority') do
 # Do something after scenarios tagged with @highpriority OR @mediumpriority
end
 
Before('@highpriority, @mediumpriority') do 
 # Do something before scenarios tagged with @highpriority AND @mediumpriority
end
 

No comments:

Post a Comment