Test Driven Development

There were six of us at the Lamb and Flag to discuss test driven development (TDD). I was joined by Miquel, Tom, David, Inigo and new boy Julian. The books chosen to kick off the discussion were two different books called “Test Driven Development”, the first by Kent Beck and the second by Dave Astels.

David revealed that he’d actually read a third book, Test Driven by Lasse Koskela. He said it was not a bad book but he wasn’t convinced by the part which talked about driving development through acceptance tests. The section on test driving the database was fine for simple applications, but in David’s experience it is not always simple to swap the database used in live with an in-memory database such as HSQL. Often the application will use stored procedures or other specific features of the target database. Inigo pointed out that if you have a requirement to support both Oracle and SQL Server, say, then using a third database would actually not be such a big step.

Inigo referred to a study by Microsoft which showed that TDD took 15-35% longer than traditional development but was 40-90% better in terms of bug counts.
He suggested that it is the fact that the tests are written at the same time as the code that is important, not the fact that tests come first. David suggested that you lose some advantages if you don’t follow the rules. Writing the tests first mean you always know where you are and that every feature should have a test. Tom said that be coded test-first when bug fixing, but found that doing true TDD was a bit tedious if followed to the letter. I mentioned Ping Pong programming, where a pair of developers play a game by adding a failing test and getting their partner to make it pass and add their own failing test. The idea is to try to write as little code as possible. There was some surprise that this was not mentioned in the books we had read.

We talked about the Kent Beck book. Inigo found it to be a little lightweight and quite philosophical while Miquel thought it was easy to read. Inigo thought it had extra sections that were not strictly needed in a book about TDD, for example the chapters on refactoring and patterns. However, he liked the design of the code that is explored in the book, which is a currency conversion application. Inigo had expected some interesting details of JUnit 4, but once he saw the copyright date he realised that this was not possible.

I found the Dave Astels book felt quite outdated. It is quite a few years old now, so many of the technologies such as JUnit and mocking have moved on quite significantly. It could also do with some typesetting love as it is not the most beautiful book to look at. I also felt that it was rather long – I couldn’t bring myself to read through the extended example which makes up most of the book. Julian (as a newcomer to the subject) did feel that it was good that it was so practical, unlike Kent Beck’s more theoretical approach. So perhaps it is the better of the two for someone new to this area.

We moved on to talking about different testing techniques. I mentioned Jumble, a mutation testing framework which I have described on my work blog. David talked about how he used Fuzzing in his previous job to find bugs in an XML parser. His experience was that it was best to have a smart fuzzer that understood XML as this was more likely to find bugs than just adding random noise to a file.

Inigo mentioned Hamcrest matchers and the use of assertThat in JUnit. It was generally agreed to be good for readability of code and error messages, but not so good with respect to IDE auto completion. David pointed out that JUnit 4 has this problem over JUnit 3 since the assertion methods need to be statically imported.

Finally Miquel asked about how to test JavaScript. Tom and David described Selenium/WebDriver as the best tool in this area.

Communicating through code

For this meeting, I was joined by Tom, Miquel and Inigo, with the discussion based around Kent Beck’s Implementation Patterns.

Miquel began by saying that much of it was common sense. Tom agreed, but said that it was one of those books people say should be given to novice programmers. But then those beginners would probably miss out on the subtleties, so the actually time when it would be useful would be rather limited. Inigo thought much of it was too obvious, except for the handful of things he disagreed with, such as the variable state pattern and his views on final variables. On the other hand, he thought that there could have been more discussion about immutable objects and functional-style programming. It was generally agreed that they weren’t really ‘patterns’ as such – Inigo thought they were mostly ‘idioms’.

On the plus side, Inigo like the idea of the book and wanted to like it more. I agreed and liked the back-to-basics approach of saying “hold on why do we even split logic into methods?”. I also liked the slightly different way of thinking about the reader of your code. Kent Beck asks what the user will read ‘between the lines’ because of the implementation approach you have taken. Inigo liked the way he admitted his ignorance about such topics as concurrency and referred the reader to other books.

It was generally agreed that the book’s Java focus might be a surprise to someone picking the book up cold. I found the performance measurement section to be out-of-place. Inigo thought it would have been much more useful to have explicitly given details of hardware, operating system, JVM version etc. Miquel pointed out that speed is one thing, but maybe the memory footprint could be important for large collections too, but that is not mentioned.

I wasn’t sure that the use of the word ‘Symmetry’ was correct (see p15). To me, something can have parts of differing sizes but still be symmetric. I think the word ‘Uniformity’ would be better and in fact that very word is used by the author on p101 in relation to JUnit. Tom said that this concept was one of the few things he had taken from the book and he’d hoped for more. It seemed to him that some of the patterns were just dictionary definitions of the term, such as the ‘patterns’ around exceptions.

I think I was the only person to read the part about frameworks. I thought this was quite interesting though, as it discussed the differences between this sort of code and application code. In a nutshell, sometimes you might make a framework uglier on the inside to keep it clean on the outside and to limit difficulties when you make changes in the future. Kent Beck seems well qualified to talk on this, having been involved in the move from JUnit 3 to 4.

