Category Archives: Archived

Migrated to blog.brasskazoo.com

OpenOffice 3.3 with HSQLDB via JDBC

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

I had developed an application that stored some metrics in a HyperSQL database for offline processing and reporting with OpenOffice.

It seemed simple enough – OpenOffice would connect to the database via JDBC, with the JDBC URL and driver class..trouble was, no matter what I did, the driver class would not be recognised!

After endlessly searching on the web for a solution, I realised the piece of the puzzle I was missing – the version of the hsqldb jar file. The version 2.0.0 jar appears to be incompatible with OpenOffice 3.3 – Reverting back to 1.8.0.10 solves the problem, and the JDBC driver class is recognised.

So I’ll publish the process in full here, just in case anyone else runs into the same problem!

Components:

  • OpenOffice 3.3.0 (The latest stable at the time of writing)
  • hsqldb-1.8.0.10.jar
  • An existing hsql database (created using hsqldb 1.8.0.10 jars)

OpenOffice Configuration

Despite OpenOffice using hsqldb for it’s internal databases, the driver is not natively available for JDBC.

Under Preferences > OpenOffice.org > Java, ensure that a JRE is registered. Open up the classpath dialog, and add an archive entry for the hsqldb jar

OpenOffice Java Config

OpenOffice Java and Classpath Configuration

This is basically where I had been running into trouble. My application originally used hsqldb version 2.0.0 with Hibernate. Despite the driver class being the same (org.hsqldb.jdbcDriver), it seems OpenOffice would not recognise this version of hsqldb.

Connect OpenOffice to Database

Using OpenOffice’s Database, select Connect to an existing database (using JDBC).

Enter the JDBC Connection details:

  • URL: The JDBC URL minus the ‘jdbc:’ – should be of the form hsqldb:/path/to/database – also append ;default_schema=true to the end.
  • JDBC driver class is: org.hsqldb.jdbcDriver

Note that ‘database’ is the collective database name for the files making up the hsqldb instance (e.g. database.log, database.properties, database.script).

OpenOffice JDBC Connection

HSQLDB JDBC Connection

Click ‘Next, enter the default username of sa (No password required).

Accept the defaults for registering the database, choose a location to save and you’re done!


If anyone has an explanation of the OpenOffice incompatibility, please leave a comment!

Advertisements

A Quick Spring Security Lock-Down

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

My new shiny web application is fantastically useful, but only to a certain group of people (i.e. my team), and should only be accessible by them.

So, before being able to put it into real production, I needed a security framework around it.

A legacy JAAS component of ours exists, but given my application was making use of the Spring framework, I compared Spring’s offering to the JAAS infrastructure.

Popular opinion seems to be that JAAS was build for J2SE, not J2EE, and is designed for things at a much ‘lower level’ than web applications, such as client-side applets rather than server-side applications.

Maven

First things first: Maven dependencies.

I’m using spring-webmvc 2.5.6, so I’d like to get security working with the application as it stands now – the latest pre-3.0 release of spring-security is 2.0.6-RELEASE:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>2.5.6</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-core</artifactId>
  <version>2.0.6.RELEASE</version>
</dependency>

web.xml

The web context requires two things:

1. Context location

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
  </param-value>
</context-param>

(we’ll create the security context in the next step)

2. Filter definition

<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

The url-pattern will mean all requests pass through the filter (which will have more explicit criteria).

Security Context

Now we get to the real meat of the security layer!

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                        http://www.springframework.org/schema/security
                         http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">

    <http auto-config="true">
        <intercept-url pattern="/**" access="ROLE_USER" />
        <http-basic />
    </http>

    <authentication-provider>
        <password-encoder hash="md5"/>
        <user-service>
            <user name="user" password="aabbccddeeff001122334455667788ff" authorities="ROLE_USER" />
	    </user-service>
	</authentication-provider>
</beans:beans>

Here we can see the configuration for http requests. The ‘auto-config’ sets the defaults (refer to the doco in the references), which are overridden by the contents of the tag. We’ll let in one user for now with the role ‘ROLE_USER’, defined in the authentication-provider section.

Including http-basic just puts the preference on using the basic HTTP prompt, but removing that line would use Spring’s default login page (with user/pass and ‘remember me’ checkbox).

And its done! Deploying the application and loading the page demands a login before progressing.

Next

Future improvements might involve setting up a styled login page, hooking up an LDAP connection (but with restrictions).
Oh, and Selenium tests..

