May 2008

The business model (or lack thereof) of selling unit testing

mouse-trap

Ralph Waldo Emerson is often attributed to copasetically saying (or most likely writing) something like:

“build a better mousetrap and the world will make a beaten path to your door”

This Sirens call has lured many an individual to build a superiorly hip mousetrap. Yet, the truth of the matter is that the world has warehouses full of better mousetraps; unfortunately, the traps are gathering dust at the expense of the inventors (and perhaps distressed investors).

The basic mouse trap works, man. It is low cost and simple to use– put some cheese on it, place it in a strategic location where mice are known to be and bingo! soon enough you’ll have yourself a mouse (dead or alive). It’s not pretty, nor is it entirely effective when it comes to scalability; however, it’s hard to overlook the fact that a mouse trap runs you about $1 (plus the cost of a morsel of cheese).

Better mousetraps, while technically superior, are often more complicated and in many cases, because it’s their bag, more expensive. Some people will buy them and find them useful; however, the average disco dancer (otherwise known as “Joe”) doesn’t care so much about the fancy trap– he or she wants mice exterminated quickly. Accordingly, they still buy the basic mouse trap because they know how it works and it costs about a dollar. And in the end, it does basically the same thing as the snazzy “better mousetrap”– that is, removes mice, baby!

Better mousetraps will always be around so long as the cost to produce them is less than what is earned by selling them (the higher the difference has a direct relationship to how long that mousetrap will last on the market too– people like making money almost as much as they love disco music). People, from time to time, will buy the superior mousetrap– often times because they’ve done the research and realize they have a particularly bad mouse problem. This realization, though, takes a lot of self discipline and honesty that the average Joe lacks. Also too, it costs a lot of money to educate the market about the superior mousetrap– most hip people don’t care because they understand the essential premise of the basic mousetrap!

In essence, xUnit (and related frameworks) are the basic mousetrap. In fact, developer testing (in the form of JUnit or any xUnit framework) is free. You can download frameworks like JUnit and start coding with them in less than a minute– maybe 10 minutes if you decide to read some documentation.

They work (they catch mice)! They are effective, but maybe not entirely pretty. Scaling xUnit across a wide code base with no testing is, at best, a herculean effort. It is challenging to overlook, though, the basic cost– $0. People who download these frameworks are motivated by pain– in this case, defects, and they are looking for a solution (often times, though, they are looking for an easy solution to a difficult problem– i.e. lots of mice procreating at a rapid pace– but knowing that they have a deep problem takes a lot of honesty and discipline, remember?).

mouse-trap

Companies have, indeed, baby, built better mousetraps for testing. For instance, Agitar’s product was phenomenal (and their team, outstanding); nevertheless, their superior mousetrap cost a heck of a lot of money. In the end, however, the Agitator produced JUnit tests. The same tests that one could have arguably written for free (yes, I know that in reality many of tests would have never been written by hand, however).

In essence, Agitar took a commodity (a mousetrap, but in this case, JUnit) and made it better– indeed, they have (or is it had now?) a good customer base (meaning they actually had customers, man). There were people that saw the benefit and had the discipline and honesty to admit they had a problem that the Agitar could solve in a superior manner.

Don’t forget basic economics though– the cost to produce their mousetrap was significant. There are only so many people who would buy a $500 mousetrap when sitting right next to it, on the same shelf, is the dollar variety (which, by they way, works fine). So too, there are only a few companies that would likely spend roughly $50,000 to $100,000 on a tool where any Google search would display a link for another tool that has zero cost (i.e. junit.org).

Indeed, there are other smokin’ companies selling superior unit testing tools that are still operating today; however, if you look closely at the big names, they have a diversified portfolio of products and it wouldn’t surprise me if their economics work out more favorably (but keep in mind the statement regarding profit and cost and the difference of the two related to length of presence in a market).

When it comes to better mousetraps, there is another well-aimed saying, which is, nonetheless, only partially true:

“Before you build a better mousetrap, it helps to know if there are any mice out there”

Indeed, this quote is half correct, for as everyone in this Age of Aquarius knows, taking the same hip comparison of mousetraps to testing tools and mice to defects, there are plenty of defects out there! The essential aspect this quote fails to mention is that:

