Battle of the fonts

I decided to revisit my choice of programming fonts recently, mostly inspired by this article.

After trying the various fonts in this article, I narrowed down my choices to Consolas and Inconsolata. Here is what they look like:

Consolas 12 Inconsolata 12
Inconsolata 13

They all look great in Eclipse. The Inconsolata font is freely available but Consolas is a bit more tricky to obtain on Mac since it’s a font created by Microsoft and usually shipped with Microsoft products.  Here are instructions how to install it on your Mac.

Any other suggestions for good programming fonts?

New blog

Those of you reading this on the web probably already noticed that I changed my blog. I upgraded from Movable Type 2 (yes, 2) to Wordpress.

My older blog is still available at the address http://beust.com/weblog2 and I made sure to update the RSS feeds and put in place all the mod_rewrite rules necessary to make this transition absolutely transparent to everyone, so hopefully, I didn’t lose anyone in the process.

More on multithreaded topological sorting

I received a few interesting comments on my previous entry regarding the new multithreaded topological sort I implemented in TestNG and there is one in particular from Rafael Naufal that I wanted to address:

The @Priority annotation couldn’t be adapted to say which free methods get scheduled first? BTW, the responsibility of knowing which nodes are free couldn’t be moved to the graph of test methods?

This is pushing my current algorithm even further in the sense that we not only want to schedule free nodes as they become available, we also want to schedule them in order of importance.

What makes a node more important than another? Its level of dependencies. The more a node is depended upon, the more beneficial it is to schedule it as soon as possible since this will end up freeing more nodes. Admittedly, you are still bounded by the size of your thread pool, but this is exactly what we want: increasing the pool size should lead to more parallelism and therefore better performance, but the current scheduling algorithm being fair (or random) means that we are not guaranteed to see this performance increase.

My first reaction was to modify my Executor but as it turns out, you can actually do this with the existing implementation. The constructor of all the Executors takes a
BlockingQueue in parameter, which is the queue that the Executor will use to process the workers. Unsurprisingly, there already is a priority queue called PriorityBlockingQueue.

All you need to do is to use that queue instead of the default one when you create your Executor and then make sure that the workers you pass it have a natural ordering. In this case, the weight of a worker is how many other workers depend on it, which is very easy to calculate.

On a related topic, I wanted to get a closer look at how the algorithm I described in my previous blog post actually works. I described the theory and I have tests that show that it seems to work as expected, but it occurred to me that I could actually “view it from the inside” with little effort.

First, I added a method called toDot which generates a Graphviz file representing the current graph. This turned out to be trivial:

/**
* @return a .dot file (GraphViz) version of this graph.
*/
public String toDot() {
  String FREE = "[style=filled color=yellow]";
  String RUNNING = "[style=filled color=green]";
  String FINISHED = "[style=filled color=grey]";
  StringBuilder result = new StringBuilder("digraph g {\n");
  Set<T> freeNodes = getFreeNodes();
  String color;
  for (T n : m_nodesReady) {
    color = freeNodes.contains(n) ? FREE : "";
    result.append("  " + getName(n) + color + "\n");
  }
  for (T n : m_nodesRunning) {
    color = freeNodes.contains(n) ? FREE : RUNNING;
    result.append("  " + getName(n) + color + "\n");
  }
  for (T n : m_nodesFinished) {
    result.append("  " + getName(n) + FINISHED+ "\n");
  }
  result.append("\n");
  for (T k : m_dependingOn.getKeys()) {
    List<T> nodes = m_dependingOn.get(k);
    for (T n : nodes) {
      String dotted = m_nodesFinished.contains(k) ? "style=dotted" : "";
      result.append("  " + getName(k) + " -> " + getName(n) + " [dir=back " + dotted + "]\n");
    }
  }
  result.append("}\n");
  return result.toString();
}

Then I modified the executor to dump the graph every time a worker terminates, and finally, I wrote a shell script to convert these dot files into images and to create an HTML file. I ran a simple test case, processed the files with the shell script and here is the final result.

