bdd

Cucumber World with Groovy

Monday, May 3rd, 2010 | Uncategorized | 7 Comments

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.

Feature: World
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.

// hello_steps.groovy
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.

// env.groovy
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).

Tags: , , , , ,

A Cucumber Scenario for Session Fixation Attacks

Tuesday, March 16th, 2010 | Uncategorized | No Comments

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 org.openqa.selenium.By
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.

Tags: , , , , , , ,