February 2008
Monthly Archive
Developer Testing and Agile and /Nyika21 Feb 2008 08:30 pm
Behaviour Driven Development: An Engineering Perspective
BDD has been discussed and dissected by many developers and code philosophers since its inception. Thinking about system behaviour is key. Thinking about the manner in which the system will react to external forces in a natural way is core to BDD. Perhaps insight into raw TDD itself will show just how this natural wrapper around TDD emerged.
A system or application emerges (from nothing) incrementally through TDD. What does this really mean? It simply means that a part of a system is constructed by way of the fulfilment of an expectation stated before that part of the system exists. What exactly is this expectation? It is a test (and we know that a test aggresively asserts that something is true about that part of the system, in a nutshell). A test must be satisfied.
//Here's our test subject
public class ZipcodeVerifier(){
private boolean wasZipValid = false;
public boolean isZipcodeValid(int zipcode){
this.wasZipValid = true;
return this.wasZipValid;
}
}
//Here's our test
public class ZipcodeValidator{
@Test
public void testGoodZipcodeIsIndeedGood(){
assertTrue(new ZipcodeVerifier().isZipcodeValid(22030));
}
}
Now, suppose the exercise that just occurred created part of a system (S1). If we step back for a second, we see that S1 was created with a one or more techniques available to TDD (for example Kent Beck gives an example of making a simple test pass, using a technique known as ‘faking it’, where we return the exact type required by the test immediately with no logic attached to determining that value( From his book “Test-Driven Development”)). Let define “faking it”, one of the techniques used, as (tk1).
Also, S1 reacted (S1r) by providing the a value after completing its mission (a boolean). Not all subsystems need to do that (return type void).S1 also changed its internal state from false (S1s1) to true (S1s2). It was not necessary for S1’s own state to change (it may just as well have changed another subsystem’s state, S2, once it, in turn, comes into existence later).
In summary, the simple TDD exercise fulfilled the expectations of a test by creating a subsystem (S1) with a TDD technique (tk1, Beck’s technique) that reacted (S1r) by returning some information (true/false) and changing its internal state (from S1s1 to S1s2).
S1’s change of state calls to mind a style of software architecture: REST (Representational State Transfer). The restful state of the subsystem S1 changed by applying the technique (tk1). Note that some other subsystem, Sn, may have had its state changed too (or instead of S1, or even in addition to S1). The point is, a subsystem’s state is changing when a TDD technique (one or more, tk1…tkn) is applied to it.
But as the number of tests on the same test-subject grows, many more other subsystems will emerge (eg: a refactor may move some code into a private method). Those subsystems may change, in time, the states of other existing subsystems.
The representational state of any one subsystem (Snsn) now seems to become more and more important in determining how another subsystem (Sn+1sm) will react (Sn+1r) OR change the state of yet another subsystem from (Sn+2sy) to (Sn+2sy+1).
Now, if one had to pick any subsystem (Sb) and decide before-hand what one wishes its state to be (Sbsn) (that is, we wish for it to possess a representational state of a specific kind), we have already set an test-expectation for Sb.
Most importantly, however, when we actually specify in (what seems like a natural) descriptive state-representational language about the state of other subsystems that would help give Sb the desired state, we arrive at BDD (or at least the beginings of it). This applies also to the pure inputs to Sb that would cause the needed reaction, Sbr.
For example:
@Test
public void checkThatAddressContainsStateSymbolGivenANonNullZipcode(){}
In effect, we need the subsystem containing what we understand as an Address (for a customer or business) to contain (to possess a state) a State Code (eg: VA or KY) given that another subsystem, the Zipcode Handler, contains a valid state (a non-null zipcode).
Going back to the original example, we can see that there really is no other subsystem that determines S1’s state. We were dealing purely with a reaction (S1r) from the subsystem. If S1 had been re-written as follows:
//Here's our test subject
public class ZipcodeVerifier(){
private boolean zipValid = false;
private SimpleDelegator delegator;
public boolean isZipcodeValid(int zipcode){
delegator = new SimpleDelegator();
setZipValid(delegator.determineValidity(zipcode));
return getZipValid();
}
public boolean getZipValid(){
return this.zipValid;
}
public void setZipValid(boolean valid){
this.zipValid = valid;
}
}
//Here's our test
public class ZipcodeValidator{
@Test
public void testGoodZipcodeIsIndeedGood(){
assertTrue(new ZipcodeVerifier().isZipcodeValid(22030));
}
}
Here, we see that S1’s state will change based on another subsystem internal state. The test is really checking that S1 has the state we expect. How? Because of the line:
return getZipValid();
based on the line:
setZipValid(delegator.determineValidity(zipcode));
…So BDD is another way of inquiring whether states and reactions are what they should be from the various subsystems that make up the main system using TDD’s rich toolset of techniques…but more importantly, doing so in simple, descriptive (almost human) terms….
, essentially:
[ BDD = Creating ∑[S1, S2, …, Sn] injecting fn( { Ss = fn(S1s, S2s, …, Sns ) } and { Sr = fn(S1r, S2r, …, Snr ) } ) using { tk1, tk2, …, tkn } ]
Build Management and /Glover18 Feb 2008 11:30 am
One build platform to rule them all?
It seems the build platform debate continues to heat up with Steven Devijver’s posting on the DZone entitled “What’s Wrong with Build Systems in Java Today?” where he previews a build platform that builds upon Ant and Maven 2 and adds, as he states:
Better-than-Maven 2 JAR and project dependency management, No XML, and Integration of Ant, Maven 2, Gant, Buildr, Rake, Grails, … projects in multi-project builds
Clearly, in the Java space, Ant is the de-facto build platform; consequently, the future of build languages will most likely need to leverage the extensive infrastructure in place to support Ant– dropping XML is key should you require a more imperative style of building things. Dependency management has always been a splintered solution ranging from Ivy to Maven’s declarative dependency framework to Ruby’s gems– all interesting and viable solutions, which makes his statement all the more interesting.
All in all, these are exciting times as dynamic languages are enabling a complete change in the way we define software builds, which will ultimately lead to tools that make building software (that is, compiling, testing, inspecting, deploying, etc) easier.
SD West 2008, Jolt Awards
There’s a lot to look forward to if you’re attending the SD West conference in Santa Clara next month. To kick it off, Stelligent’s own, Andrew Glover, will be delivering a half day tutorial introducing Groovy on Tuesday, March 4th. If learning Groovy quickly interests you this is one presentation you can’t miss out on!