A yellow node is “free”, green means that the node is “ready” (to be run in the thread pool), grey is “finished” and white nodes haven’t been processed yet. Dotted arrows represent dependencies that have been satisfied.
As you can see, the execution matches very closely what you would expect based on my description of the algorithm and I confirmed that changing the size of the thread pool creates different executions.

Hard core multicore with TestNG



I recently implemented a new feature in TestNG that took me down an interesting technical path that ended up mixing graph theory with concurrency.

Here are a few notes.

The problem

TestNG allows you to declare dependencies among your test methods. Here is a simple example:

@Test
public void a1() {}

@Test(dependsOnMethods = "a1")
public void b1() {}

@Test
public void x() {}

@Test
public void y() {}

In this example, b1() will not run until a1() has completed and passed. If a1() fails, b1() will be marked as “Skipped”. For the purpose of these articles, I call both method a1() and b1() “dependent” methods while x() and y() are “free” methods.

Things get more interesting when you want to run these four test methods in parallel. When you specify that these methods should be run in a pool of three threads, TestNG still needs to maintain the ordering of a1() and b1(). The way it accomplishes this is by running all the dependent methods in the same thread, guaranteeing that not only will they not overlap but also that the ordering will be strictly respected.

The current algorithm is therefore simple:

  • Break all the test methods into two categories: free and dependent.
  • Free methods are thrown into the thread pool and executed by the Executor, one method per worker, which guarantees full parallelism.
  • Dependent methods are sorted and run into an executor that contains just one thread.

This has been the scheduling algorithm for more than five years. It works great, but it’s not optimal.

Improvements

Dependent methods are a very popular feature of TestNG, especially in web testing frameworks such as Selenium, where the testing of pages is very dependent on the ordering in which operations are performed on these pages. These tests are typically made of a majority of dependent methods, which means that the current scheduling algorithm makes it very hard to leverage any parallelism at all in these situations.

For example, consider the following example:



Since all four methods are dependent, they will all be running in the same thread, regardless of the thread pool size. An obvious improvement would be to run a1() and b1() in one thread and a2() and b2() in a different thread.

But why not push thing further and see if we can’t just throw all these four methods in the main thread pool and still respect their ordering?

This thought led me to take a closer look at the concurrent primitives availables in the JDK, and more specifically, Executors.

My first question was whether it was possible to add workers to an Executor without necessarily having them ready to run right away, but this idea soon appeared to me as going against the principle of Executors, so I abandoned it.

The other idea was to see if it was possible to start with only a few workers and then add more workers to an Executor as it’s running, which turns out to be legal (or at least, not explicitly prohibited). Looking through the existing material, it seems to me that Executors typically do not modify their own set of workers. They get initialized and then external callers can add workers to them with the execute() method.

At this point, the solution was becoming fairly clear in my mind, but before I get into details, we need to take a closer look at sorting.

Topological sort

In the example shown at the beginning, I said that TestNG was sorting the methods before executing them but I didn’t explain exactly how this was happening. As it turns out, we need a slightly different sorting algorithm than the one you are used to.

Looking back at this first example, it should be obvious that there are more than one correct way to order the methods:

  • a1() b1() x() y()
  • x() a1() b1() y()
  • y() a1() x() b1()

In short, any ordering that executes a1() before b1() is legal. What we are doing here is trying to sort a set of elements that cannot all be compared to each other. In other words, if I pick two random methods “f” and “g” and I ask you to compare them, your answer will be either “f must run before g”, “g must run before f” or “I cannot compare these methods” (for example if I give you a1() and x()).

This is called a Topological sorting. This link will tell you all you need to know about topological sorting, but if you are lazy, suffice to say that there are basically two algorithms to achieve this kind of sort.

Let’s see the execution of a topological sort on a simple example.

The following graphs represent test methods and how they depend on
each other. Methods in green are “free methods”: they don’t depend on any other methods. Arrows represent dependencies and dotted arrows are dependencies that have been satisfied. Finally, grey nodes are methods that have been executed.



First iteration, we have four free methods. These four methods are ready to be run.

Result so far: { a1, a2, x, y }