References

Spring Source, Spring Security Reference Documentation <http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ns-config.html>
Peter Mularien, 5 Minute Guide to Spring Security <http://www.mularien.com/blog/2008/07/07/5-minute-guide-to-spring-security/>

Continuous Deployment: Deploying to Glassfish with Maven and TeamCity

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

A later stage of the continuous integration process – continuous deployment. The sooner we can deploy a tested and verified piece of software, the better!

Here I’m describing an automated deployment process that uses Maven to deploy to a Glassfish application server. TeamCity facilitates the build and test stages, with an additional deployment of the packaged web application. Using the glassfish plugin for maven 2, we can integrate the application server deployment into the continuous integration cycle, and provide a constantly up-to-date development/test environment.

Glassfish

I’ll create a new domain from scratch for the maven apps, using the default port values (i.e. admin port 4848, http port 8080), but setting the admin password and master password.

In setting up the glassfish domain we generate a password file so that we are not storing any passwords in plain text – such as in the pom or settings.xml

cd ${glassfish.home}/bin
./asadmin create-domain --savemasterpassword=true my-apps

the –savemasterpassword switch generates an encrypted ‘master-password’ file in the domains/my-apps directory.

Maven

Maven profiles makes it easy to have machine-specific variables so that moving to other platforms in the future is straightforward.

On the on the host machine I’ve created the file ~/.m2/settings.xml.

<?xml version="1.0" encoding="UTF-8"?>
xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <profiles>
    <profile>
      <id>glassfish-context</id>
      <properties>
        <local.glassfish.home>/Users/brass/bin/glassfishv3</local.glassfish.home>
        <local.glassfish.user>admin</local.glassfish.user>
        <local.glassfish.domain>my-apps</local.glassfish.domain>
        <local.glassfish.passfile>
${local.glassfish.home}/glassfish/domains/${local.glassfish.domain}/master-password
        </local.glassfish.passfile>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>glassfish-context</activeProfile>
  </activeProfiles>
</settings>

This gives us the parameters for the glassfish instance that we will use in our pom.

Update: I found that while the above works for v3.1, my dev machine’s glassfish v3.0.1 needed to reference glassfish home one directory deeper:

<local.glassfish.home>/Users/brass/bin/glassfishv3/glassfish
</local.glassfish.home>
...
<local.glassfish.passfile>
${local.glassfish.home}/domains/${local.glassfish.domain}/master-password
</local.glassfish.passfile>


In the project pom.xml, we define a profile for glassfish deployment:

<profile>
  <id>glassfish-deploy</id>
  <pluginRepositories>
    <pluginRepository>
      <id>maven.java.net</id>
        <name>Java.net Maven2 Repository</name>
        <url>http://download.java.net/maven/2</url>
      </pluginRepository>
    </pluginRepositories>
    <build>
      <plugins>
      <plugin>
        <groupId>org.glassfish.maven.plugin</groupId>
        <artifactId>maven-glassfish-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
          <user>${local.glassfish.user}</user>
          <passwordFile>${local.glassfish.passfile}</passwordFile>
          <autoCreate>true</autoCreate>
          <debug>true</debug>
          <echo>false</echo>
          <terse>true</terse>
          <domain>
            <name>${local.glassfish.domain}</name>
            <adminPort>4848</adminPort>
            <httpPort>8080</httpPort>
            <httpsPort>8443</httpsPort>
            <iiopPort>3700</iiopPort>
            <jmsPort>7676</jmsPort>
            <reuse>false</reuse>
          </domain>
          <components>
            <component>
              <name>${project.artifactId}</name>
              <artifact>
${project.build.directory}/${project.build.finalName}.war
              </artifact>
            </component>
          </components>
        </configuration>
      </plugin>
    </plugins>
  </build>
</profile>

The repository for the glassfish plugin repository is specified within the profile since its not part of the larger project in this case.

As you see the variables from the local settings.xml are used for the glassfish config.

TeamCity

The TeamCity setup needs to include two things in the maven2 runner config:

  • Glassfish goals
  • Profile parameters

TeamCity - maven runner configuration

The glassfish goals that are used should be able to start the domain if it isn’t running, and replace the application.

The ‘redeploy’ goal would allow a hot-swap deployment, if for example we were running other applications on the domain.

