savaged.info

2009-09-24

groovy functional testing with gradle

Filed under: workfriendly — savaged @ 10:22
Tags: , , , , , , , ,

In my previous posting I created a ‘hello world’ style functional test example using the neat BDD framework, easyb. In that post my attention was focussed on the easyb side of things. In this post I want to draw attention to the use of Groovy when building and running the tests.

Instead of an Ant script I now can use a Groovy scripted solution. I have two choices (of course there are others); I can use Gant or Gradle. I would like to share both in that order, along with a few comments about them (please add IMHO before each comment).

Gant:

ant.path(id: 'project.classpath') {
    pathelement location: 'lib/easyb-0.9.6.jar'
    pathelement location: 'lib/commons-cli-1.2.jar'
    pathelement location: 'lib/groovy-1.6.4.jar'
    pathelement location: 'lib/selenium-java-client-driver.jar'
}

ant.taskdef(name: 'easyb', classname: 'org.easyb.ant.BehaviorRunnerTask') {
    classpath refid: 'project.classpath'
}

target(run: 'runs the tests') {
  easyb(failureProperty: 'easyb.failed') {
    classpath refid: 'project.classpath'
    report location: 'test/reports/behavior/Stories.txt', format: 'txtstory'
    behaviors(dir: '.') {
      include name: 'test/behavior/**/*Story.groovy'
    }
  }
}

setDefaultTarget run

So Gant is very much like Ant, to state the obvious, except instead of XML one can leverage the power of Groovy. I used a neat tool, called ant2gant, to help me convert my original Ant script (from the previous posting) to the version above. (I did a few tweaks, but the straight conversion would have been just as good.)

Gradle:

/**
 * needs: java -jar selenium-server.jar -interactive
 */
repositories {
    mavenCentral()
    mavenRepo urls: 'http://www.easyb.org/repoa/'
    mavenRepo urls: 'http://nexus.openqa.org/content/repositories/releases'
}

configurations {
    easybtaskdef
    easybrunner.extendsFrom easybtaskdef
}

dependencies {
    easybtaskdef(
        'org.easyb:easyb:0.9.6',
        'commons-cli:commons-cli:1.2',
        'org.codehaus.groovy:groovy-all:1.6.4'
    )
    easybrunner (
        'org.seleniumhq.selenium.client-drivers:selenium-java-client-driver:1.0.1'
    )
}

defaultTasks 'clean', 'run'

task clean << {
    new File('test/reports/behavior/Stories.txt').delete()
} 

task run << {
    ant.taskdef(
        name: 'easyb',
        classname: 'org.easyb.ant.BehaviorRunnerTask',
        classpath: configurations.easybtaskdef.asPath
    )
    ant.easyb(failureProperty: 'easyb.failed') {
	classpath {
            pathelement path: configurations.easybrunner.asPath
        }
        behaviors(dir: '.') {
            include name: 'test/behavior/**/*Story.groovy'
        }
	report location: 'test/reports/behavior/Stories.txt', format: 'txtstory'
    }
}

The Gradle version, is not too dissimilar to the Gant one, but we’re now able to use the dependency resolution Gradle offers. At a high-level view, Gradle is somewhat akin to Maven in this regard. And once again we get the advantages of using a powerful script language rather than XML.

There are enhancements I could make to my scripts, particularly to take advantage of the Groovy language. For example, I could use a variable for the easyb report, removing the repeated literal.

Here’s a small footnote for any vim folks (see my groovy minimalism posting). I found that I can get Groovy syntax highlighting in my build.gradle file simply by adding the follwing at the top.

#!groovy

Enjoy.

2009-09-14

groovy bdd with easyb

Filed under: workfriendly — savaged @ 15:42
Tags: , , , , ,

Behavioural Driven Development (BDD) is exciting to me. That’s becasue the Agile User-Story and Acceptance Criteria, actually become merged with the code-base itself. Bringing them to life, IMHO.

One framework that assists with BDD is easyb, which also has Groovy at it’s heart. Of course, I was keen to see how it could work for me. So here’s my ‘hello world’ type example:

First, I downloaded the latest version of easyb, and pop it in my home folder (or C:\). Then I knock up a simple easyb example story:

package info.savaged.testing.bdd.easyb

description 'This story is about adding'

narrative 'narrative', {
    as a 'person doing maths'
    i want 'to add two and two'
    so that 'I can find the result'
}

scenario 'add two and two', {
    given 'two is added to two', {
	total = 2 + 2
    }
    then 'the result should be four', {
	total.shouldBe 4
    }
}

And another example, this time with some Selenium thrown in:

package info.savaged.testing.bdd.easyb

import com.thoughtworks.selenium.*

description 'This story is about googling'

narrative 'this string is required for now', {
    as a 'person who uses google'
    i want 'to search for a set of internet links for a phrase'
    so that 'I can find information online'
}

before 'start selenium', {
    given 'selenium is up and running', {
        selenium = new DefaultSelenium(
            'localhost',
            4444,
            '*iexplore',
            'http://www.google.co.uk')
        selenium.start()
    }
}

scenario 'a search phrase has been entered', {
    when 'filling out the search with a phrase', {
        selenium.open '/'
        selenium.type 'q', 'savaged.info'
    }
    and 'the submit button has been clicked', {
        selenium.click 'btnG'
    }
    then 'the results should have a list of links for that phrase', {
        selenium.waitForPageToLoad '5000'
        selenium.isTextPresent 'Results * for savaged.info'
    }
}

after 'stop selenium', {
    then 'selenium should be shutdown', {
        selenium.stop()
    }
}

Finally, to make use of these behaviour files, an Ant script:

<project name="bdd" default="run" basedir=".">

    <taskdef name="easyb" classname="org.easyb.ant.BehaviorRunnerTask">
        <classpath>
	    <pathelement location="easyb-0.9.5.jar"/>
	    <pathelement location="groovy-1.6.0.jar"/>
        </classpath>
    </taskdef>

    <target name="init">
    </target>

    <target name="run" depends="init">
	<easyb failureProperty="easyb.failed">
	    <classpath>
		<pathelement location="easyb-0.9.5.jar"/>
		<pathelement location="commons-cli-1.1.jar"/>
		<pathelement location="groovy-1.6.0.jar"/>
		<pathelement location="selenium-java-client-driver.jar"/>
	    </classpath>
	    <report location="Stories.txt" format="txtstory" />
	    <behaviors dir=".">
		<include name="*Story.groovy" />
	    </behaviors>
	</easyb>
    </target>

</project>

Of course, the Ant script expects the easyb libraries and the Selenium java client jar files to be present. And you would need to have started the Selenium server remote control server running. Assuming that’s all in place running:

$ ant

Should produce some affirmative test output along with a file containing the user stories in plain text.

That’s just a silly example, but the possibilities are significant. If the business analysts or other product user in the Agile development team could work in the easyb Groovy format, the tightness of the team could be really enhanced.

IMHO, I think BDD is best compared to functional testing. I believe the User-Story and it’s test scenario(s) fits against the UI testing.

For example simple CRUD at another level of test (unit or integration), would require a fair amount of mocking. One might need to mock the http request and response, in a web-app,  for example. Whereas, coming in from the GUI, with a tool set like Selenium or Canoo Webtest, makes for clean BDD code. Especially if one were to use the before and after easyb features. After all, your manager or business sponsor should be able to see what the test is doing, and lots of ‘set-up’ code would, no doubt obfuscate that.

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 57 other followers