The four methods have been run and they “freed” two new nodes, b1 and b2, which become eligible for the next wave of executions. Note that while one of d’s dependencies has been satisfied (a1), d still depends on b1 so it’s not free yet.

Result so far: { a1, a2, x, y, b1, b2 }



b2 and b1 have run and they free three additional methods.



The last methods have run, we’re done.

Final result: { a1, a2, x, y, b1, b2, c1, c2, d }

Again, note that this is not the only valid topological sort for this example: you can reorder certain elements as long as the dependencies are respected. For example, a result that would start with {a2, a1} would be as correct as the one above, which starts with {a1, a2}.

This is a pretty static, academic example. In the case of TestNG, things are a lot more dynamic and the entire running environment needs to be re-evaluated each time a method completes. Another important aspect of this algorithm is that all the free methods need to be added to the thread pool as soon as they are ready to run, which means that the ExecutorService will have workers added to its pool even as it is running other workers.

For example, let’s go back to the following state:



At this stage, we have two methods that get added to the thread pool and run on two different threads: b1 and b2. We can then have two different situations depending on which one completes first:



b1 finishes first and frees both c1 and d.

Or…



b2 finishes first but doesn’t free any new node.

A new kind of Executor

Since the early days, TestNG’s model has always been very dynamic: what methods to run and when is being decided as the test run progresses. One of the improvements I have had on my mind for a while was to create a “Test Plan” early on. A Test Plan means that the engine would look at all the TestNG annotations inside the classes and it would come up with a master execution plan: a representation of all the methods to run, which I can then hand over to a runner that would take care of it.

Understanding the scenario above made me realize that the idea of a “Test Plan” was doomed to fail. Considering the dynamic aspect of TestNG, it’s just plain impossible to look at all the test classes during the initialization and come up with an execution plan, because as we saw above, the order in which the methods are run will change depending on which methods finish first. A Test Plan would basically make TestNG more static, while we need the exact opposite of this: we want to make it even more dynamic than it is right now.

The only way to effectively implement this scenario is basically to reassess the entire execution every time a test method completes. Luckily, Executors allow you to receive a callback each time a worker completes, so this is the perfect place for this. My next question was to wonder whether it was legal to add workers to an Executor when it’s already running (the answer is: yes).

Here is an overview of what the new Executor looks like.

The Executor receives a graph of test methods to run in its constructor and then simply revolves around two methods:

/**
* Create one worker per node and execute them.
*/
private void runNodes(Set<ITestNGMethod> nodes) {
  List<IMethodWorker> runnables = m_factory.createWorkers(m_xmlTest, nodes);
  for (IMethodWorker r : runnables) {
    m_activeRunnables.add(r);
    setStatus(r, Status.RUNNING);
    try {
      execute(r);
    }
    catch(Exception ex) {
      // ...
    }
  }
}

The second part is to reassess the state of the world every time a method completes:

@Override
public void afterExecute(Runnable r, Throwable t) {
  m_activeRunnables.remove(r);
  setStatus(r, Status.FINISHED);
  synchronized(m_graph) {
    if (m_graph.getNodeCount() == m_graph.getNodeCountWithStatus(Status.FINISHED)) {
      shutdown();
    } else {
      Set<ITestNGMethod> freeNodes = m_graph.getFreeNodes();
      runNodes(freeNodes);
    }
  }
}

When a worker finishes, the Executor updates its status in the graph. Then it checks if we have run all the nodes, and if we haven’t, it asks the graph the new list of free nodes and schedules these nodes for running.

Wrapping up

This is basically a description of the new TestNG scheduling engine. I tried to focus on general concepts and I glossed over a few TestNG specific features that made this implementation more complex than I just described, but overall, implementing this new engine turned out to be fairly straightforward thanks to TestNG’s layered architecture.

With this new implementation, TestNG is getting as close to possible to offering maximal parallelism for test running, and a few Selenium users have already reported tremendous gains in test execution (from an hour down to ten minutes).

When I ran the tests with this new engine, very few tests failed and the ones that did were exactly the ones that I wanted to fail (such as on that verified that dependent methods execute in the same thread, which is exactly what this new engine is fixing). Similarly, I added new tests to verify that dependent methods are now sharing the thread pool with free methods, which turned out to be trivial since I already have plenty of support for this kind of testing.

