A few years ago I was lucky enough to attend Tom & Mary Poppendieck’s Lean Software Engineering course when they visited Glasgow. One of my colleagues recently reminded me of the assertion Mary made on that course that Test Driven Development is a minimum bar for a professional software developer to reach. With that in mind, I came up with the message below that I hope will inspire & motivate or at least catch the attention of people just starting out in this line of work (and perhaps some of those who’ve been around a while too).

What is a professional software engineer?

Wikipedia defines a professional as:

I don’t like that definition, it’s far too narrow. It defines a professional in terms of group membership and ability to generate income. If I want to have someone on my team, hire someone, those are not the top attributes I am looking for. When I build a team, I want to want people who care about quality and focus on maintaining high standards consistently…not just when it’s easy to do so.

Perhaps we should stop using the word “professional” to describe quality-focused software engineers and go for something more like “software artisans” or “craftsmanship” to indicate the qualitative attributes we seek?

What is the difference between a professional and an amateur?

I think we confuse professionals and amateurs (gifted or otherwise). I can use a hammer and saw, I could probably build a fairly basic shelter given enough time…I wouldn’t want to live in it because it would be a death trap, but it would probably be ok in the very short term to keep safe from the elements. If I wanted to build a permanent home, I’d get professional builders & architects in to do the job properly.

So how can we separate amateurs from professionals?

I think it can be summed up by the aspirations of the individual:

  • An amateur aspires to achieve perfection
  • A professional aspires to deliver very high quality results, consistently

An example

I know several very keen amateur photographers. They have all the latest cameras and lenses, they know all about shutter speeds, focus, exposures, lighting, etc. Most of them have taken some absolutely spectacular pictures. However, those pictures generally represent a huge investment in time, and more discarded pictures than they’ll ever admit to. Professional photographers generally can get a very high quality picture in a fraction of the time and their pictures are generally of a far more consistent quality. This is because they have mechanisms and practices in place to govern the quality of their output. Sure, there might not be as much free expression in their work as in an amateur, but that is most likely the nature of the pictures they are being asked to capture, rather than taking pictures of whatever you like, whenever you feel like it. I think that the same is true in software development.

Low Barrier of Entry

The barrier of entry to software development is very low. This means there is a broad spectrum of quality across the industry. I recall being about 7 years old and getting the computers in Tandy to display my name, infinitely scrolling across the screen. I can write a program, does that make me a professional software engineer?

When I was a student, I wrote some MS Access and VBA front-end to manage stock and re-ordering from suppliers. I earned money from that, which I lived off of. Does that make me a professional software engineer?

A long time ago I passed my Java Programmer Certification, my degree also qualified me for some kind of partial membership to the British Computing Society (can you tell that I’m not overexcited by that?). I’m a member of two professional groups, does that make me a professional software engineer?

We need a culture of quality, we need to be software artisans.

Becoming a software artisan is not about ticking a few boxes, reading a book, getting your code to compile, then declaring it to the world how wonderful you are. It’s a journey that starts with a sometimes difficult realisation:

  • You are not the world’s most clever software developer
  • You are probably not even in the top few percentile

That’s OK, you are in the majority. That doesn’t mean you can’t be a good software developer, it just means that you need to work at it and adjust your attitude for learning. Understand that you are not perfect, and introduce good practices and checks to ensure that you are producing a quality product…rather than just banging away on the keyboard until it “seems to work”.

Test Driven Development is exactly the sort of process that can raise the quality of your code dramatically, at the same time as reducing the chance that it won’t work. People make mistakes, quite often silly mistakes, sometimes more complex and subtle ones. If you’ve crafted your test before you start coding, then you’ve got a clear, black & white (green & red?) indication of whether you have made a mistake or not. It provides you with confidence to try out different design patterns and refactoring. TDD is a software developers safety net.

Following the SOLID ideas around writing good OO code, that’s something else that can raise the quality of your work. It will make it more robust, easier to use, more readable/less confusing, more amenable to refactoring, and various other positive things. However, you have to remember to follow those ideas with all the code you write. TDD guides you in the direction of the SOLID ideas because the further away from them the code is, the harder it is to test. A difficult test is an indication, a code smell, that the code under test might be able to be refactored/redesigned to be more easily testable…and that very often involves making it more SOLID.

TDD, it’s not just a good practice, but it enforces other good practices too!

Learning TDD

I’ll not sugar coat this, TDD is hard to learn without lots of practice. However, the same can be said of any worthwhile skill. I like to think of it like riding a bike. We can all agree that travel by bike is faster than walking…but not the first time you ride a bike. No, you get grazed knees and bruised elbows as you fall off, but gradually you stay on for longer and longer and it eventually becomes second nature and you start to achieve your potential.