See the plugin page (http://maven-glassfish-plugin.java.net/) for more info.

Next

So now this process provides us with continuous deployment – a commit will be built, tested and deployed automatically, allowing changes to the software to be seen and used almost immediately!

How to load properties files into Spring and expose to the Java classes

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

Loading properties files in the spring configuration

The issue:

Our webapp is using a spring and hibernate backend, and both spring configuration and Java classes need to access database connection properties.

Currently there is an application.properties file and a spring applicationContext.xml, both which contain the same information for the database connection.

Ideally, there should be only one configuration file to define the properties, which is used by both spring and Java.

Spring has the ability to load properties files as part of the application configuration, for use internally. The properties can be referenced within spring configuration files using ant-style placeholders, e.g. ${app.var}.

To solve our issue though we’ll also need to provide a populated bean that can be used by our production classes.

Here’s the properties file (application.properties):

appl.name=My Web Application
appl.home=/Users/webapp/application/

# Database properties
db.driver=org.hsqldb.jdbcDriver
db.name=v8max.db
db.url=jdbc:hsqldb:file://${appl.home}/database/${db.name}
db.user=SA
db.pass=

Spring loads the properties file using a bean of the type org.springframework.beans.factory.config.PropertyPlaceholderConfigurer, and then we can reference the properties directly in the spring configuration file.

Note that we can also use placeholders within the properties file, as in the db.url above – the PropertyPlaceholderConfigurer will resolve them too!

    <!-- Load in application properties reference -->
    <bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:application.properties"/>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${db.driver}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.user}"/>
        <property name="password" value="${db.pass}"/>
    </bean>

So now we’ve removed the need to have literals in the spring config!

Exposing the spring properties bean in java

To allow our Java classes to access the properties from the same object as spring, we’ll need to extend the PropertyPlaceholderConfigurer so that we can provide a more convenient method for retrieving the properties (there is no direct method of retrieving properties!).

We can extend the spring provided class to allow us to reuse spring’s property resolver in our Java classes:

public class PropertiesUtil extends PropertyPlaceholderConfigurer {
   private static Map propertiesMap;

   @Override
   protected void processProperties(ConfigurableListableBeanFactory beanFactory,
             Properties props) throws BeansException {
        super.processProperties(beanFactory, props);

        propertiesMap = new HashMap<String, String>();
        for (Object key : props.keySet()) {
            String keyStr = key.toString();
            propertiesMap.put(keyStr, parseStringValue(props.getProperty(keyStr),
                props, new HashSet()));
        }
    }

    public static String getProperty(String name) {
        return propertiesMap.get(name);
    }
}

If we now update the applicationProperties bean to use the PropertiesUtil class, we can use the static getProperty method to access the resolved properties via the same object as the spring configuration bean.

Of course, we could run into problems if a class tries to use PropertiesUtil before the spring context has been initialised. For example if you’re registering ServletContextListeners in your web.xml before configuring spring, you’ll get a NullPointerException if one of those classes tries to use PropertiesUtil. For that reason I’ve had to declare the spring context before any context listeners.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Other listeners -->

References

  1. http://www.jdocs.com/spring/1.2.8/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html
  2. http://j2eecookbook.blogspot.com/2007/07/accessing-properties-loaded-via-spring.html

A cyclical dependancy anti-pattern: Identity Theft

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

Anti-patterns:

In software engineering, an anti-pattern (or antipattern) is a design pattern that appears obvious but is ineffective or far from optimal in practice.[1]

Or as I like to think of it, the type of code that makes you want to rip your eyes out, like in that movie Event Horizon

Identity Theft

Here’s a pattern that I have seen many times in a previous codebase, which I believe suffers from some design flaws:

FooListing is a class that retrieves and maintains a list of Foo objects.

Description

FooListing is a repository-type object that holds a list of Foo objects, which it populates from the database using its populate() function.

The Foo object also has a populate() method, but this method instantiates a FooListing, and uses the FooListing populate function with its key – so now the FooListing contains the desired Foo object.

Our original Foo object now contains a reference to the Foo object that it wants to be.  So it does what anyone would do, steals its identity and hides the body.

Foo.populate() looks something like this:

public void populate() {
  FooListing listing = new FooListing()
  // Set up FooListing
  FooListing.setSearchKey(id);
  if (listing.size > 0) {
      Foo foo = listing.get(0);
      this.setBar(foo.getBar);
      // continue to copy over properties
      // ...
  } else {
      LOG.warn("Foo not found for key: " + id);
  }
}

Why this is bad:

Firstly, apart from the questional morality, it is duplicated code. FooListing already has the capability to create and populate a Foo object from the database. Two locations for this code means twice the maintenance if something changes, (more than) twice the possibility of bugs, etc.

Foo and FooListing have become tightly coupled and dependant on each other under this design – there is a cyclic dependancy which is a code smell, and may cause headaches when writing unit tests.

There is also a waste of resoures creating the uneccesary FooListing and Foo objects inside of Foo.populate(), at least some of that could be avoided by client code accessing instances of Foo via FooListing.populate

It also doesn’t make sense that a data access object like Foo should be concerned with information about how it is created. Foo should act more like a bean, or an immutable class.

Another dangerous aspect of this design is the implication that client code accessing Foo cannot be certain that Foo has been instantiated correctly. If the client code has a faulty key for Foo that does not exist in the database, when it creates new Foo(key) there is no way to know that Foo.populate() has failed to find the correct value, and instead they are left with a faulty Foo instance which was not what they requested.

Solution:

The best solution for this isolated pattern is to completely remove (or deprecate) the Foo.populate() method, and replace calls to it with FooListing instances.

If FooListing fails to find a matching Foo, the client code should realise this when FooListing returns them a null object. The client code can handle and recover from this case in context.

Implementing a getFirstResult() function in FooListing could be beneficial if there are many cases where the code with otherwise be calling get(0).

We could also simplify the calling code so that retrieving a result is a one-line operation – i.e. get() calls populate() if the list has not already been populated.

public final class FooListing {
  private List<Foo> _listing;
  private int _id;

  public FooListing {
  }

  public FooListing(int id) {
    _searchId = id;
  }

  public void populate() {
    _listing = new ArrayList<Foo>();
    // Query the database and add to _listing
  }

  public Foo get(int index) {
    if (_listing == null) {
      populate();
    }
    if (_listing.isEmpty() || index >= _listing.size()) {
      return null;
    } else {
      return _listing.get(index);
    }
  }

  public Foo getFirstResult() {
    return this.get(0);
  }

  public List<Foo> getList() {
    return _listing;
  }

  public void setSearchId(int id) {
    _id = id;
  }
}

And the client code would only need to call

Foo foo = new FooListing(id).getFirstResult();

References:

1. http://en.wikipedia.org/wiki/Anti-patterns

Building a simple project using behavior-driven development with JBehave

IMPORTANT!
This post has moved to http://blog.brasskazoo.com!

In a previous post introducing BDD I outlined a simple bus ticket application. Since then I’ve been looking at JBehave, and thought I’d try building a simple version of the bus tickets project, using JBehave to support behavior-driven development of the application.

About JBehave

JBehave is a testing framework that takes the BDD concepts and applies it to JUnit tests, so you can effectively test your acceptance criteria directly using automated unit tests.

It uses BDD acceptance criteria as steps in a test case, and each Given/When/Then statement is interpreted and executed as a method. The acceptance criteria is simply stored in a text file which is read by JBehave when the test case is run.

Setting up JBehave

Download the distribution jars from http://jbehave.org (at the time of writing, version 2.3.2 is the latest), and extract it to a convenient location!

Set up references to the jars in your project (you need to reference at least hamcrest, junit-dep and jbehave-core for this example to work).

New project: ‘bus-tix’

For the purposes of this example, I’m creating a project I’ll call ‘bus-tix’, with production and test code packages.

The scenarios

Lets take one of the scenarios from my previous post (slightly modified):

Scenario: Inserting initial coins

Given that the application is operating
When a coin is inserted
Then ensure the time indicator displays the purchased time

I will use this as the behavioural spec for the initial work on the application. From the description of the scenario, we can instantly tell that we’re going to need a coin handler and time indicator as part of the application.

Now before I put this into a text file, I must point out that the default configuration of JBehave requires that the scenario files are named to match the class names of the test case – so if we had the test case InsertingInitialCoins, then the scenario text file must be named inserting_initial_coins (with no extension). I don’t particularly like this, so as you’ll see I modify the constructor so that I can call my scenario ‘inserting_initial_coins.scenario‘, to make it clear the purpose of the file.

We’ll need to create a test case, which extends org.jbehave.scenario.Scenario, and a ‘step’ class which extends  org.jbehave.scenario.steps.Steps. The step class will contain all the corresponding steps for the scenario file(s).

Scenario: Inserting initial coins

Given that the application is operating
 When a coin is inserted
 Then ensure the time indicator displays the purchased time

Create the test case class InsertingInitialCoins

package com.brass.bustix;

import org.jbehave.scenario.PropertyBasedConfiguration;
import org.jbehave.scenario.Scenario;
import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
import org.jbehave.scenario.parser.PatternScenarioParser;
import org.jbehave.scenario.parser.ScenarioDefiner;
import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;

public class InsertingInitialCoins extends Scenario {
    public InsertingInitialCoins() {
        this(Thread.currentThread().getContextClassLoader());
    }

    public InsertingInitialCoins(final ClassLoader classLoader) {
        super(new PropertyBasedConfiguration() {
            public ScenarioDefiner forDefiningScenarios() {
                return new ClasspathScenarioDefiner(
                    new UnderscoredCamelCaseResolver(".scenario"),
                    new PatternScenarioParser(this), classLoader);
                }
            }, new BustixSteps());
        }
    }

The default constructor calls the custom scenario file loader, so that we can append ‘.scenario’ to your scenario files. If I were creating several of these test scenarios, I would pull all that up to an abstract class to avoid re-writing those constructors.

Steps class (empty for now):

package com.brass.bustix;

import static org.jbehave.Ensure.ensureThat;
import org.jbehave.scenario.annotations.Given;
import org.jbehave.scenario.annotations.Then;
import org.jbehave.scenario.annotations.When;
import org.jbehave.scenario.steps.Steps;

public class BustixSteps extends Steps {
    // TODO – fill in steps
}

Make sure that the .scenario file is copied to your compile directory! Otherwise you will get the error like:

org.jbehave.scenario.errors.ScenarioNotFoundException: Scenario com/brass/bustix/inserting_initial_coins.scenario could not be found by classloader sun.misc.Launcher$AppClassLoader@133056f

When you run the test for the first time, you will see this output:

Scenario: Inserting initial coins
Given that the application is operating (PENDING)
When a coin is inserted (PENDING)
Then ensure the time indicator displays the purchased time (PENDING)

Perhaps confusingly, the test has passed despite the steps not being executed – PENDING means that the step hasn’t been executed because no corresponding method has been found.

Defining Steps

JBehave uses annotations to mark a method as a particular step. The annotation is the first word of the step we’re using, with the rest of the text as a parameter to that annotation. So for our first step ‘Given that the application is operating’ we reformat it as an @Given annotation:

@Given(“that the application is operating”)

And then JBehave knows that the function following that annotation is what needs to be executed for that step.

So now in BustixSteps we add:

@Given(“that the application is operating”)
public void startApplication() {
    ensureThat(false);
}

The assertion statement ensures that the test will fail – an empty test will pass (as it usually does with JUnit). The ‘ensureThat’ function comes from JBehave’s wrapping of hamcrest matchers – an interesting alternative to Junit’s assert statements. I won’t go into them right now.

Rerunning the test, we get the failure we want!

Scenario: Inserting initial coins
Given that the application is operating (FAILED)
 When a coin is inserted (PENDING)
 Then ensure the time indicator displays the purchased time (PENDING)

java.lang.AssertionError:
Expected: is <true>
got: <false>
...

Lets fill in the rest of the steps for this scenario while we’re here:

package com.brass.bustix;

import static org.jbehave.Ensure.ensureThat;
import org.jbehave.scenario.annotations.Given;
import org.jbehave.scenario.annotations.Then;
import org.jbehave.scenario.annotations.When;
import org.jbehave.scenario.steps.Steps;

public class BustixSteps extends Steps {

    @Given("that the application is operating")
        public void startApplication() {
        ensureThat(false);
    }

    @When("a coin is inserted")
    public void insertCoin() {
        ensureThat(false);
    }

    @Then("ensure the time indicator displays the purchased time")
    public void testThatTimeIsDisplayed() {
        ensureThat(false);
    }
}

At this stage, we’ve got our steps outlined for our basic scenario, and we can begin the test-driven  development of the application!

Note: when you have a scenario step that begins with an ‘And’, it is still considered as one of given/when/then, e.g.

Given that the application is operating
  And the time indicator displays nothing

..are both @Given annotations.

Next: check out the hamcrest matchers to make sure you’re getting the full potential from your asserts!

References

A brief introduction to Behaviour-Driven Development

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

Behavior-Driven Development (BDD) is a methodology developed by agile developer Dan North in 2006.

It was created on top of an existing methodology named Test-Driven Development (TDD), a fairly widely known and discussed technique. Put simply, TDD specifies that simple test cases should be written first, and the developer then writes the smallest amount of code possible to make the unit tests pass.

Whilst TDD is firmly in the realm of the developer, BDD attempts to bridge the gap between developers, testers, business analysts, and other stakeholders; it is closer to technical specifications than to simply unit tested code.

By developing a consistent vocabulary across groups, we work towards eliminating miscommunication and ambiguity. And by putting the emphasis on behavior, we are more closely working with requirement specifications and the business value of the product’s function.

Stories

Like many agile processes, BDD employs the concept of ‘user stories’ in the form of a narrative, but with a specific format to them.

Story: [Title]

As a [role]
I want [feature]
So that [benefit]

This format clearly identifies the actor, the system feature and the business value or benefit of the story.

Each story also has acceptance criteria, in a format similar to this:

Scenario 1: [Title] 

Given [context]
  And [some more context]
  ...
 When [event]
 Then ensure [outcome]
 And ensure [another outcome]
 ...

The use of the word ensure identifies outcomes that are the responsibility of the scenario. Also using the word should in the scenario indicates the desired outcome could be affected by or reliant on another part of the system, and implicitly suggests a challenge to the assertion – “Should it? Should it really?”

Test Cases

Now we get to the core test-driven aspect – writing tests to cover each scenario. North encourages starting thinking of tests in a sentence starting with ‘should’ – as in “test (that the system) should [do something]” which converts to a test case titled ‘testShouldDoSomething’, making intention of each test clear, and we should be able to relate it to the acceptance criteria.

Now for an example…

In this simple example we have a ticket machine on a bus, where a trip duration is purchased by a passenger. The machine has a coin slot, an LCD to display the purchased time, a ‘print’ button, and a ticket printer (it does not have a coin return!).

Story: Purchasing a bus ticket

As a bus passenger
I want to purchase a bus ticket
So that I can board the bus

Acceptance Criteria

Scenario 1: Inserting initial coins
Given that the ticket machine is operating
 When coins are inserted
 Then ensure the purchased travel time is displayed on the LCD screen

Scenario 2: Inserting additional coins
Given that the ticket machine is operating
 And coins have been inserted
 When coins are inserted
 Then ensure the incremented travel time is displayed on the LCD screen 

Scenario 3: Printing the ticket
Given that the ticket machine is operating
 And coins have been inserted
 When the print button is pressed
 Then ensure ticket is printed with the purchased travel time
 And ensure that the LCD screen is cleared

We can see from the narrative the full extent of the story: The user, the system feature, and the value of the feature.

The acceptance criteria can then be transformed into unit tests:


// Scenario 1
public void testShouldSetTimeOnFirstCoinInsert() {...}

// Scenario 2
public void testShouldIncrementTimeOnCoinInsert() {...}

// Scenario 3
public void testShouldPrintTicketWithPurchasedTime() {...}
public void testShouldClearScreenAfterPrint() {...}
public void testShouldFailWhenPrintWithNoPurchase() {...}

Each test case verifies an outcome of the scenario, and for scenario 3 also verifies an error condition (i.e. when the print button is pressed and there has been no coins inserted).

With the test cases supporting the acceptance criteria, we’re affectingly applying test-driven development practices to business value, visible by stakeholders outside of the development team. Considering the difficulty many of us may have convincing non-technical people (and management) of the benefits of code quality strategies, to be able to actively engage them at higher levels with story narratives and plain English acceptance criteria is quite beneficial.

Consider these points

Summarised from Dan North’s blog

  • The story title should describe an activity
  • The story narrative should include a role, a feature and a benefit. – “As a [role] I want [feature] so that [benefit]
  • The scenario title should describe what’s different
  • The scenario should be expressed in terms of Givens, Events and Outcomes
  • The givens should define all of, and no more than, the required context
  • The event should describe the feature
  • The story should be small enough to fit in an iteration

References

[1] http://dannorth.net/introducing-bdd
[2] http://en.wikipedia.org/wiki/Test_Driven_Development
[3] http://dannorth.net/whats-in-a-story
http://behaviour-driven.org/Introduction
http://stackoverflow.com/questions/2509/what-are-the-primary-differences-between-tdd-and-bdd#2548
http://en.wikipedia.org/wiki/Behavior_Driven_Development