This new engine will be available in TestNG 5.11, which you can beta test here.

Supporting unit testing natively in programming languages: follow-up

There were quite a few interesting comments on my previous entry about supporting unit tests directly inside a language, so I thought I’d address some of these observations.

Michael suggests to keep the unit tests near the method they test:

@Tests({
@Test(3, 4: 7),
@Test(-2, 0: -2)
})
public int add(int x, int y) { return x + y; }

My main hesitation about this approach is that the production code is now littered with test code, and even if you use an IDE that conveniently lets you fold these tests away, it’s still painful to read such code in non-IDE environments, such as web browsing, code reviews, terminal diff, etc… This is one of the reasons why I suggested to have the unit test section in one place.

There is also the problem that unit tests usually require more than just “parameters in, result out”: very often, you will need to initialize your objects or perform some arbitrary code to set things up.

Dan is worried about pulling test dependencies in your production code:

What about test-only dependencies? Your production code would depend on mock libraries, Hamcrest expressions, etc.

Yes, this is used to be my strongest argument when I was against the idea of mixing unit tests with code, but this objection disappears if you actually embed this functionality in the language. I argued in my post for a new keyword called unittest that would define a brand new section, so I don’t see why this section couldn’t include its own imports as well:

unittest {
import org.testng.Assert;
public void positiveNumbers() {
Sum sum = new Sum();
Assert.assertTrue(sum.add(3,4) == 7);
}
}

This code will only be compiled if the compiler is invoked with the option -unittest, and otherwise, it will be simply ignored.

Dan adds:

the main gotcha is standardizing on how to run unit tests

Exactly, and that’s my point: this aspect is very underestimated and it’s the reason why so much code is written every day without accompanying unit tests. If you move this functionality inside the language, you create a universal framework across all companies and all projects that make testing a very natural part of the coding process in that particular language.

When you receive a piece of code for review, you now expect the accompanying unit test to be part of that file.

A few people chimed in to advocate Maven, but regardless of my feelings toward this tool, Maven doesn’t solve the problem I’m trying to address here since it’s yet another tool that’s external to the language, which means that it won’t always be available wherever that language is used.

A reader called Mikew is using something similar to my suggestion in Java at his workplace. He and his teammates are using inner classes to put test code inside their production code, and it seems to be working for them, despite the downsides of such an approach. As I pointed out, a lot of these downsides would disappear if such a functionality was supported natively.

Python’s Doctest doesn’t seem very scalable to me, especially because it makes you write code in comments and that the scope of the tests that you can write is extremely limited, but I agree with the underlying intention.

Phil Goodwin brought Eiffel into this discussion:

This was an assertion framework, and so did not quite support the whole testing story. Nevertheless, it provides a substantial foundation for embedding test code into source.

Eiffel’s support for testing, and the whole idea of Design by Contract in general, has always struck me as a toy that only works in trivial cases. Eiffel supports preconditions, postconditions and invariants, but in my experience, these concepts only work for foundation and library classes (e.g. containers) but scale very poorly in the real world (good luck coming up with an invariant for a class that’s manipulating database records while managing transactions).

I wrote a lot of code in Eiffel a long time ago and I distinctly remember that writing either of these contracts became plain impossible very quickly.

Having said that, Eiffel is the only language (besides D) that I can think of that supports arbitrary blocks of code to be included in classes while having a special status attached to them (“this is test code”).

Overall, the concept of something similar to a unittest section in a programming language continues to be very appealing to me and I am betting that if a language supporting this feature emerges in the next few years, the overall quality of code written in that language will be significantly higher than what we are used to.

Should programming languages support unit testing natively?

I used to be strongly opposed to this idea but I started changing my mind recently. Here is what happened.

The bad

Production and test code can be integrated at various levels:

  1. Supported by the language.
  2. Not supported by the language but mixing production and test code in the same classes.
  3. Production and test code live in different classes but in the same directory.
  4. Production and test code live in different directories.

