Cucumber, a BDD framework and cuke4duke integrating it with Java
Cucumber is a BDD framework: you define the requirements of your software in plain text and then write tests that “execute” these requirements against the software. The difference from unit testing and TDD (where you write tests before code) is that the requirements are readable by non-technical people, and thus provide and executable documentation of how the application behaves. So it is not the code that is tested, but the application. For that, cucumber has integration with frameworks for in browser testing, httpunit etc. (see the cucumber source for many examples)
Cucumber is written in Ruby, it is interesting to note that it started as a port of a Java framework named Jbehave. The benefits of using Ruby is that tests are easy to write and the wealth of testing packages for testing various GUI frameworks. Using Jruby, one can write tests in Ruby that interact with Java classes (see example here)
Now cucumber comes full circle with cuke4duke, a bridge of cucumber to other languages on the JVM.
The project allows to run cucumber tests from an Ant or Maven build (read relevant documentation here and here). It also has API to write the tests in Java. Spring integration is also available.
The classic cucumber example for testing is one of a calculator.
Here are the requirements from a calculator (defined in features/addition.feature)
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press add
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | output |
| 20 | 30 | 50 |
| 2 | 5 | 7 |
| 0 | 40 | 40 |
Note how the requirements do not define whether the calculator is tested as a service (API), GUI app or web app. (other requirements may specify that).
The step definition (first in Ruby) however, needs to know that (in this case testing a simple class):
require 'spec/expectations'
require 'cucumber/formatter/unicode'
require 'calculator'
Before do
@calc = Calculator.new
end
Given /I have entered (\d+) into the calculator/ do |n|
@calc.push n.to_i
end
When /I press (\w+)/ do |op|
@result = @calc.send op
end
Then /the result should be (.*) on the screen/ do |result|
@result.should == result.to_f
end
Cucumber will iterate over each example in the requirements and feed the values to the Given, When and Then sections.
Note that in this example, the calculator is written to be perfect for the test because we push two numbers and then send the operator. If on the other hand the calculator would have had only an add(num1,num2) method, then the test would have saved the values in local variables and invoke the method in the Then clause.
At this point we can use Cucumber to test Java code by running it with Jruby.
If we want to write the test in Java, then we create a Java file in src/test/java:
public class CalculatorSteps{
private Calculator calc;
private String result;
@Before
public void setup() {
calc = new Calculator();
}
@Given("I have entered (\\d+) into the calculator")
public void enterNumber(int n) {
calc.push(n);
}
@When("I press (\\w+)")
public void calculate(String op) {
if ("add".equals(op)) {
result = String.valueOf(calc.add());
return;
}
throw new RuntimeException("Unknown operator " + op);
}
@Then("the result should be (.*) on the screen")
public void checkResult(String n) {
assertEquals(n, result);
}
}
Some notes abou Maven:
- The dependencies on cucumber related packages are defined in the 'test' scope (the documentation lists them as regular dependencies)
-
To work with other Ruby testing frameworks, their gems should be installed. Ruby gems are packages much like rpm or deb that can be installed site-wide so they become available to other packages. To add gems, use <gems> list in the plugin configuration. For example, to use Celerity (a jruby wrapper around HttpUnit), add:
<gems>
<gem>celerity:0.0.7</gem>
</gems>
- ittayd's blog
- Login or register to post comments
