Mouseless Firefox

Firefox's default keyboard shortcuts do a pretty darn good job of giving you everything you need to browse the web mouseless.

Backspace = Back
Shift + Backspace = Forward
Tab = Next Field (If you didn't know this one already...)
/ = Search Text
' = Search Links Only
F3 = Search Again

Once you've got a link selected:
  Enter = Open Link in current tab
  Ctrl/Cmd+Enter = Open Link in new tab
  Shift + Enter = Open link in new window

Spacebar = Page Down
Shift + Spacebar = Page Up
CMD + L = Jump To Location Bar (CTRL + L on Windows, I think)
Ctrl/Cmd+Tab = Switch tabs
Ctrl/Cmd+[1-9] = Select tab (1-9)
You can find the full list of firefox shortcuts here

My New MVC Metaphor: The Command Line

A useful metaphor for the MVC pattern struck me today: The command line. A command line prompt gives you all the elements of an MVC architecture.

The Models

On the command line, the model elements are the programs you execute. ls, grep, awk, cat, wget, etc... all of those wonderful tools that actually get things done.

The Controllers

The controller elements are the things you use to tie the models together. The pipes, the redirects, the ampersands. All of these things allow you to tie models together in an infinite number of different combinations to do what you want. The proportion of models to controllers in any given system (or command) is high. You want it to be mostly models with a little controller glue...but without the controllers, the models are nearly useless. The result of all of this, then, is:

The View

Standard Out. Of course, the command line only really has one native input/output format: text. But oh what a format it is.

And the last component...

There's one more component we haven't addressed in this equation, but I'll leave that as an exercise to the reader.

svn replacement for git stash

I had no idea how dependent I'd become on git's stash function until I needed it while working on a project that uses subversion. I needed to make a quick change to a class to support a change to a schema change to a live server (don't ask), but I was already in the middle of working on another task.

Thankfully, you can approximate git stash by creating a patch file:

% svn diff > WorkInProgress.txt
% svn revert -R .
<make changes>
% svn commit -m "Patched to support server schema change"
% patch -p0 -i WorkInProgress.txt
% rm WorkInProgress.txt

Agile 2009 Sessions

If you're headed to Agile 2009 this year, and you're at all interested in TDD, be sure to swing by my two talks: Test Driven Development in Java: Live and Uncensored and Continuous Testing Evolved.

The TDD session will be a lot of fun. I've found that solving real-world problems in front of an audience can lead to some unexpected outcomes which are usually entertaining and informative for everyone. Plus, it keeps me on my toes!

I'm hoping the Continuous Testing session will spark some discussion about the future of TDD, Continuous Integration and automated testing in general. I really think CT is the future of automated testing, and Rod and I are going to be bringing some great new research and insight to the conference for this session.

Dual Licensing for Infinitest

In the latest release of Infinitest, we've moved to a dual license model. While the terms of the commercial license are nothing special, the terms of the free license are rather innovative: It's free for individuals. Companies that want their employees to use the tool can buy a commercial license from our newly formed company, Improving Works. While I think this license is actually quite straightforward, its novelty demands an explanation. What does "free for individuals" mean anyway? (Hint: it's not the same as "personal use")

First, let's talk about why we moved to a dual license in the first place.

I think some companies believe that by "open sourcing" their products, they can enlist an army of unpaid developers to help them meet their business goals. I'm sorry, but it doesn't work that way. On every open source project that I've ever contributed to, the core committers wound up doing 95% of the work, Infinitest included. Patches from the user community, while helpful and appreciated, tended to focus on bugs and compatibility issues, and were never significant enough to actually move the project forward. What Infinitest needs right now, more than anything, is to move forward. I think Continuous Testing is going to become an essential practice in the next few years, similar to what Continuous Integration or automated developer testing are today. In order to get there, however, the practice needs a mature Java tool.

We believe, like many other companies that use a dual license model, the most direct path to that maturity is via commercialization. While we gladly contribute our free time to Infinitest, most of the Infinitest committers are professional consultants. That means we have the flexibility to turn every dollar of revenue that we earn into development time for the product. It also means Infinitest need not be a full time gig for us. If it can pay for 500 additional hours of development a year, that's great. 5000 hours? Even better. With this approach, there's no magic number we need to reach to be sustainable, because we're sustainable from day one. And with the depth of Improving Enterprises' bench at our disposal, we can offer high quality support to our customers without worrying about where it's going to come from.

The conundrum, however, is that Infinitest also needs to be a freely available tool. If developers are not free to use the tool on their own projects, without restriction, it's unlikely that they'll be able to learn the practice of continuous testing well enough to apply it when working for a client or employer. The reality of the software industry is that very few companies will pay you to learn things that aren't (in their view) directly related to your day-to-day work. If you want to learn a new tool or technique, you often have to do it on your own time. We don't think you should have to pay to improve yourself.

So why not use the GPL, as is typical with dual licensed products? We considered a more traditional dual licensing model using the GPL, and if Infinitest were a library, that would be the clear choice. The problem is, you don't need to create a derivative work from Infinitest in order to use it. So the GPL doesn't create the kind of incentives necessary to make a dual license model feasible for a tool like Infinitest. The usage requirement we need in order to create those incentives also means that any open source license we adapted to our needs would surely not be accepted by the OSI, the FSF or any other group. Plus, open source license proliferation is generally not a good thing, so why make it worse?

After much research and debate, we wound up in the middle ground. The licenses we created balance all these concerns with a single restriction: You must be working for yourself. That is, free licenses are granted only to individuals, not corporations or other entities. Those individuals cannot use Infinitest to do work on behalf of another party (what's known in copyright law as a work made for hire). However, if you want to license, sell, or even assign the copyright of your work after creating it with Infinitest, that's fine. We want to encourage individual entrepreneurs and innovators to use Infinitest in any way that benefits them, because they contribute the most back to the user community. I think that's simple, fair, and offers a good balance between all the competing interests.

And if that's all too much to absorb, the layman's version goes like this: If you want to use Infinitest at your day job, your employer has to pay for it. Otherwise, it's free for you to use however you like.

For more information about Infinitest, please visit or

Working Effectively with Transitional Code (Part 1)

Thanks to M. Feathers for the title inspiration.

Many companies today are struggling. As the economy contracts, they have started to look for new ways to become more efficient. Some have recognized the benefits of Agile methodologies, and have started to make the transition. These transitions can be lengthy, and if done improperly, painful and costly. A problem that I've started to see more and more among companies adopting an agile mindset is the stalled transition.

A stalled transition occurs when an organization:
  • Partially adopts agile practices and/or principles. Some teams and individuals fail to make the transition and revert to old habits.
  • Adopts practices that have been modified for expediency by mandate, rather than for effectiveness through team retrospectives.
  • Fails to adopt sets of practices that are interdependent (Continuous integration without automated testing, for example).
  • Mandates agile practices blindly, without understanding their benefits and effects.
For example, an organization may adopt some of the project management practices of various agile methods (Stand up meetings, planning poker, user stories) without adopting the technical practices that make those management practices effective (Test Driven Development, Continuous Integration, Refactoring). 

The result is, quite often, a mess. Projects managed in this fashion typically exhibit a number of common characteristics. Test coverage is spotty. Many tests make trivial assertions like checking for nullity of a returned object. Some tests make no assertions at all, which makes any code coverage metrics highly suspect. Builds often take 30 minutes or longer to complete, not due to any inherent complexity, but simply due to poorly written tests that run slowly. Refactoring is not done mercilessly, if at all, and so the the level of code quality is low and dropping. Quality standards are only intermittently applied. Pairing is rare or non-existent, and implicit code ownership silos start to appear "Give that task to Larry, he knows the UI better than anyone". 

As a result, the team may find it impossible to make frequent deliveries of working code. Customer demos are full of hand-waving and special cases, and the product is most certainly not ready to ship. When it does ship, defect counts and high, and stakeholders are often disappointed with the result.

I call this mess transitional code, and it is a serious and increasingly common problem. Adopting iterative and incremental project management practices without rigorously applying iterative and incremental technical practices is recipe for disaster. 

This is the first in what I hope will be a series of posts on this issue. I believe its resolution is critically important to the Agile movement.