Another lunchtime discussion…”So. is easyb for unit testing or functional testing? Which is it?”
Does it have to be either? It is a testing tool that is driven by stories. These stories can be helping us to understand either how our units of code operate or what constitutes an acceptably-behaving system.
Since easyb is a Groovy DSL and since Groovy interoperates fully with Java, it is easy to incorporate a tool such as Canoo Webtest. For example:
description "Testing a Web Application"
narrative 'Can we test a web application in a scenario? Yes. Yes we can!', {
as_a "Starving Developer"
i_want "To test my web application"
so_that "I can get a better job elsewhere"
}
ant = new AntBuilder()
webtest_home = 'C:/DEVTOOLS/Canoo WebTest 2.6'
ant.taskdef(resource:'webtest.taskdef') {
classpath() {
pathelement(location:"$webtest_home/lib")
fileset(dir:"$webtest_home/lib", includes:"**/*.jar")
}
}
scenario "The Transentia Web Site Is Up and Running", {
given "The URL for the Transentia Web Site"
when "We look for the page subtitle"
then "We must see the appropriate byline", {
ant.testSpec(name:'groovy: Test Groovy Scripting at creation time'){
config([host:"www.transentia.com.au", basepath:'flatpress'])
steps() {
invoke(url:'index.php')
verifyXPath(xpath: "//p[@class='subtitle']", regex: true, text: '.*training.*')
}
}
}
}
It’s good to look at this example and see the synergies Groovy brings to the task: would a ‘pure’ Java developer normally reuse ant as shown above?
A similar use of easyb is given in Functional web stories, but that example uses selenium, not WebTest. There is also a useful followup article covering the use of easyb fixtures to improve the script at http://thediscoblog. … ixtures-easyb-style/.
I like the idea of a single tool being able to drive various testing activities, I particularly like the way that this gives a consistent ‘feel’ to the reporting:
1 scenario executed successfully Story: transentia story Description: Testing a Web Application Narrative: Can we test a web application in a scenario? Yes. Yes we can! As a Starving Developer I want To test my web application So that I can get a better job elsewhere scenario The Transentia Web Site Is Up and Running given The URL for the Transentia Web Site when We look for the page subtitle then We must see the appropriate byline
(as an aside, this consistency of reporting style can also be achieved by getting easyb to output an XML report that can then be transformed in any which way…)
So my answer to the question is “easyb can be used in any way that makes sense, but consider the value of a consistent documentation stream.”
Now, just to be complete and to show that I do “eat my own dogfood”, here is the associated gant script:
DEVTOOLS = 'c:/DEVTOOLS'
dirEasybHome = "${DEVTOOLS}/easyb-0.9"
dirWebtestHome = "${DEVTOOLS}/Canoo WebTest 2.6"
dirReport = 'reports'
includeTargets << gant.targets.Clean
cleanPattern << '**/*~'
cleanDirectory << [ dirReport ]
dirGantHome = ant.project.properties."environment.GANT_HOME"
ant.path(id: 'pathGant') {
fileset(dir: dirGantHome, includes: 'lib/*.jar')
}
ant.path(id: 'pathWebtest') {
fileset(dir: dirWebtestHome, includes: 'lib/*.jar')
}
ant.path(id: 'pathEasyb') {
fileset(dir: dirEasybHome, includes: '*.jar')
}
ant.taskdef(name: "easyb", classname: "org.disco.easyb.ant.BehaviorRunnerTask", classpathref: 'pathEasyb')
target(easyb: 'Run easyb tests') {
depends(init)
ant.easyb(failureProperty: "property.easyb.failed") {
classpath() {
path(refid: 'pathEasyb')
path(refid: 'pathWebtest')
path(refid: 'pathGant')
}
report(location: "${dirReport}/xml-report.xml", format: "xml")
report(location: "${dirReport}/story-report.txt", format: "txtstory")
report(location: "${dirReport}/behavior-report.xml", format: "txtspecification")
behaviors(dir: '.') {
include(name: "**/*.story")
}
}
ant.fail(if: "property.easyb.failed", message: "***easyb run failed")
}
target(init: 'Initialise the build, given a clean start') {
depends(clean)
ant.mkdir(dir: dirReport)
}
setDefaultTarget(easyb)
This should reinforce the message from Goodybye Ant, Hello Gant.
(*)Just to say, I dislike the term “functional testing”, I much prefer acceptance testing.