“and you had better make sure there are plenty of well educated, motivated customers who will actually pay real money for the mousetrap (even though they could buy something similar on the cheap), baby!”

The business model (or lack thereof) of selling unit testing tools is difficult. Period. If you want to do it, you had better make sure you can build the better mousetrap on the cheap and that there are a lot of people who are educated, disciplined, and honest enough to pay for it.

I have mice (actually defects, but you get the point, man) and have, from time to time, considered buying the superior mousetrap; however, more often than not, I’ve ended up purchasing the dollar variety because it is quick and easy. Unit testing isn’t dead, baby– the inventors of better mousetraps (that have failed) often tout that mice will overrun the world. No, unit testing is a largely established practice that will gradually grow because the cost is free. Mice will always be around and people will always want to exterminate them– they just don’t always want to pay through the nose to do it, man. Can you dig it?

Irish Continuous Integration gabfest

hudson-groovy

On June 10th, I’ll be giving a hip tutorial on CI at the International Conference on Agile Processes and eXtreme Programming in Software Engineering.

The tutorial will walk students (with or without hangovers) through a series of exercises on a project where an automated build system is created that facilitates compilation, testing, inspection, and deployment. This copasetic build system will then be plugged into a CI server (Hudson in this case, baby) and students will code a series of features using Agile techniques like developer testing, which will ultimately demonstrate how a Continuous Integration process reduces risk and improves software quality. Students will then toast to CI over yet another pint of Guinness for lunch!

All you need for this tutorial is a laptop with Java installed (Java 1.5, please)– I will provide everything else (Hudson, Ant, required libraries, etc) expect beer.

If you are in Ireland (or just feel like going there) the week of June 9th (and you have a high tolerance for alcohol), then you’ll want to come to the International Conference on Agile Processes and eXtreme Programming in Software Engineering, baby! Drop me a line if you are attending (or are located in Ireland)– if you are up for a round of Guinness, even better!

Concisely operating with ternaries

One of my favorite features in Groovy is its hip ? operator, which facilitates Nullpointer navigation safety– while this feature isn’t available directly in Java, there is a handy Java operator that I’ve found myself using more and more these days (in Java, man) based upon my dynamic language conditioning of preferring code terseness: the ternary operator.

The ternary operator doesn’t directly relate to the ? operator in Groovy; however, its bag is similar– that is, reducing typing. This operator enables you to succinctly assign a value to a variable based on one or more boolean decisions like so:

this.location = (location != null ? location : DEFAULT_LOC_NAME);

In the code above, the location member variable (this.location) is being set to a location local variable or a static constant (DEFAULT_LOC_NAME) if the location local variable is null. Thus, the code to the left of the ? operator must be a boolean expression and the value to the left of the : operator is returned if true and the value to the right of the : is returned if the expression is false.

The single line of Java code facilitated by the ternary would be roughly equivalent to a conditional like so:

if(location != null){
   this.location = location;
}else{
   this.location = DEFAULT_LOC_NAME;
}

Of course, the {}’s are optional (thus, the code could be reduced somewhat); however, the point being that a copasetically placed ternary reduces typing and a bit of redundancy (in this case), baby.

In the past, I used to eschew the ternary due to its terseness– I found myself using conditionals to more clearly express my intent; however, after years of dynamic language conditioning, I’ve found myself reserving my stance on the ternary.

If you find yourself typing too much Java, baby, then consider employing the ternary– you may find its laconic nature refreshingly simple. Can you dig it, man?

The weekly bag– May 16

The weekly bag appears to be a monthly bag at this point, man!

Easy fixtures easyb style

The hip team over at easyb.org has been diligently working towards a 1.0 release and recently added the notion of fixtures for stories; that is, the DSL has been updated to include:

  • before_each
  • after_each

These constructs operate much the same as JUnit’s original fixtures in that code in the before_each closure is executed before each scenario and after_each, after.

As an example of how fixtures can be copasetic, over on testearly.com, easyb was utilized in combination with Selenium to create a more human readable functional story.

The first scenario attempted to capture a sunny day:

  • given a user is on the race report page
  • when someone enters a first name and last name in the race report form for someone who has signed up for a race
  • then they should receive a list of all races that person has singed up for

