about me about me
photography photography
software projects software projects
contact me contact me

Maybe that end part, doesn’t get object oriented design is a bit sensationalist. Don’t get me wrong, I have a lot of respect for Joel. He speaks a lot of sense, his blog and books are testament to that … I own a few of them.

I might be a couple of years late on this … it wasn’t until I was researching an answer to a question on the Stack Exchange Programmers site about test driven design that I stumbled across this blog post by Robert Martin.

So I listened to episode 38 of the StackOverflow podcast, and figured Joel might have said the things he did to stir things up a bit, and light a fire of conversation for the podcast. More Googling lead me to other evidence that he thinks unit testing is a time waster.

On listening to the follow up podcast, episode 39, it hit me that as Joel probably doesn’t write much code these days, my guess is he’s never actually done any TDD. Jump to 33:15 in episode 39 and listen for yourself.

Joel describes one of his products, Copilot, a remote desktop assistance tool. It uses aggressive JPEG compression to work on low bandwidth connections.

He decides to implement a feature to reduce the compression and improve the image quality. He makes the example that this would basically change an argument to the JPEG library from 10 to 37.

I’ve transcribed from 36:45 (apologies for the length but Joel is wordy :) …

There is no way to actually construct this test in advance of actually running it. Or if you did it would be extremely hard, I mean, it would take a lot of work to write some kind of test, that’s gonna know what that other machine that you are connecting to, which would have to be some other simulated machine that generated certain simulated experiences, and you’d have to, I guess, get your own JPEG library, and hope that it’s the same as the JPEG library that we’re using, and let it do both kinds of compression.

It would take way more work to write the test than to write the code. This is, I think, a classic example of YAGNI.

… and yet that code is only 10 lines of code, it’s going to work!

Mr Spolsky can’t see the wood for the trees here.

I see this type contradictory statement a lot, where someone can’t consciously picture the separation of responsibilities in their head. However, they’ve also said the answer without realising it, unconsciously they know the solution!

In one breath Joel describes an end-to-end test but then confuses the situation by scoping this test to ’10 lines of code’. That’s a unit test, where your class for talking to the JPEG compression library should have explicit dependencies. You can then mock the JPEG library and just assert that the lowerCompression() method simply passes 37 instead of 10 as an argument.

Why assert such simple logic? Well in the bigger picture, you have you a test covering this piece of code, if something in this system breaks, or needs modifying, and your test still passes, you know it’s not this piece of code at fault. Magnify this to a suite of tests, and depending on your level of code coverage, your test suite can tell you where the fault lies.

Adding such a test will most likely mean you refactored your code so you could test it! Possibly reducing the responsibilities of the class under test? You needed to mock the JPEG library, so you now pass it into your JPEG library class (an abstraction layer) as a dependency. That reduces coupling.

You also have a meaningful name for those 5 to 20 lines of code, lowerCompression() to encapsulate this behaviour. It’s all good. The terminology might sound fancy but when distilled it’s simple common sense. Why aren’t more people doing this?!

Testing Burden

Joel’s repeat example about the ‘testing burden’ is asserting a UI menu in an application has moved, and this breaks 10% of your tests.

Ten percent of tests breaking tells me either you don’t have much of a test suite, you’ve tested the nuts off this UI menu or a portion of your system is too tightly coupled to the UI. If the system is tightly coupled, and much of the business logic is in the UI, the tests have to be driven through the UI.

If you’ve used TDD, this scenario is highly unlikely to happen. Here’s the secret: test driven design promotes layers of separation. Every developer should have heard this phrase. This is programming 101, decoupling your business logic from your presentation layer.

MVC is more popular today than it’s ever been. Most developers will tell you the primary benefit is that provides a structure that promotes separating your Model from your View, it even spells it out: Model, View, Controller!

If you don’t adhere to this rule, you’ll have a tough time testing your code (test friction). Or if you do orchestrate a unit test to do it, I guarantee that you’ll be testing (what should be) multiple layers of your architecture.

You Ain’t Gonna Need It

Describing this as ‘a classic example of YAGNI is abusing the principle. Joel is using it in the context of ‘you don’t need testing’ because he sees it as unnecessary. Wikipedia describes it as …

programmers should not add functionality until it is necessary

If anything, this refers to only implementing what is needed to get your test to pass, and no more (i.e. focusing on requirements and code intent). TTD is no silver bullet but it certainly helps amplify a lot of code smells and improve your program design, you just need to try it before you discard it as ‘something only architecture astronauts do’.


comments

Greg K // 20.Aug.2011 // 19:12

I’m just listening to episode 41 where Uncle Bob is the guest. Joel just apologised for comments made in episode 38. Maybe I should have listened to this episode before writing this post :)

Greg K // 20.Aug.2011 // 20:14

I have to say episode 41 was the best episode I’ve listened to so far, other than Joel and Jeff talked over their guest too much :)

I wonder if FogBugz didn’t have an API, whether the code would have been separated from the view. The way Joel described it, there was a fair amount of coupling, with business logic embedded in the view.

Greg K // 22.Aug.2011 // 21:40

So it turns out I really am the last person to blog about this