On Tuesday evening, I encourage you to attend the “Agile Roundtable” hosted by Stelligent. If you haven’t participated in a Stelligent roundtable previously, this is the one you need to get yourself to. Topics on the discussion table include Test-Driven Development and Continuous Integration. For more information, or to RSVP, please contact mandy.owens@stelligent.com.
Finally, the winners of the industry-acclaimed Jolt Awards will be announced on Wednesday evening, March 5th. We’re quite partial to the “Technical Books” category where we hope Continuous Integration: Improving Software Quality and Reducing Risk jolts the industry!
Developer Testing and /Glover08 Feb 2008 01:18 pm
Conversational testing
Steven Devijver (one of the co-creaters of the Grails framework and an all around super guy) recently interviewed me concerning easyb. easyb is a behavior driven development framework for the Java platform, which makes use of a specification based Domain Specific Language– by doing so, easyb aims to enable executable, yet readable documentation. In fact, as Steven coined, easyb enables conversational testing, which I think is a fitting term!
Read the interview and see what you think– or better yet, try easyb out for yourself!
Code Coverage and /Glover05 Feb 2008 01:45 pm
Fine grained code coverage
Typical code coverage tools give you line and path coverage information (which is certainly helpful depending on how you examine the data); however, what most tools don’t covey is directness. That is, what was the distance from the test to a particular path?– the thinking being that the closer the test, the more reliable the quality of that test. If method doOrder is 5 paths of indirection away from a test, then one could infer that this particular method may require better testing.
Project PEA is a code coverage tool that’ll monitor your JUnit tests in an attempt to gather call stacks so as to give you an idea of indirection– with PEA you can ascertain how well a particular test actually verifies say, that doOrder method.
For more information, check out PEA or view a powerpoint presentation that Matt Harrah put together explaining it.
Developer Testing and /Glover and Agile04 Feb 2008 08:40 pm
The story behind database behavior
Stories offer a powerful mechanism for conveying information– indeed, if written correctly and combined with an adequate means of validation, stories can become executable documentation. For instance, easyb (a behavior driven development framework for the Java platform) supports a story format that consists of:
- given some condition
- when something happens
- then something else should happen (this may or may not necessarily provide validation)
For instance, easyb supports the notion of plug-ins, which are modules that provide additional functionality– currently there is a plug-in that supports database management so that during the context of a story, a database can be seeded. This is, of course, useful should you need to validate high level functionality.
Using easyb itself, it is rather easy to describe what the plug-in does and how to use it. A story to validate the database plug-in sounds a bit like this:
- given that database has an initalized data model (i.e. tables to hold stuff)
- and given the plug-in’s method is invoked with a dataset (i.e. rows for tables)
- when a select statement is issued for a value only found in the dataset inserted by the plug-in
- then the desired item (i.e. column value) should be returned
In essence, this story is the use case for the plug-in– reading it you can most likely ascertain that the plug-in puts rows in database tables. Reading this story, it is also evident that at some point, it may be helpful to start and stop a database instance during the course of the story– i.e. start it up at the commencement of the story and stop it at the end.
Using easyb’s story format, I can sketch out the body of the story as follows (note, the story includes starting and stopping a database):
given "a database is up and running", {}
and
given "the database has an initalized data model", {}
and
given "the database_model method is invoked with a dataset", {}
when "a select statement is issued for a value that could
only be present if the database_model call worked", {}
then "the word bellicose should be returned", {}
and
then "shut down the database", {}
Making the story executable entails adding some logic– in the course of doing so, the story demonstrates how to use the database plug-in (minus the first and last steps, right?)!
The first given can be coded as follows (in Groovy, that is):
given "a database is up and running", {
Server.main(["-no_system_exit", "true"] as String[])
}
The Server instance in the above code is HSQLDB’s org.hsqldb.Server type. This is, by the way, a handy database that is easily controlled programatically and easy to install (it’s a jar file!).
The next given is a bit more complicated– the database needs an empty schema– one can’t assume one is present, so I’ll just create it. This also happens to validate the story quite nicely– no assumptions are made about the underlying database!
and
given "the database has an initalized data model", {
sql = Sql.newInstance("jdbc:hsqldb:hsql://127.0.0.1",
"sa", "", "org.hsqldb.jdbcDriver")
ddl = """DROP TABLE definition IF EXISTS;
DROP TABLE synonym IF EXISTS;
DROP TABLE word IF EXISTS;
CREATE TABLE word (
WORD_ID bigint default '0' NOT NULL,
PART_OF_SPEECH varchar(100) default '' NOT NULL,
SPELLING varchar(100) default '' NOT NULL,
PRIMARY KEY (WORD_ID),
UNIQUE (SPELLING));
CREATE TABLE definition (
DEFINITION_ID bigint default '0' NOT NULL,
DEFINITION varchar(500) NOT NULL,
WORD_ID bigint default '0' NOT NULL,
EXAMPLE_SENTENCE varchar(1000),
FOREIGN KEY (WORD_ID) REFERENCES word(WORD_ID)
ON DELETE CASCADE
ON UPDATE CASCADE,
PRIMARY KEY (DEFINITION_ID));
CREATE TABLE synonym (
SYNONYM_ID bigint default '0' NOT NULL ,
WORD_ID bigint default '0' NOT NULL ,
SPELLING varchar(100) default '' NOT NULL ,
FOREIGN KEY (WORD_ID) REFERENCES word(WORD_ID)
ON DELETE CASCADE
ON UPDATE CASCADE,
PRIMARY KEY (SYNONYM_ID));
commit;"""
sql.execute(ddl);
}
The data model here is quite simple– three tables and I’m using GroovySQL to jam it into the database.
Next, I need to actually use the plug-in to seed the database with data! The core API of the plug-in is the database_model closure, which takes standard JDBC connection information (URL, user name, driver, etc) and a String representing the dataset. In this case, I’m using Groovy’s MarkupBuilder to to create an XML representation of the data (which the underlying code requires– that code uses Java’s own DbUnit, by the way).
and
given "the database_model method is invoked with a dataset", {
database_model("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:hsql://127.0.0.1", "sa", ""){
def writer = new StringWriter();
def builder = new MarkupBuilder(writer);
builder.dataset(){
word(word_id:1, spelling:"bellicose", part_of_speech:"Adjective")
definition(definition_id:10, definition:"demonstrating willingness and willingness to fight ",
word_id:1, example_sentence:"The pugnacious youth had no friends left to pick on." )
synonym(synonym_id:20, word_id:1, spelling:"belligerent")
synonym(synonym_id:21, word_id:1, spelling:"aggressive")
}
return writer.toString()
}
}
Note, the and clauses– in truth they’re noops but they serve to make the story read more nicely. Notice how the MarkupBuilder instance creates data that matches the data model found in the 2nd given. For instance, the word “bellicose” is inserted with an id of 1.
That right there is the heart of the plug-in– inserting data into the database so that a high level story can play out. Now, using easyb, it’s time to validate that the call to database_model worked.
Validating the database_model call means querying the database for the data that the database_model call should have inserted– in my case, I’ll see if the word bellicose is present!
when "a select statement is issued for a value that could
only be present if the database_model call worked", {
value = null
sql.eachRow("select word.spelling from word where word.word_id = 1"){
value = it.spelling
}
}
Note how I’m still using GroovySQL to talk to the database. Once I have the word (stored in the value variable), it’s time to verify it is there.
then "the word bellicose should be returned", {
value.shouldBe "bellicose"
}
Note how easyb supports some magic validation via the shouldBe call– easyb supports a few variations, which ever one you pick is up to you– shouldBeEqual or shouldBeEqualTo or shouldEqual all do the same thing.
Lastly, stopping the database is as easy as sending a shutdown command (via SQL) to the instance of HSQLDB.
and
then "shut down the database", {
sql.execute("SHUTDOWN")
}
The story behind the plug-in’s behavior doesn’t really require a few documents– it just requires one– the story itself, which as you can see has been implemented in easyb (by way of Groovy, but you can certainly run these in Java). easyb is all about easy– the plug-in was rather easy to describe, don’t you think?
Continuous Production - Production-ready software…any time
Production-ready software, on-demand
The general notion of the practice of Continuous Integration is that it’s performed during the “development cycle”. I think we need to expand this into areas typically thought of as “latter lifecycle” activities. In my experience, even the most Agile of projects aren’t considering all aspects of what it takes to make software “production ready”.
Over the past year, I’ve been advocating a much more intensive criteria for Continuous Integration with my peers and customers, which is more like “Continuous Production” meaning you can produce production-ready software on a daily or even a continuous basis. Effectively, we’re talking about extending the Continuous Integration model into all environments (Test, Stage and Production), not just the development environment. In fact, at Stelligent, our purpose is to get our customers to production-ready software on a daily basis.
A posting on Wikipedia describes Continuous Production as “a method used to manufacture, produce, or process any product without interruption. There is no discrete rate at which goods are produced, as opposed to a batch production process, or job production.” I’m suggesting we move toward a similar model for developing software.