I have always thought that options 2) and 3) are a bad idea because they make it hard to read and review the code, they contribute to the creation of huge classes and they negatively impact your build infrastructure (which must now be able to strip out the test code when you want to create a shippable binary). We (Google) feel strongly about these points, so we are strictly enforcing option 4) (although we often put our tests in the same package as the production code).

I think this practice is the most common out there and it works very well.

With that in mind, wouldn’t a language that natively supports unit testing be the worst case scenario?

The epiphany

Not long ago, I reflected on my testing habits for the past ten years, and I made a couple of interesting observations:

  • I feel the need to write tests for the code that I write very often.
  • Just as often, that need is thwarted by environmental constraints, so I end up not writing these tests.

My experience is with large software, large teams and huge code bases. When you work in this kind of environment, it’s very common for the company to have developed its own testing infrastructure. Sure, the code remains code, but how you run it and how you deploy it will vary greatly from company to company (and sometimes even from project to project).

Typically, I code a feature, iterate over it a few times and I reach a point when I’m pretty happy with its shape: it’s looking decent, it gets the job done and while there is obviously more work to be done on it, it’s mature enough that writing tests for it at this point will not be a waste.

The code to write these tests is usually pretty obvious, so I can form it in my head pretty quickly and materialize it in code not long after that. Now I need to find a way to actually run this test and make it part of our bigger testing infrastructure, and this is where things usually get ugly. I typically find myself having to change or update my environment, invoke different tools, pull out various wiki/HTML pages to brush up on what’s required to integrate my tests to the big picture.

The worst part is that I will probably have to relearn everything from scratch when I switch to the next project or the next job. Again, I will write the test (which is pretty easy since it’s the same language I used to write the production code) and I will find myself having to learn a brand new environment to run that test.

The environmental hurdle is not easy to address, but if the language that I am coding in supported unit tests natively, I would probably be much more tempted to write these tests since 1) there is now an obvious location where they should go and 2) it’s very likely that the test infrastructure in place knows how to run these tests that I will be writing.

The main gain here is that the developer and the testing infrastructure now share a common knowledge: the developer knows how to write tests and the infrastructure knows how to access these tests. And since this mechanism is part of the language, it will remain the same regardless of the project or the company.

How do we do it?

So what would a language that natively supports unit tests look like?

I know first hand that writing a test framework is not easy, so it’s important to make sure that the test feature remains reasonably scoped and that it doesn’t impact the language complexity too much. You will notice that throughout this entire article, I make a point of saying “unit test” and not just “test”. As much as TestNG is focused on enabling the entire spectrum of testing, I think it’s important for a language to only support unit testing, or more precisely, to only make it easy to test the compilation unit that the test is found in.

Interestingly, very few modern languages support unit testing, and the only one that I found among the “recent” ones is D (I’m sure commenters will be happy to point me to more languages).

D’s approach is pretty minimal: you can declare a unittest section in your class. This keyword acts as a method and you simply write your tests inside:

//
// D
//
class Sum
{
int add(int x, int y) { return x + y; }
unittest
{
Sum sum = new Sum;
assert(sum.add(3,4) == 7);
assert(sum.add(-2,0) == -2);
}
}

This is as barebones as it can get. The advantage is that the impact on the language itself is minimal, but I’m wondering if I might want to be able to write different unit test methods instead of having just one that contains all my tests. And if we’re going down that path, why not make the unittest keyword be the equivalent of a class instead of just a method?

//
// Pseudo-Java
//
public class Sum {
public int add(int x, int y) { return x + y; }
}
unittest {
public void positiveNumbers() {
Sum sum = new Sum();
assert(sum.add(3,4) == 7);
}
public void negativeNumbers() {
Sum sum = new Sum();
assert(sum.add(-2,0) == -2);
}
}

As I said earlier, I think it’s very important for this feature to remain as simple as possible, so what features from sophisticated testing frameworks should we remove and which ones should we keep?

