bdd
Cucumber World with Groovy
Cucumber provides the ability to create a world in which you can expose useful methods for the testing environment. This post briefly details how to expose these methods when using Groovy with Cuke4Duke.
In order to make useful methods available
As a tester
I want the world to be full of wonderful methods
Scenario: Greet
When I greet
...
Scenario: Farewell
When I farewell
...
These scenarios capture the ability to greet and farewell our customers. The matching step definitions are shown below.
import static org.junit.Assert.*
import static org.hamcrest.CoreMatchers.*
this.metaClass.mixin(cuke4duke.GroovyDsl)
When(~'I greet') {
assertThat(hello(), is('hi'))
}
When(~'I farewell') {
assertThat(goodbye(), is('ciao'))
}
You will notice that we haven’t defined the hello() or goodbye() methods anywhere in our step definition file. We are assuming these methods are provided by the world environment that Cucumber provides. This allows the world methods to be shared between many different step definition files.
Next we define the world environment. Instead of defining all methods in a single class, we can group the methods into individual classes and make them all available on the world class at runtime using Groovy’s mixin support.
this.metaClass.mixin(cuke4duke.GroovyDsl)
class Greeter {
def hello() {
'hi'
}
}
class Fareweller {
def goodbye() {
'ciao'
}
}
class World {}
World() {
World.mixin Greeter, Fareweller
new World()
}
The World() call is part of Cucumber’s DSL, here we use it to publish an instance of our World class thus making both hello() and goodbye() available in the testing environment (note that the name of the World class is not important).
A Cucumber Scenario for Session Fixation Attacks
When working on a Spring project I was alerted via the logs that my login handling was susceptible to Session Fixation Attacks. It was nice of Spring to alert me of this, and it seems like the problem is due to the Apache httpd connection via mod_jk. But before diving into a solution I decided to write a simple acceptance test using Cucumber. This allows me to first prove the security hole is present, easily tell when I have fixed it and has the additional benefit of being able to add the check to a set of automated regression tests to ensure it never happens again.
The countermeasure built into Spring uses the Identity Confirmation technique. This basically involves invalidating a user’s session when they login and creating a new session with a different JSESSIONID. It turns out to be fairly easy to write a test for this in Cucumber. Firstly I wrote the plain text scenario:
Scenario: Avoiding Session Fixation Attacks through Identity Confirmation Given I have a session ID When I sign in Then I should have a different session ID
The next step is to write the step definitions. Cuke4Duke provides Cucumber support for JVM languages and makes it easy to write reusable step definitions. As I’m a fan of the expressiveness of Groovy I chose to write the step definitions using the GroovyDsl.
import static org.junit.Assert.*
import static org.junit.matchers.JUnitMatchers.*
import static org.hamcrest.CoreMatchers.*
this.metaClass.mixin(cuke4duke.GroovyDsl)
def sessionId
Given(~'I have a session ID') {
browser.get("$host/signin")
sessionId = getSessionId()
}
When(~'I sign in') {
def signinForm = browser.findElement(By.name('signin'))
signinForm.findElement(By.name('j_username')).sendKeys('testing@example.com')
signinForm.findElement(By.name('j_password')).sendKeys('123456')
signinForm.submit()
}
Then(~'I should have a different session ID') {
assertThat(getSessionId(), is(not(sessionId)));
}
def getSessionId() {
browser.manage().cookies.find() { it.name == 'JSESSIONID' }.value
}
The browser variable is injected via env.groovy as an instance of WebDriver which provides the methods to find elements and manage cookies.
def sessionId simply declares a variable allowing sharing of state between the steps so we can check the session ID has been changed.
Search
Subscribe
Recent Posts
Tags
Archives
- I tend to print more and more emails these days... a sign of old age? 1 week ago
- Checking out slides on "Every day groovy" by @mr_paul_woods via @grailspodcast http://slidesha.re/9u3yrN 2 weeks ago
- Set up a twitter team account (@rickrollingnz) for our crazy trip through India in a Rickshaw, hoping to tweet from mobile as we go! 2 weeks ago
- More updates...