Declarative Real Time Programming NOW!

(Mon Oct 23, 2006) [/Tools#

It took barely 30 minutes into RubyConf before everyone knew about Erlang. Never underestimate the power of a screencast. Except 'screencast' wasn't even a word in 1993, so they just made a video instead. Little did they know that a room full of Rubyists would have thoroughly enjoyed it in 2006.

The 12-minute Erlang video is a must see! And yes, despite the obvious humor, this is serious stuff, folks. But enjoy the humor nonetheless...

Test-First JavaScript

(Tue Dec 28, 2004) [/Tools#

If you're thinking of writing some JavaScript, think again. OK, if you must write JavaScript, then it should at least be fun! And what could be more fun than writing JavaScript driven by tests? Wait! Don't answer that. It's all relative, of course, but JsUnit turns that lemon into lemonade, as they say. It's JUnit, only the tests are written in JavaScript and they run in the browser. The test runner even sports a red/green bar that inches forward with each test. Whee! I'll admit, we had some good fun with it at a client site today.

Getting FIT

(Tue Dec 28, 2004) [/Tools#

No, I'm not talking about working off all that turkey from yesterday's feast. I'm talking about Ward Cunningham's Framework for Integration Testing. It's a simple, yet elegant, tool intended to help customers write automated acceptance tests. I've been putting it to the test lately, and my impressions are that it will end up being the xUnit of acceptance testing.

Glenn blogged two entries on this topic: his analysis of FIT and the magic of Ward. Truly excellent insights! Glenn's bandwidth never ceases to amaze me.

FitNesse Beta Released

(Tue Dec 28, 2004) [/Tools#

Uncle Bob and crew just released a beta version of FitNesse: a stand-alone wiki bundled with Ward Cunningham's FIT framework. FitNesse is pure Java (JRE 1.4.0 or newer) and you don't need a web server to make it go. Installation is a piece 'o cake.

With FitNesse, it's never been easier to collaboratively create online documents with embedded acceptance tests expressed in HTML tables. Test fixtures, written in Java, are simple adapters that form the glue between a FIT test and the system behavior being tested. Running the tests on any given page is as simple as clicking a link and watching the rows of each FIT table turn green (or red). Very nice!

Using FileMerge with Subversion

(Tue Dec 28, 2004) [/Tools#

I just discovered svnopendiff: a handy Ruby script that opens Subversion file differences in FileMerge.app. By default, it diffs between the pristine copy and the working copy, presenting a side-by-side view with differences highlighted. A slightly less intelligent zsh script is also available.

I moved all of my projects from CVS to Subversion a while back and have been very happy with the results. The only thing I miss is the ability to go into the attic and torch a file or directory that got added by accident (e.g., a Keynote bundled directory). Subversion currently doesn't have support for permanently removing files that it's been introduced to. Here's hoping the svnadmin obliterate command gets implemented someday soon.

Java's Achilles Heel

(Tue Dec 28, 2004) [/Tools#

While adding some new entries to the JUnit FAQ this morning, I was once again reminded of Java's Achilles Heel - the onerous classpath.

JUnit newbies consistently have trouble correctly setting their CLASSPATH variable. And yet JUnit presents a relatively mild case of classpathitis. All you need is one jar file (junit.jar), your class files, and any other class files your class files depend on. Simple, right? Well, not if the number of mailing list questions regarding the classpath is any indication. The FAQ has helped reduce a lot of confusion, but the scourge of the classpath continues to be widespread throughout the Java community.

I've certainly been bitten by classpath problems more than once. The kind that result in a ClassNotFoundException are usually fairly easy to fix. It typically means your CLASSPATH variable doesn't have all the stuff it should. But the kind of classpath problems that don't conveniently throw exceptions are really nasty. You only suspect there's a problem because the version of a class you think is being used is not. It usually turns out that the class you're expecting to be used is masked by another version of the class at a higher precedence in the CLASSPATH variable. Those kind have a way of robbing massive amounts of your time.

A couple years ago I finally got tired of doing battle with the classpath. After all, it's just like the PATH variable, and the Unix which utility was created as a weapon against pathing problems. Fueled by frustration, I created JWhich to help hunt down insidious classpath problems. After using it to my advantage in a few battles, I wrote an article explaining how it's made my life with Java easier. I generally use it on the command line to check the system classpath, though some folks have adapted it for life inside of a servlet/EJB container. To address classpath problems specifically related to JUnit, WhichJUnit was born.

Perhaps these simple tools will help you spend more time doing the things you'd rather be doing.

pyUnitPerf

(Tue Dec 28, 2004) [/Tools#

Grig Gheorghiu sent word that he has ported JUnitPerf to Python, dubbed pyUnitPerf. His blog has all the deets. He mentioned that he's been using various Python-based test frameworks to basically drive other chunks of software written in Java and C++, so he'll be using pyUnitPerf for this, as well.

One commenter calls the port "unpythonic", which sounds like a really cool name for next year's framework du jour, or a Pixar movie. Seriously, he makes a good point about doing straight ports of Java goodies to other languages. It's easy to overlook powerful features of the destination language and end up with ports that are least common denominators. Consequently, hard-core users don't want to call the code one of their own, and adoption is stifled. I don't know if that's the case here, but Grig strikes me as the type who would welcome any help making pyUnitPerf more "pythonic".

Got Filename Completion?

(Tue Dec 28, 2004) [/Tools#

In my travels visiting various projects, I continue to meet developers wearing out their fingers in the Windows command shell. Just watching them type (and re-type) all those file/directory names character by character is like nails on a chalkboard to me. Growing up on UNIX, I can't imagine life without filename completion. It's another one of those things that computers are good for. Yet I'm surprised that many good developers still don't know it's possible on Windows. (Don't ask why it's not set by default.) So here goes...

Filename completion is your friend. You simply type the first few characters of a file or directory, then hit the filename completion key (TAB). The computer then uses its noggin to figure out which file/directory you're referring to and completes the rest of the word. If the characters you enter match multiple files or directories, then continuing to hit TAB will cycle through the choices. It adds up to a whole lot less typing in the long run and you don't have to remember the exact spelling of names.

Here, just look at how lazy I am. I wouldn't dream of typing

cd c:\myBigFatProjectName\tests
when I can coast through the file system like this:
cd c:\m<tab>\t<tab>

Ah. No more chalkboard noise. Life is good. We might actually get some code written today.

Here's how to turn on filename completion in Windows:

  1. Start the registry editor (regedit) and use Edit->Find to locate the CompletionChar registry key (or navigate to HKEY_CURRENT_USER\Software\Microsoft\Command Processor)
  2. Change the CompletionChar registry key value to 09 (the hexadecimal value of the TAB key)
  3. Restart any open console windows

Note: UNIX veterans will be quick to note that the Windows rendition of filename completion has some shortcomings. For example, you have to type in file separators (\) for it to continue walking down a directory structure. Then again, you're all probably using cygwin with a real shell.

So, I'll continue to spread the word whenever I hear that screeching noise while wandering around projects. In the meantime, take the opportunity to wander around your own project. Watch what other folks do. You'll be amazed at what you can pick up just by shoulder surfing. When I was learning to snowboard, I'd wait for another rider to come by and then try to follow their line down the mountain. Everyone rides with their own style and shadowing a lot of different riders helped me learn much faster than I would have alone.

FIT Teaser

(Tue Dec 28, 2004) [/Tools#

Bill Wake has posted an excellent introduction to FIT. It's a challenge really, intended to give folks an opportunity to practice writing FIT test tables and fixtures. When all the tests pass, you've built the core of a spreadsheet application. It will still need a user interface of course, and that will require different types of tests. In the meantime, your FIT tests will give you confidence in the guts of the spreadsheet application. And in the process you'll have built a UI-independent testing interface to the "business logic".

With FitNesse -- FIT and a Wiki rolled into one -- you don't have to run the tests from the command line. Rather, there's a button labeled Test on the HTML page that when pressed runs all the tests (tables) on that page. Here's the output of running Bill's tests. Notice that passing tests are indicated by green cells; failing tests by red cells showing the expected and actual values for each result. The challenge is to get all the cells to turn green using your own FIT test fixtures.

But before you get too focused on turning the cells green, take a few moments to imagine how you might have written these FIT tests yourself. Or, more appropriately, who you might ask to help you write effective acceptance tests using FIT. It seems to require two skill sets: Java programming and testing.

The test fixtures are written in Java. Each fixture is a Java class that has instance variables to capture the test inputs and methods to invoke actions and return expected results. As such, fixtures are simple adapters to the system under test. That is, they form the glue between the HTML table specifying the test and the API of the production code being tested. Though fixtures can be relatively trivial -- simply delegating all work to the system under test -- they do require someone who knows how to cut Java code. But how do you know what variables and methods a test fixture should have? In other words, what shape should any particular test fixture take in order to effectively test a feature of the application?

Without worrying about the API of the system under test, or writing any Java code whatsoever, you can start writing some FIT tables that specify acceptance tests. FitNesse allows us to edit any page using the browser. By virtue of being a Wiki, FitNesse also offers a convenient markup language for expressing HTML tables without having to actually venture into the nefarious world of angle brackets. We can even write some documentation associated with each test, right there along with the test inputs, actions, and expected outputs. Oh, the tests won't actually pass until you write the FIT test fixture and the production code it exercises. But that's a Java implementation detail. First things first: test then code.

Open the browser, create a new page for our tests... and now what? Well, you have to specify a test of course, but what's a good test? Ah, therein lies the difficult part. You're faced with defining a test that when green gives you (and your customer!) confidence that the feature you're building actually does the right things and does them right. That is, you have to figure out what the feature is supposed to do and how you'll know when it does those things. Later on you'll surely write unit and integration tests as you're implementing the feature to validate your design decisions and sanity check individual components. But right now you're confronted with having to define an acceptance test that tells you when the feature is done.

Take another look at the tests in Bill's challenge. Would you have thought of all those tests? I'm quite sure I wouldn't have. I'd do my best, but I'd like some help. Specifically, I'm willing to bet that someone with more testing experience than I would have taught me a thing or two about what might go wrong. Moreover, they'd probably have different perspectives on what a test fixture for any particular feature should offer. Or perhaps this team member has spent more time with our customer learning how a feature will be used, and now they're speaking on that customer's behalf. Together we could design the test right here in the browser -- adding rows and columns -- before ever writing a line of Java code. And if later we paired while writing the test fixture, I might teach them a thing or two about programming in Java. We might both learn something valuable about software development.

Once we've defined the test fixture, driven by the variables and methods declared in the FIT table, then anyone is free to add new test cases without ever firing up a Java compiler. Want to test a new corner case that's been keeping you up at night? Simply add a new row to a existing table, press Test, and we'll see red or green. And if we see red, then the fact that we collaborated on defining the test using a tool we both understand inclines us to work together to fix the problem. It's our test.

Automating tests is the easy part. Computers do all that work for us. Writing good tests that can be automated to continuously tell us if we've built the right thing right, now that's the tough part. I want all the help I can get. I find pairing with someone with testing experience to write FIT tests to be quite efficient and enjoyable. I prefer to do that as a matter of course before I start investing time writing production code.

FIT won't be the only testing tool we use, but it is one way we can proactively take a step (or ten) toward each other. In doing so, we might actually deliver better software faster.