Easyb is a powerful and elegent Behaviour-Driven Development (BDD) tool based on Groovy. It excels at being light-weight, highly readable, and easy to use. Lately, I have been using it with great success in combination with Selenium 2/WebDriver Page Objects for the automation of acceptance and regression web tests (ATDD). I'll discuss that in a future blog. But in this article, I want to give a sneak preview about a particularly nice feature due out in the next release.

The soon-to-be-released next version of easyb introduces some very cool features, one of the most useful of which is probably support for example-driven testing. This feature exists in other BDD frameworks such as Cucumber and JBehave, but has so far been notably lacking in easyb.

The new version of easyb introduces the (synonymous) where and examples keywords, which let you define sets of test data that will be used in your scenario. This test data is associated with variables, that you can use in your scenarios, as shown here:


examples "The number #{number}' should be converted to #{romanNumerals}", {
  number  =       [1,   2,    3,     4,    5,   6,    7,     8,      9,    10]
  romanNumerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
    You can use either examples or where, and place the test data before or after your scenarios, depending on what reads best.




Once you have set up your test data, you can then use these variables in your scenarios, using the hash symbol to inject the values:


scenario "Converting #number into the roman numeral #romanNumerals",{
     given "the number #number", {
          theNumber = number
     when "the system converts this number to the roman numeral equivalent", {
          theConvertedNumber = RomanNumerals.fromInteger(theNumber)
     then "the result should be #romanNumerals", {
          theConvertedNumber.shouldBe romanNumerals




When easyb runs these stories, it expands the test data and runs a separate scenario for each example, which appears in the reports:

In the text representation of the story, which is a great way to get users or BAs to check the requirements, the test data is also expanded out:

As a result, if the scenario fails with a particular set of test data, it is easy to see what values caused the test to fail:

The test data can be at the story-level, as shown above, or associated with a particular scenario. It can be contained in either a closure (as shown in the above example), or as a Map. In this case, we use the where keyword, in conjunction with a Map to represent the test data:

scenario "calculate multiplications", {
     given "values of #x and #y", {
     when "you multiply #x and #y", {
          result = x * y
     then "the result should be #xTimesy", {
          result.shouldBe xTimesY
     where "Number examples with #text and #number", 
           [x:              [1, 2, 3], 
               y:              [2, 4, 6], 
               xTimesY: [2, 8, 18]]