Showing posts with label cucumber. Show all posts
Showing posts with label cucumber. Show all posts

Tuesday, October 19, 2010

Building the Gherkin on OSX

cucumber64x64.png Update 2011-09-01: Updated changes of github repositories and changes in rake build.

Recently I wanted to build the Gherkin project to reproduce a certain behavior we observed in SpecFlow.
These were the steps that were necessary to build the Java version of the Gherkin parser on OS X:
Ragel installation:
I am using MacPorts. Installing Ragel is a breeze:
sudo port install ragel

rvm installation
I figured that rvm is the best option to install JRuby side by side of other Rubies.
I followed the installation instructions of rvm.

JRuby installation
... again a breeze with rvm:
rvm install jruby

Switch to JRuby
rvm use jruby

Clone gherkin:
git clone http://github.com/cucumber/gherkin.git

Clone cucumber:
To build gherkin you need the cucumber sources lying beside your gherkin sources.
git clone http://github.com/cucumber/cucumber.git

Required gems:
You need some gems to build gherkin:
gem install rspec json term-ansicolor rake_compiler awesome-print builder
(other gems like rake, bundler were already installed ...)

Java dependencies:
The rake build needs json-simple lying in your local Maven repository
cd java
mvn clean compile
The maven compile step of the maven build will fail, but it will download the json-simple dependency into your local repository.

Executing the rake build:
rake clean
rake jar

Executing the java build:
cd java
mvn clean compile test
All tests should pass. Now you can open the java project in your favorite IDE.

Wednesday, March 31, 2010

Classifying BDD Tools (Unit-Test-Driven vs. Acceptance Test Driven) and a bit of BDD history

BDD (Behavior Driven Developement) seems to gain momentum lately.

BDD is hard to grasp, because it is more than a development methodology (unlike TDD) and there are currently very different ideas what it really means. To make matters worse there are a lot of BDD tools around that pursue quite different concepts.
In this post I try to classify two main categories among those tools.

Important for the understanding is that BDD can be practiced at different levels. At the code/unit level and at the feature level. In both cases it is a good practice to use examples to specify the behavior of the units resp. features. However in both cases we have different stakeholders and intents with the BDD process.
Both approaches to BDD are not exclusive, they can be combined.
(see also "BDD for Acceptance Tests vs. BDD for Unit Tests (or: ATDD vs. TDD)" on the SpecFlow mailing list)

Currently I would differentiate two flavors of BDD tools:
  1. Tools with a business readable output
  2. Tools with a business readable input
With tools from the first category (business readable output) the support for the BDD process is typically focused on the developers. All artifacts involved are owned by the developers and are typically code. This is not a bad thing, as responsible and committed developers are often the main stakeholders in successful software projects. Other stakeholders are only addressed by the tools by providing understandable reports after developers have done their work.

Tools from the second category (business readable input) try to widen the focus of the BDD process by enabling more involvement by all other stakeholders: customers, business analysts, testers maybe even operations.
This involvement is possible upfront, meaning before the developers have done their work. This business readable input is an artifact commonly owned by all stakeholders. By having a commonly owned artifact, the process tries to ensure that all involved stakeholders build up a shared understanding which is crucial for successfully software projects (for more information I suggest reading Bridging the Communication Gap by Gojko Adzic).

Because this shared understanding is input (as opposed to output) and business readable, the process can even be taken further and make the artifact business writable. If this is achieved successfully then we have done a big step towards executable specifications.

In practice we often see tools of the first category (business readable input) used as a replacement/extension for TDD at a unit-testing level.
In this case the behavior of the unit under development is focused by trying to specify this behavior upfront in a less technical way. However this is usually not interesting for other stakeholders than developers, because the technical units under development are usually too fine grained and have no meaning to non technical persons. Also technical units are the primary focus of developers and they are the main stakeholders (think of testability, separation of concern, maintainability ...), other stakeholders should not be too involved here. So this is mainly a tool for developers and allows in some cases the mapping of technical units to overlying features.

The second kind of tools aim clearly at Acceptance Testing and Acceptance Test Driven Development. Here system features are clearly focused. Features are usually more coarse grained than the behaviors of single technical units. Features should always be understood and driven by business requirements.

It is certainly possible to write acceptance tests with the first category of tools, but the driving aspect (as in Acceptance Test Driven Developement) is certainly harder to achieve and less supported by these kind of tools.


Examples:
Easyb is a Groovy based tool of the first category. The following example (from this post) shows how behavior is specified at at unit-level (class-level):
scenario "Two amounts with the same currencies are added", {
  given "Two different amounts with the same currencies", {
    money1 = new Money(12, "CHF")
    money2 = new Money(14, "CHF")
    expected = new Money(26, "CHF")
  }
  when "Add given amounts" , {
    result = money1.add(money2)
  }
  then "New amount is sum of two given ones", {
    result.equals(expected).shouldBe true
  }
}

scenario "Two amounts with different currencies are added", {
  given "Two amounts with different currencies", {
    money1 = new Money(12, "CHF")
    money2 = new Money(14, "EURO")
  }
  when "Add given amounts", {
    add = {
      money1.add(money2)
    }
  }
  then "Operation should fail", {
    ensureThrows(IllegalArgumentException) {
      add()
    }
  }
}