Yet in realizing this story (as Selenium was utilized) additional aspects related to using Selenium were mixed into the prose. For instance, for every scenario, the following given was needed to fire up a Selenium instance:

given "selenium is up and running", {
 selenium = new DefaultSelenium("localhost",
  4444, "*firefox", "http://acme.racing.net/greport")
 selenium.start()
}

What’s more, because it’s Selenium’s bag, the following then was also required to clean things up:

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

These are obviously candidates for pushing into a fixture type construct, right? Consequently, if you need copasetic logic that is repeated for a scenario, you can place it into either a before_each or a after_each construct like so:

before_each "initialize an instance of selenium", {
 given "selenium is up and running", {
   selenium = new DefaultSelenium("localhost", 4444,
      "*firefox", "http://acme.racing.net/greport")
   selenium.start()
 }

 and "given a person is at the race report page", {
   selenium.open("http://acme.racing.net/greport/personracereport.html")
 }
}

Selenium requires some clean up; accordingly, the following construct will be executed post a scenario:

after_each "shut down selenium", {
 then "selenium should be shutdown", {
  selenium.stop()
 }
}

Given this fixture logic, the corresponding scenarios become more concise as their intent is more clearly expressed (without too much selenium mixed in):

scenario "an invalid person should return an error message", {

 given "a form with a first and last name entered and sumbitted", {
  selenium.type("fname", "Merlin")
  selenium.type("lname", "Paine")
  selenium.click("submit")
 }

 then "the report should have a list of races for that person", {
  selenium.waitForPageToLoad("5000")
  selenium.getText("//b").shouldBeEqualTo "no races found for this person"
 }
}

Remember, these fixture constructs are executed for each scenario in a story– at this point, one time fixture logic can be easily added to a story by placing it outside the construct of a scenario. If you haven’t taken easyb for a test drive yet, go for it, man!!

Gant with Hudson in 5 steps

hudson-groovy

Gant is a Groovy-based build system that uses Ant’s extensive collection of flower power tasks without all of the nasty XML– this enables you to leverage greater flexibly when it comes to hiply assembling software. Capitalizing on this flexibility within a CI process, however, can be somewhat challenging, unless, that is, you happen to be using Hudson, baby!

Hudson is an open source CI server that is particularly interesting given its ease of configuration and its compelling plug-ins, which provide increased visibility into such aspects as test result trends, for instance. What’s more, because it’s Hudson’s bag, baby, it has a copasetic Gant plug-in that enables you to easily employ Gant as a build process for any CI project.

Setting up the Gant plug-in is easy too– all it takes is 5 steps.

First, download the plug-in.
hudson-groovy

Next, you need to upload the smokin’ plug-in into Hudson– to do this, you need to go to your Hudson server’s home page and select the Manage Hudson link. This link is on the upper left corner of the page. Once you hit that link, you’ll be presented to with a list of options for managing Hudson. Select the Manage Plugins link, baby.
hudson-groovy

Once you’ve hit that link, you should see a small form that allows you to select the plug-in on your local machine and upload it. Do that!

hudson-groovy

So far, pretty easy, eh? Don’t worry, it doesn’t get any more difficult either– the next step is to globally configure the plug-in. This involves doing one thing– pointing Hudson to your installation of Gant, which if you’re following Gant’s instructions, is essentially is your Groovy installation. Therefore, go back to the Manage Hudson link and click the System Configuration link.

hudson-groovy

From there, find the Gant section. There are two form elements that require information– the name of your Gant instance and GROOVY_HOME (which is where you installed Groovy, man).

You’ll notice that you can multiple instances of Gant configured; hence, I usually make the name the version number of the underlying Gant instance in use.

Lastly, you’ve got to configure a particular job to use that version of Gant. During a job setup, you’ll note in the Build section, you can now select the Invoke Gant script checkbox. What a trip!

hudson-groovy

Once you select the checkbox, you’ll be presented with two form elements– which Gant version to use (this is drop down list with the various names from your global configuration) and which commands to invoke. By the way, you’ll note that the form says “Ant Version”– don’t be fooled though– simple typo, man. Once you are done configuring the job, don’t forget to hit the save button. I usually like to force a build to verify things are copasetic.

That’s it, baby! You are all done and ready to go with Gant and Hudson. Can you dig it?