There is a great ring of truth to the rule on 10,000 hours of practice leading to mastery of a subject rather than some innate talent. There are some practices you can do to cut down on that time that I’ll steal from a rather good infographic.

  1. Get a coach
  2. Surround yourself with like-minded individuals
  3. Build expert habits
  4. Don’t waste time on the small stuff
  5. Deliberately practice (not just mindless repetition)
  6. Teach others
  7. Find someone to kick your butt if you fall off track

I reckon I’ve clocked up at least my 10,000 hours of TDD, and I’m STILL learning new and better ways to do it.

I really enjoyed Martin Fowler’s recent article on Test Coverage, and in particular I liked the graphic he included in it:
Image has gone :-(

This simple diagram sets out very clearly what test coverage is good at measuring and what it is not. I think that is a very important distinction to make because coverage is no indication of quality, just of what is and isn’t tested.

This appears to be at odds with a current wave of thinking (well, one that I’ve observed anyway) where a message comes down from senior managers that all projects must have at least xx% of test coverage. The repercussions of not achieving this target vary from audit actions to remedy the coverage all the way through to not allowing projects to be released until they hit the magic number…and the number varies wildly as well…but the thinking behind this is common, and flawed: High Test Coverage == High Quality Code.

Correlation != Causation

Correlation does not imply causation, but once that link has been pointed out it can be difficult to ignore without a solid understanding of what you are observing and why there is a correlation.

The correlation is there, plenty of projects with high test coverage are of excellent quality. These projects tend to be ones driven by the sensible implementation of good tests as and when required, quite likely following some kind of deliberate practice like Test Driven Development…but not necessarily. The thing to note here is not the quantity or coverage of the tests, it’s the use of good tests, when and where required.

The other side of this is where a target is set and the team has not been writing tests all along. They quite often panic when presented with a target and immediately look for shortcuts. The reason for this could be that testing is an often overlooked skill and, from my experience, a large number of developers mistakenly think that it’s beneath them. Not always the case, but this is a blog post so I feel justified in my over-generalisation.

I’m not saying that it’s easy to retro-fit good tests to a relatively untested code base. Far from it as without considering the testing up-front, it’s likely that the code is not organised/designed in such a way as to make testing easy. I’ve seen many teams jump on a product that promises to write all the tests they need, automatically, with minimal input. The problem with these tests is that they are rarely the high value tests that are needed, and they are applied mechanically across the project with no sense of context. More importantly, they remove the knowledge and understanding that a developer would gain by thinking through what tests are relevant and how the code should behave.

So, what should we do?

First of all, we should stop selling code coverage as a measure of quality. It’s not. However, it can be useful in spotting projects where the test coverage is particularly low or to spot trends in evolving code bases.

When coupled with other tools to identify complexity and rate of change (of the source code over time) then you can identify good areas to examine and see if you could write more tests. I imagine that there are even more interesting and useful insights to be had by combining other measures, feel free to comment on this if you have any good ones.

Aiming for 100% code coverage is a noble goal, but it should only be an aspiration and definitely not a target…and you still shouldn’t confuse it with a stamp of quality assurance.

Personally, I struggle to do anything other than TDD these days but I understand it’s not the path of least resistance and can be difficult to learn. Having said that, if you are not writing tests for your software then you are either incredibly over-confident, incredibly naive, or both.

End with an analogy

A Road network

Like any analogy, I expect this one will have many flaws but I’m going to use it anyway.

  • Would you consider that the road network would be improved just by adding more roads until we reached saturation?
  • Regardless of the quality of the roads?
  • Even when they were built where nobody lived, traveled, or wanted to go?

Ruby Refresher

November 10, 2009

Ruby is a language that I’ve enjoyed working with in the past, but feel I’ve never really built anything substantial with it. I’ve got a Ruby on Rails book that I keep starting but never really get anywhere with. I suspect it’s because I don’t have a concrete task to tackle. The majority of my Ruby code was implementing unit tests for stored procedures using Marjoree, but that was over a year ago and I’ve hardly touched it since. Without regular exposure to Ruby, I’ve all but forgotten how to use it.

I was talking to Paul Wilson about this the other day and he suggested that I go to the Vital Ruby/Vital Rails training he’s running this week in Edinburgh. Sadly I can’t talk my work into either paying for it, or giving me the time off at the moment, so Paul suggested I take a look at Ruby Koans. So I downloaded the beta release of RubyMine (2.0 beta 3)  from JetBrains (have I mentioned that I’m a huge fan of IntelliJ?) and got to work. Ruby Koans “walk you along the path to enlightenment in order to learn Ruby” via TDD. It’s a rather large set of failing unit tests that you have to make pass. Each test demonstrates a feature of Ruby which you have to understand before making it pass. It’s the most fun way I’ve ever seen for learning (or re-learning in my case) a language.