If we stick with D’s approach, there is probably little we can add, but if we go toward a class keyword, then there are probably two features that I think would be useful:

  • Method setUp/tearDown (which would already be useful in the example above, where we create a new Sum object in both test methods.
  • Exception testing.

At this point, I’m already feeling a bit uncomfortable with the extra complexity, so maybe D’s simplistic approach is where we should draw the line.

What do you think about native support for unit testing in programming languages? And what features would you like to see?

How to “Go Home” on your Verizon Droid (and Android in general)

As you probably know by now, Verizon’s Droid has been officially announced and it will be available in the US on November 6th.

It’s running Android 2.0 (“Eclair”), which is by far the most advanced release we have worked on. And in case you didn’t follow, this is the third official release in about a year (there has actually been one more that was never made official).

One of the features that has received the most coverage so far is our turn-by-turn navigation application, which turns your Droid into a speaking GPS device. While most articles I have read do a good job of covering its basic features, some articles deplore the absence of a “Go Home” function.

Well, actually, this function already exists.

It’s very simple really, all you need to do is create a home shortcut. Here is how you do it:


    



Long press on the Home screen, select Shortcuts and then Directions.




Make sure that “Turn by turn navigation” is checked.
Enter your home address (or any other),
pick a name for your shortcut and press “Save”.


    


Your shortcut is ready, tap it to start navigating.

Happy navigation on your Droid!

Why I think that IDEA going open source is not a good sign


It looks like I shocked quite a few people with my recent prediction of doom for IDEA, so I thought I’d take some time to elaborate.

Here is what I said:

cbeust: JetBrains deserves the utmost respect for what they have created and pioneered, but IDEA going opensource means that it will now slowly die

cbeust: About IDEA: commercial software that goes open source never ends well, even for products that don’t suck

First of all, I’d like to make it crystal clear that I have nothing but the utmost respect for the guys at JetBrains, who possess three very rare qualities:

  • They are innovators. It’s not exactly easy to come up with new ideas, whatever your field is, but these guys have come up with a lot of concepts that are now part of every developer’s daily life.
  • They know how to write a great application. Who would have imagined that it would be possible to create not only such a snappy Swing application but also one that just seems to read your thoughts?
  • They managed to sell their product while competing against a free product that is of equally high quality (Eclipse) and funded by a very rich company (IBM).

About that last point: there is a saying that claims that if you are trying to sell software that competes against free products, you should change business. I don’t buy that, and it’s not just because I used to work for a company that was doing exactly that (BEA). A lot of companies are doing fine selling products that compete with free software, and they all have one thing in common: their product doesn’t suck. JetBrains can certainly be counted as one of them.

Having said all this, I still see the move from commercial to open source as a sign that the business is struggling. A lot of companies have gone down that path in the past and all of them have tried to make it pass as a selfless action meant to help the community, but the truth is that they were just having a harder time selling their software, so making it open source is usually a last ditch effort to regain mindshare while trying to make money somewhere else.

I can’t think of a single example where a struggling commercial software suddenly started regaining market share when they went open source. Can you?

I have no insight on how well JetBrains is doing, so it’s quite possible that they are one of these rare exceptions. Maybe they were making tons of money with IDEA licenses and they really decided to suddenly give the product away out of kindness for the Java community. Even with these parameters, it still doesn’t really sound like a good idea to me, but well.

Whatever side of the fence you stand on, one thing is clear about this move: it means less revenue for JetBrains for the foreseeable future. And what this means is that they will have less means to compete against Eclipse and less power to add features to either of the editions (the Community one or the Ultimate one).

And this is where a lot of companies make a fatal mistake: they think that making their software open source will automatically generate a ground swell of patches and additions from the community that will float them back to the top.

And in my experience, this never happens.

Oh patches will be sent and I’m sure a few isolated developers will come up with very cool additions to IDEA, but without a committee of JetBrains employees at the receiving end to sort through these patches and act as a strong steward (“reject this one”, “accept this one as is”, “accept this one but it needs more work”, “accept this one but we need to integrate it with XXX”, etc…), these patches will just start piling up and they won’t be processed.

The challenge here is not just technical, it’s about product management, and open source communities are just not good at that. Hackers scratch their itch and when they’re done, they move on to the next itch with very little interest in how buggy their code is or how well it integrates with the rest of the platform. They leave that up to others.

So I’m pretty pessimistic about IDEA’s future. I think the community edition will soon start stagnating and in one year, it will have made little progress. The Ultimate edition might fare well for a little while, as long as fans help support it by paying the $249, but I’m skeptical that this revenue will be enough to keep such an ambitious product alive.

And of course, Eclipse’s apparently unstoppable momentum isn’t helping. These guys just don’t seem to rest and the amount of features and directions that they keep expanding on is just mindboggling.

I wish the best to IDEA. I really do. I think Eclipse wouldn’t be nearly as good as it is right now if IDEA wasn’t around and IDEA’s disappearance from the landscape would mean that Eclipse risks stagnation as well. Competition is good for users. I really hope that I’m wrong with my predictions.

Let’s meet again here in one year.

Duct tape and the brittleness of agility

Duct tape, reloaded

In a recent article, Joel Spolsky discusses the concept of the “duct
tape programmer”. According to Joel, a duct tape programmer is a
developer that “gets things done”. They don’t spend too much time
over designing, discussing or writing tests: they just sit down at
their desk and code until the feature is ready to be used by
customers.

Joel uses Jamie Zawinski (jwz) as the perfect example of a duct tape
programmer. For people who don’t know jwz, he was made famous during
the Lucid/XEmacs/Netscape era. He was known for never sleeping and
tirelessly being busy coding. His contributions include vast portions
of XEmacs (in C and Lisp) and countless features in Netscape. He
retired from coding a few years back, bought a club in San Francisco
which he uses to organize events. His web
site
still shows his undying geekdom and if you’ve never had a
chance to read about them, check out href="http://www.jwz.org/tent-of-doom/">some of the pranks he came
up with during his tenure at Netscape.

jwz is the perfect example of a duct tape programmer and the kind of
developer that Joel would want on his team, as opposed to “software
astronauts” that spend more time discussing problems than implementing
solutions.

Clean Code is code that hasn’t been run enough times

Not surprisingly, Rob Martin didn’t like Joel’s article. Although he
tries to be civil and compromising, Rob is pretty much at the other
end of the spectrum when it comes to software development. In
particular, Joel’s emphasis that testing should come second since it
doesn’t directly impact customer satisfaction rings a sour note with
the entire Agile community.

The funniest part in Rob’s rebuttal article was:

Programmers who say they don’t have time to write tests are living in
the stone age. They might as well be saying that man wasn’t meant to
fly.

Well, man is indeed incapable of flying, which is why we need to use
devices to achieve that goal.

Joking aside, Rob’s assertion that a software product that is not
tested is necessarily buggy is pure fantasy. There are thousands of
software products that we use regularly that are probably very poorly
tested (or poorly automatically tested), and yet, they work and they
are fairly usable.

The crux of the disagreement can probably be found in Rob’s following
statement:

I want you to ship, but I don’t want you to ship shit.

Nobody can disagree with this, but I bet you that Joel and Rob have
very different ways of defining “shit” in the software world. For
Joel Spolsky and Jamie Zawinski, “shit” is a product that is buggy or
unusable. For Rob Martin, “shit” is software that wasn’t designed
with TDD and that doesn’t have 100% test coverage.

In order to understand their standpoint, it’s important to keep in
mind who these two people are and what they do. Joel is the founder
of a fairly successful software company and their flagship product,
Fogbugz, a bug tracker, seems to be quite liked by its users.
Rob Martin is employed by Object Mentor, a
methodology consultant company.

They both have something to sell, although it seems to me that Joel
probably doesn’t expect that this kind of article will help boost the
sales of Fogbugz. On the other hand, it’s important for Object Mentor
to make sure that Agile, XP and the other methodologies that their
business is based on, keep being discussed and cited as positive
technologies that help deliver products faster.

Is Agile on the way out?

Joel’s article is just the most recent example of a growing backlash
that is slowly building against Agile and XP. Here is
another testimony from Mike Brunt, someone who has had a terrible
experience with the practice.

Even though it’s unlikely that Joel and Mike know each other or read
each other’s article before writing their own, some of Mike’s points
are very close to what Joel is saying. For example:

Agile programming emphasizes coding.

This may sound like a good thing but it really is not, especially when
you emphasize coding over feature #1 (shipping). Unit tests fall into
that category. Unit tests are tools for the programmers. They are a
convenience, one of the many ingredients that you use in the kitchen
but that your customers really don’t care much about.

The extreme emphasis on developer comfort (unit tests, code coverage,
TDD, etc…) over the satisfaction of your customers is something that
has always deeply disturbed me in the Agile/XP movement. I have
expanded in more details on this topic in href="http://www.amazon.com/Next-Generation-Java-Testing-Advanced/dp/0321503104">my
book, so I won’t repeat everything here, but there is another
point that I feel strongly about: if I have time to write either a
unit test or a functional test, I will always pick the latter, because
such a test will exercise a feature of the product that my users will
be seeing, as opposed to a unit test, which is only destined to make
my life easier (i.e. find bugs faster).

Agile is fragile

The comments on Mike’s articles were not very friendly. It doesn’t
take much to get Agilists riled up, and this post was no exception.
However, most of these comments are all using the same old tired
argument: “if you use Agile and it didn’t work for you, you were not
doing Agile properly”.

This argument is very similar to the one you read whenever somebody
dares to post that Linux is not working out for them: “Oh you’re
using Fedora (1)? No wonder you’re having these problems, you should be
using Ubuntu (2)”. Replace (1) and (2) with href="http://en.wikipedia.org/wiki/List_of_Linux_distributions">any of the Linux distributions and
you basically have the template of the response you will see on any
post that dares to criticize Linux.

This sort of answer is very similar to “Oh Agile didn’t work for you
because you were doing Agile wrong”, and both these statements come
from delusional people who just don’t understand that if their
technology is so hard to use “right”, then it’s useless.

Brittleness in software

Linux and Agile/XP are both technologies that I call
“brittle”. Brittle because you need to manipulate them
very carefully or they will just explode in your hands. Brittle because
you need to follow extremely precise guidelines to use them, and
failure to do so dooms you to failure.

Finally, they are brittle because the amount of expertise necessary to
use these technologies is simply too high.

However, Agile/XP is in much worse shape than Linux, which has quite a
few success stories. Put in the right hands and used in the right
conditions, Linux can do wonders, and hundreds of companies (including
my employer) can attest to that. But
Agile/XP doesn’t really have any track record of success to show
despite many, many years of trying to become mainstream.

Ironically, the few times where I have seen a few Agile practices
being successful was when the teams using them were cherry-picking
from the Agile manifesto.
They read all the points in the Agile manifesto, chose the practices
that made sense to them and disregarded the rest. And it worked.

Agilists are not very agile

There are two paradoxes here:

  • Teams that “don’t do Agile” (i.e. they don’t follow the
    manifesto to the letter) can be successful.

  • The very same people who advocate Agile are actually far from
    being agile and open-minded. “Agile means this and no variation is
    allowed” never sounded very agile to me.

I know Rob Martin really believes in all these principles he advocates,
but it’s really hard for me to forget the fact that he’s making a
living out of them. If software methodologies become easy to apply
and they no longer require a five day course to learn, his employer
will go out of business.

On the other hand, while Joel Spolsky never misses an opportunity to
mention Fogbugz (and I can’t really blame him, it’s what his company
does), I don’t think he has much to gain from a commercial standpoint
with this kind of article. I do think that he’s exaggerating his
points a little bit in order to be provocative and generate indirect
publicity and I’m pretty sure that Fogbugz is a lot more tested than
he wants us to think.

But overall, I’m happy to see the pendulum beginning to swing the
other way. Instead of advocating religious methodologies, I want to
see thought leaders suggest common sense and judgment and show
flexibility when it comes to recommending technologies. I think we
will have reached this point when an Agile advocate comes to see me,
takes a look at my team, chats with them a little bit and then tells
me “I think stand-up meetings will be useful to your team but you
should probably not use pair programming”.

Now, this is true agility.

More pastry for the Android


Our mascot received a new companion today.