Executing the above story gives you the follwowing readable report:
2 scenarios executed successfully.

  Story: money

    scenario Two amounts with the same currencies are added
      given Two different amounts with the same currencies
      when Add given amounts
      then New amount is sum of two given ones

    scenario Two amounts with different currencies are added
      given Two amounts with different currencies
      when Add given amounts
      then Operation should fail
(of course easyb can also generate a fancy html report)


Cucumber is a tool of the second category. The following example from cuke4duke shows how an executable feature is specified:
Feature: Book search
  In order to find books I might buy
  As a potential customer
  I want to search for books by different criterias
 
  Background:
    Given the following books
      | Author          | Title                                           | Year | Publisher      |
      | Martin Fowler   | Patterns of Enterprise Application Architecture | 2002 | Addison Wesley |
      | Eric Evans      | Domain Driven Design                            | 2003 | Addison Wesley |
      | Gerard Meszaros | xUnit Test Patterns                             | 2007 | Addison Wesley |
 
  Scenario: Search for title
    When I search for title 'Patterns'
    Then the result list should contain 2 books
 
  Scenario: Search for author
    When I search for author 'Fowler'
    Then the result list should contain 2 books
(notice the error in the second scenario!)

When executing this example (using cuke4duke) the whole EJB stack is exercised, including database-access. The result is the following report:
(of course Cucumber can generate a lot of different outputs)


History (as I could reconstruct it):
Tools from the first category evolved from TDD. Dan North introduced BDD in 2002, see his introductory blog post.
JBehave was one of the first BDD tools, at this point clearly part of the first of the above categories.
Then the BDD movement was mainly driven by the Ruby/Rails community. RBehave was introduced and then merged into RSpec as RSpec Story Runner.
RSpec then was as a tool that could satisfy both of the above catgories

RSpec StoryRunner was then dropped and Cucumber was created. Cucumber coined the current flavor of BDD tools with plain-text specifications. Cucumber also is aiming at extending its reach beyond Ruby/Rails (see cuke4duke, cuke4Nuke, gherkin).
Other first-generation tools then adapted and also support plain-text specifications (JBehave2, NBehave).

Beside all those explicit BDD tools there is FIT/FitNesse. FIT was also invented in 2002 by Ward Cunningham. Its goal was enabling collaboration and communication through automated accepatance testing. FitNesse took up the basics of FIT and provided an intuitive, wiki-based frontend/IDE.
While FIT seems to have practically died, FitNesse  is still thriving. FitNesse also recently added Parameterized Scenario Tables and there is GivWenZen. This makes it possible to use the plain-text GWT (Given-When-Then) syntax, that was made popular by the plain-text BDD tools.

I will list a more complete overview of BDD tools for the Java and .Net platforms in later posts.

Tuesday, February 2, 2010

How to debug your code with cuke4duke

cucumber.jpg Cuke4duke is a ATDD/BDD tool for the JVM. The tool is based on Cucumber and uses JRuby to execute.

Out of the box cuke4duke offers three main ways to execute: Ant, Maven or cuke4duke-commandline.

But all of those three approaches are a bit tricky if you want to debug your application when executing in a BDD scenario.

There is some information on the wiki how to achieve it.

Here some more details:


Maven and Remote Debugging

When using Maven, you can add the following lines to your cuke4duke config in your pom.xml:
<plugin>
  <groupId>cuke4duke</groupId>
  <artifactId>cuke4duke-maven-plugin</artifactId>
  <configuration>
    <jvmArgs>
      <jvmArg>-Dcuke4duke.objectFactory=cuke4duke.internal.jvmclass.PicoFactory</jvmArg>
      <jvmArg>-Xdebug</jvmArg>
      <jvmArg>-Xnoagent</jvmArg>
      <jvmArg>-Djava.compiler=NONE</jvmArg>
      <jvmArg>-Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y</jvmArg>
    </jvmArgs>

(a running example is here)

When you now run the integration-test phase (ie. mvn verify), then Maven breaks and waits for a debugger to connect:
[INFO] [cuke4duke:cucumber {execution: run-features}]
[INFO] Listening for transport dt_socket at address: 4000

Now you can connect with Eclipse with a new debug configuration (Run->Debug Configurations...). Choose 'Remote Java Application' and configure the same port as you configured in the pom.xml under address:
Screen shot 2010-01-10 at 4.06.36 PM.png
Now execute this debug configuration, and Maven (which is still waiting) will continue after Eclipse successfully connected, and any breakpoints you set in Eclipse will trigger.


Running from the IDE

Another way is to execute the whole enchilada (JRuby, cuke4nuke, cucumber…) directly out of the IDE. In Eclipse this is accomplished with a new Debug Configuration. Choose Java Application then configure it accordingly: Main class: org.jruby.Main
Screen shot 2010-01-10 at 4.13.57 PM.png
Program Arguments:
${M2_HOME}/repository/.jruby/bin/cuke4duke ./target/test-classes features


VM Arguments:
-Dcuke4duke.objectFactory=cuke4duke.internal.jvmclass.PicoFactory
Screen shot 2010-01-10 at 4.15.02 PM.png
Classpath: Make sure all needed jars are on the classpath.
Screen shot 2010-01-10 at 4.15.17 PM.png
Now execute this debug configuration and Eclipse will break directly at any breakpoint you set in your sources.
Related Posts Plugin for WordPress, Blogger...