Meeting 23 – The Pragmatic Programmer

This month’s meeting was to review the Pragmatic Programmer [Andrew Hunt & David Thomas]. This book was first published in ’99 and on more than one occasion it was mentioned that some ideas were possibly more revolutionary then than they are now. Many other areas seemed to touch on techniques that are picked up with experience but reassuring to see written down. This highlights how much good content is in this book and Graham mentioned that it would be a good book to give to new developers joining a team in order to (re)focus them on what is important.
There are a total of 70 tips which are printed on a card inside the back cover (useful for anyone thinking about buying it). I don’t remember any being highly controversial or ground breaking but so many of them produced interesting conversation and we covered a surprising number of them. There was a good discussion on a possible contradiction between never leaving ‘Broken Windows’ unrepaired and the idea of ‘Good enough’ coding; for example, which category would a slow loading web page be in? Graham suggested that always fixing broken code/design/decisions was more about internal quality.
David pointed out that the appendix contains many references to material that covers some of the tips in more detail and that it has been continually updated in the reprints.
All in all, a good book that prompted some good conversation.

Meeting 22 – Beautiful Code

We had a decent turn out to discuss Beautiful Code edited by Andy Oram. Besides me there was Graham, Tom, Steven, David, Victoria and John, of whom about half of us had read some of the book.

The book is a collection of articles and so I’d just dipped in and read whatever chapters I’d fancied, whereas some of the others had started from the start and read them in order, although no-one completed all 500+ pages.

Overall, I found it to be a bit of a mixed bag. There were some interesting chapters and some rather less so. I also thought that quite often the link to ‘beautiful code’ was a little tenuous. Often it seemed like the concept behind the code was elegant while the code itself was a little on the ugly side. Graham agreed and said that he had expected the articles to be more inspirational. David pointed to the chapter on Code Generation (Chapter 8.) as one where the code got pretty gnarly while the idea behind it was pretty.

We looked at the different chapters in a bit of a random order, so here are some of what was said about each:

David liked the chapter on Haskell and Software Transactional Memory (Chapter 24). The idea is that your code is split up into code that is guaranteed to be side-effect free and code that is not. The transactional memory is implemented in an optimistic locking style. Since you are using the side-effect free code, if you hit a conflict you simply retry. The beauty came from the way the language kept the two different types of code apart. I liked it too, but when it got to the “Santa Claus” problem I found that there was too much new stuff for a Haskell newbie such as myself.

I liked the chapter on “Beautiful Tests” (Chapter 7). The code was simple, but it showed that finding bugs in the code was actually very hard. Graham thought that it highlighted the difficulty in proving the absence of defects. It introduced the idea of test theories to help you think of circumstances that your tests don’t yet cover. An interesting metaphor was that tests are like sportsmen in that they work best in teams with each one looking after a different area.

A chapter that Graham liked was “The most beautiful code I never wrote” by Jon Bentley (Chapter 3). Unfortunately I tried to read this in bed and fell asleep. David said it reminded him of a lecture from his student days and that it had had a similar effect on him then. He liked the clever algorithms in Chapter 10 “The quest for an accelerated population count” and said that he was glad that someone had written these things down.

Michael Feather’s chapter on the design of FIT (Chapter 6) was one I liked because it showed some code that didn’t follow the traditional rules of API design but ended up with a small, clean set of classes that do what is required of them.

Last but not least, Chapter 11 “Secure Communication: The technology of Freedom” got a bit of a thumbs down. David branded it as being like someones blog on what they did on their holidays. This was the only chapter John had looked at (on the bus coming to the pub) and it had not left a good impression.

I’m sure I missed lots of good conversations, but the book is such a mixture of things that the conversation did tend to move around quite swiftly. If I missed your favourite chapter out, give it a mention in the comments…..

Meeting 21 – Programming Erlang

We had a meeting on Tueesday evening to discuss our first impressions on Erlang. We have all been using the book ‘Programming Erlang’ by Joe Armstrong. We were a little late getting started but Steven, Andy, Graham, David and myself eventually found eachother.

None of us had used Erlang previously but Graham has used Haskell a lot and noted some of the major differences between the them. I should have started taking notes earlier but the two that stood out for me were that Haskell has lazy evaluation and strong typing.

The biggest interest in Erlang was its scalability thanks to concurrent and distributed applications being easy to write. We did wonder how Erlang might balance load in a distributed environment and quickly came up with a wish list – can Erlang choose how to distribute load across nodes, and can it migrate a process to a different node? I’m sure with use these questions can be answered.

Everyone seemed to agree that the language feels quite old. My memory about it appearing in its current form around 1990 was correct but most people thought it must have been older. Its apparent age probably comes from how it appears to a newcomer when seeing things like make files and lack of UTF8 support at the heart of the language. Steven mentioned that he also thought some common programming tasks seemed to look awkward – I think his example concerned lots of calls to lists:reverse. Graham suggested that when more familiar with functional programming such scenarios may become less frequent as things can be done differently.

