Thursday, November 6, 2014

The horrible state of open source tools

Are you kidding me???

Recently I wrote a performance testing tool in Ruby and I have been rewriting it in Java. The tool uses Cucumber, so I have decided to substitute JBehave, since JBehave is the predominant BDD tool in the Java space, and also because I tried to use the Java version of Cucumber but it is broken and incomplete. (Sigh - why not call it "beta"?)

So I first looked at the JBehave docs, and was irritated to discover that there are no code examples: you have to jump through hoops, such as running, in order to just see an example. I don't know what is and I don't want to know - I just want to see a friggin' code example. So I googled and found one - a good one - here.

Even better, the example gets right to the point and shows me how to run JBehave without having to use any other tools - most JBehave examples use JUnit, which I detest. I just want to run JBehave. Period. No complications. This is how you do it:
Embedder embedder = new Embedder();
List<String> storyPaths = Arrays.asList("Math.story");
embedder.candidateSteps().add(new ExampleSteps());
The file path ending in ".story" is from the example, and I wanted to find out the exact rules for what that path could be (the explanation of the example is not clear), so I went to the JBehave Javadocs, and this is what I found:

Are you kidding me??? - oh, I already said that.

I am used to Javadocs serving as a definitive specification for what a method does. In contrast, the JBehave methods have no header comments, and so the Javadoc methods have no specs. How is one supposed to know what each method's intended behavior is?

Am I supposed to go and find the unit tests and read them and infer what the intended behavioral rules are? Maybe if I had hours of spare time and that kind of perverse gearhead curiosity I would do that, but I just want to use the runStoriesAsPaths method. An alternative is to dig through examples and infer, but that is guesswork and needlessly time consuming.

Unfortunately, this is a trend today with open source tools: not commenting code. The method name gives me a hint about the method's intended behavior, but it does not fill in the gaps. For example, can a path be a directory? Is the path a feature file? What will happen if there are no paths provided - will an exception be thrown or will the method silently do nothing?

This is trash programming. Methods need human readable specifications. Agile is about keeping things lean, but zero is not lean - it is incompetent and lazy. A good programmer should always write a method description as part of the activity of writing a method: otherwise, you don't know what your intentions are: you are hacking, trying this and that until it does something that you want and then hurrying on to the next method. This is what I would expect a beginner to do - not an experienced programmer.

Yet so many tools today are like this. It used to be that if you used a new tool, you could rely on the documentation to tell you truthful things: if something did not work, you either did not understand the documentation or there was a software bug. Today, the documentation is often incomplete, or just plain wrong: it often tells you that you can do something, but in reality you have to do it in a certain way that is not documented. That is what I found to be the case with the Java plugin for Gradle. Recently I wrote a Java program that took me two hours to write and test (without JUnit or any other tools - just writing some quick test code), and then I spent a whole day trying to get the Gradle Java plugin to do what I wanted. That is not a productivity gain!

Tools that are fragile and undocumented are a disservice to us all. If you are going to write a tool, make sure that the parts that you write and make available work, and are documented, and work according to what the documentation says - and don't require a particular pattern of usage to work.