A lot is bundled in this term, Continuous Production, though. In my experience, it means that you automate most everything it takes to create software so that it can be deployed into the user’s environment any time. It means you may automate some or all of the following:
-
Compilation of source code and tests -
this is a given for CI.Tools: Ant, MsBuild, rake, NAnt or similar build tool.
-
Database Integration/Migration to target database server (e.g. Oracle) -
Some shops are doing this with CI. Tools: Ant sql task or ORM-based Ant tasks,
dbdeploy
-
Testing - execution of unit, component, system, functional/acceptance, security, load and performance tests - Some shops are doing this with CI. Tools:
JUnit,
DbUnit,
Selenium,
JUnitPerf,
FindBugs,
JMeter, NUnit, NDbUnit
-
Inspections - execution of static/dynamic analysis checkers: code coverage, code duplication checks, coding standards, cyclomatic complexity and dependency analysis - Some shops are doing this with CI. Tools:
PMD,
CheckStyle,
FindBugs,
JavaNCSS,
JDepend,
Cobertura, NCover, NProf, Source Monitor, NCover
-
Deployment - Deployment and repeatable configuration to servers (e.g. JBoss) - Some shops are doing this with CI. Tools: Application Server-specific Ant tasks (e.g.
WebLogic)
-
Remote Deployments to target environments - For example, from a build machine to staging environment (for web containers and database servers). Tools:
Ant,
Java Secure Channel and
SmartFrog, Capistrano
-
You will need a way to rollback to a previous deployment (this includes database changes)
-
(Optionally) Creation of
installation distribution - Few shops are doing this with CI. Tools:
NSIS and
antinstaller, InstallShield .
-
(Optionally) Generation of distribution media - Few shops are doing this with CI
-
Source labeling and (possibly) build labeling - Some shops are doing this with CI
-
Automated notification of build status - This is a given for CI via Email, X10 devices, etc.
-
Automating the
promotion through QA, Staging and Production environments - Promote the binary and accompanying artifact through each target environment. Tools: Build Management servers such as
AntHill Pro are useful for build promotion
-
Of course, the actual steps will vary depending the type of software application you are producing whether it be a rich client, web application, embedded or other…but you get the point. Continuous Production, to me, means you have the capability to create production-ready software whenever necessary .
What I am saying is that the creation of production-ready software should become a “nonevent “.
The benefits are numerous, but here are a few:
-
Decisions can be made based on working software , not on a task item on a project management chart - no more “it’s 80% done”
-
Eliminate the reliance on an individual with specialized knowledge to produce the software for production
-
There’s “done”, there’s “done, done” (coded with acceptance tests). With Continuous Production, it’s “done, done, done” and ready for release to users (code, acceptance tests, operating in the customer’s environment)
Note: This does not mean that you will be taking up cycles producing production-ready software with every change to the version control repository. Test, Stage and Production builds are more likely to be performed on demand (by a person). However, the point is that your build environments are capable of building production-ready software on a continuous basis.
There are very, very few projects that are doing this right now. I’d have to guess it’s much less than 1%. It makes me think of the saying “it’s not the destination, it’s the journey”. If your team sets this as a goal, the closer you get to it, the less you’ll be spending time on environment-related, repetitive and error-prone issues and the more time you spend on new features and improvements to the software. Is it possible, right now, for every project to do this? Probably not. However, once you start asking questions like “What do I need to do to make this feature production ready?”, it changes your perspective on everything from coding to testing and deployment.
In reality, I think even the most automated development environments still need (or should) have a manual component when creating software that is production-ready. This may include usability testing or even a simple manual sanity check. But, I think the more we move toward this model, the less headaches we’ll have and the better our estimates.
In my book on Continuous Integration, I make a reference to something Tim O’Reilly mentioned regarding Flickr’ s ability to deliver updates to its web software as frequently as every 30 minutes. This is only possible if you’ve automated many of the deployment steps.
Let me know if you or someone you know is doing this or moving toward this type of model. I’m curious to hear your experiences with it.