We also discussed the book. David asked if we thought it would make a good reference for beginners. I thought the examples were very good and some of the later programs appear to achieve a lot in just a couple of pages. On the downside, there was more than one occasion we were unable to find a topic we were discussing in the index.
For myself, there was a lot to take in. I enjoyed reading the book but started to forget some of the syntax as I read more complicated examples. The book does suggest actually trying the examples while working through the book so maybe I will start again. Graham and David thought that it is unlike a lot other books on functional programming due to its focus on practical programming and not so much the theory.

I believe that only Chris has so far tried something in Erlang but since he wasn’t present we all concluded this might be a good next step :-P

Choose your language

It’s time to choose the first programming language that we’ll be covering in our new strand. As we have done with books in the past, I suggest listing your three favourites in order in the comments. We will meet to discuss our progress for the first time in January.
UPDATED: Looks like Erlang is the winner, with SmallTalk just behind in second place.

Meeting 17- Refactoring To Patterns

A decent turn out at the Lamb and Flag to discuss “Refactoring to Patterns” by Joshua Kerievsky. I was joined by Tom, Mick, Steven, Andy, Ursula and John.

We started out by discussing what Steven thought of the book, because he’d previously said that he wasn’t impressed by it. He explained that he’d found the books “Refactoring” and “Design Patterns” to be life-changing. When he heard about this book, he expected it to be in the same mould and ordered it before it was even published. But when it arrived it didn’t live up to the expectation. However, having looked at it again, he has now come to the conclusion that it does what it says on the tin. So it is a useful book after all.

We all agreed that it isn’t a book for dipping into. You need to concentrate on it and read a whole pattern in a single sitting. I found that it was not good for reading just before going to sleep. You think “I’ll have a quick read before turning out the light”, pick it up and start reading “Replace Composite with Polymorphic..” and don’t get much further.

I think it is a book to work through with colleagues, finding places to apply the patterns and seeing how the design turns out. Tom agreed and said that he liked to read the book in a different order to that given. He thought the best way was to ‘follow the smell’ and see how each smell could be removed by application of the refactoring.

Mick showed us his copy of the book, complete with many markers. He’d found lots of places in his current codebase where these refactorings would help. He thought that the main ‘take home message’ was that sometimes adding functionality the naive way and refactoring was better than trying to think of the perfect solution upfront. He also said that he had found some of the “Benefits and Liabilities” sections to be irritating because initially all of the liabilities seemed to be “it could be too complicated”. Later on he thought that the liabilities became more interesting.

Ursula said she thought it was like a travel guide. I liked this analogy. The section at the front is like the background information on the country and each refactoring is a different place. If you’re visiting a particular place, then the section in question could be very useful, if you’re not, then it isn’t going to be so interesting to read.

John said he found it very much focussed on object-oriented programming, which was not quite what he was expecting. This was mainly because “Design Patterns”, although strongly focussed on object-orientation, is about higher level design ideas. So you can get something out of it, even if you’re not working in OO. But this book is all about the nuts and bolts of working in an OO language. Since he has only dabbled in OO, he didn’t follow the book through.

There was some discussion about how or if you could automate some of the refactoring in this book. Mick mentioned Google’s “Singleton Detector” and I mentioned that I’d attended a half-day tutorial with the author, Joshua Kerievsky in which he’d given us some material that he’d developed while writing this book. It was called (slightly confusingly) “Patterns of Refactoring” because it described techniques he’d come up with while writing these patterns. These techniques came out of the constant improvements to the refactoring steps described. Quite often the first draft would leave the code broken and untestable for a long period. But over time he found ways to make small steps that kept the compiler and the test suite happy. Typically, I forgot to bring these notes with me, but there is a short article I wrote about it on the company blog.

This led Ursula to ask about how testing and refactoring fit together. There were some differing views. If you are doing small scale refactoring, then the tests will likely not need changing and are a good indication that nothing has been broken. With large scale refactoring, the tests are liable to need changing as you go along. In that case, it is helpful to have some higher level functional tests as backup to show that all is still well.

We then moved onto a discussion of how deprecation fits into the picture, particularly when doing refactoring in very large systems and where published interfaces are involved. Ursula described a system whereby a feature was scheduled to be removed at a given release and how this simplified matters.

Finally, we talked about my idea of alternating the discussion month by month between an agile book and a programming language. When I explained that it was more likely to be an older language (like Smalltalk or Lisp) or a more esoteric one (like Haskell or OCaml) there was more interest in the idea. Steven said he didn’t want to end up discussing PHP or the like. So it seemed like there was actually more enthusiasm than I thought for the idea….

Programming for kids

I posted this to the mailing list, but I thought it might been of interest to our many(!) blog readers too.

At Wednesday’s meeting there was a discussion about how in the ‘olden days’ (the 80′s) when a child got a computer it booted up into a programming environment. These days if they want to do programming they have to go searching to set up some kind of IDE. We also talked about putting a programming environment on a phone as a way to get kids into programming. Well I’ve just seen an article mirroring this discussion exactly.

Adrian suggested that Javascript might be the language to use, since it is on virtually every machine out there.