Mark Needham

Thoughts on Software Development

Archive for October, 2009

Book Club: Integration tests are a scam (J.B. Rainsberger)

with one comment

In our latest book club we discussed J.B. Rainsberger’s presentation from Agile 2009 titled ‘Integration tests are a scam‘.

These are some of my thoughts and our discussion of the video:

  • While talking about how to write interaction tests he suggests that we should only be looking to create interfaces for Domain Driven Design services. If we find ourselves wanting to create interfaces for entities or value objects then we probably have a service wanting to get out. We should try to extract that responsibility out into a service.

    I’m intrigued as to how repositories and factories would fit into this picture as I’m not sure whether they count as services, entities or value types. I’ve worked on code bases where we’ve created interfaces for them but I don’t know if that means they would be services or that we did something wrong.

    There also seem to be varying schools of thought on whether or not we should tests these types of things directly or whether we should just make use of them in our code and judge their correctness that way.

  • Rainsberger’s main gripe seems to be with tests which cover more than one interesting behaviour and he identifies the slow feedback and complexity of test setup as being undesired consequences of this approach.

    My feeling is that he was mainly referring to tests written directly from the UI although several colleagues suggested that tests where we call the code directly while using several real objects had the characteristics of the integration tests that Rainsberger dislikes. Ayende is having some success with what he coins ‘system oriented tests‘ which sound similar to the latter so there might be something in this approach.

  • Rainsberger’s solution for testing our systems thoroughly is to make use of contract and interaction tests – the former testing the real implementation of services and the latter the way that our objects work together with each other. Essentially making use of mocking as far as I understand.

    He also suggests the need for a tool which would be able to indicate that every interaction test we write has a corresponding contract test which sounds quite similar to the NSynthesis tool that a couple of my colleagues have worked on. This tool only tests that we do have a contract test for each mock rather than testing with the exact parameters used in our interaction tests as Rainsberger describes. If I understand this correctly then that would seem to result in a lot of tests!

    I think we still need some integration tests that go through the user interface particularly if we are writing javascript heavy front ends – from my experience only using unit tests doesn’t take us the whole way to having confidence that this type of code works.

    It is perhaps useful as a rule of thumb to test the happy path of pieces of functionality through integration tests and try and test the edge cases from tests that sit further down.

  • I like the idea that acceptance tests are supposed to be clarifying requirements and not testing correctness although it seems to be really easy to cross the line where they do end up verifying the correctness of our application.

Rainsberger has an interesting post on his blog where he goes through the feedback he received from the talk.

I’m not sure if I totally understand contract tests at the moment – there is a post on Rainsberger’s blog which explains it a bit more and my colleague Danilo Sato wrote a comment on a post I wrote about using generic abstract classes for testing suggesting that this approach is similar to the one Rainsberger is advocating.

Written by Mark Needham

October 6th, 2009 at 11:37 pm

Posted in Book Club

Tagged with ,

My Software Development journey: Year 3-4

with 3 comments

Just over a year ago I wrote a blog post about my software development journey up to that point and I thought it’d be interesting to write a new version for the 13 months or so since then to see what the main things I’ve learned are.

Functional programming

I started playing around with F# about 11 months ago after becoming intrigued about this approach to programming following some conversations with my colleague Phil Calcado.

I’ve only really scratched the surface of what there is to know about functional programming so far but some of the ideas that I’ve come across seem very intriguing and I think they can help us to write more expressive and easier to understand code.

One of my favourite aspects of the functional programming approach is that it heavily encourages immutability. It is still possible to mutate state in F# but the code ends up looking really ugly if you take that approach which encourages you not to!

Mutating of state is much more prevalent in C# code bases but it seems to make it much more difficult to reason about the state that the code is in and we seem to turn to the debugger way more frequently as a result.

In contrast I don’t think I’ve ever tried to debug any F# code I’ve written. Certainly part of the reason for that is that I haven’t written any large systems using the langauge but I think part of it is because it’s much easier to reason about code if a value is set once and then doesn’t change.

Rich Hickey, the inventor of Clojure, has a really interesting presentation from QCon London where he describes the need for values to be immutable and for state to be modeled through state transitions instead of by mutating data.

Along those lines Greg Young also speaks about the need for explicit state transitions and Martin Fowler’s event sourcing pattern describes the way we can achieve this when using an OO approach.

Learning about functional programming has also encouraged me to see reusable functions in C# code and I think the ability to use higher order functions effectively removes a lot of the typical design patterns that we might otherwise look to use.

Jeremy Miller covers these ideas and more in his recent article titled ‘Functional Programming for every day .NET development

More recently Liz and I have been playing around with Scala and from trying out some of these exercises I am seeing that when writing recursive functions my thought process has moved towards thinking about how to get the function to exit first and then working back from there to see how to get to that stage.

I’m not sure if that’s the distinction between declarative and imperative programming but it certainly seems to be a less imperative thought process than I would typically apply.

I’m currently working my way through Amanda Laucher’s ‘F# in Action‘ book and watching the videos and trying out the exercises from MIT’s ‘Structure and Interpretation of Computer Programs‘ course from the 1980s so there is still much to learn in this area.

Context

It’s become more obvious to me over the last year that there pretty much isn’t ‘one true solution’ to any problem and that there are different ways of doing things each of which has its own advantages and drawbacks.

I guess the trick is working out which is more suitable in a given situation which I imagine will become easier the more different situations I come across.

While I believe there are rules of thumb that can be useful when developing software it seems like there will always be some constraint which might guide us to a solution which isn’t necessarily the perfect one. I think this is inevitable unless we have infinite time and money.

For example we were recently looking at the performance of our code and realised that there are a lot of network calls being made in one particular area.

One solution to this would be to cache this data but the problem we have is that this data can be changed by the user and our caching mechanism at the moment has time based expiry and we don’t want to deal with any other type of cache data invalidation as we are due to release quite soon.

In this case a time constraint is changing the way that we view our options so we’ve had to choose another solution.

I was recently watching a Skills Matter pair programming presentation by my colleagues Christian Blunden and Sarah Taraporewalla and it became clearer to me that the approach I use when pairing now is much more dependent on the situation and doesn’t directly correlate with the useful patterns which they suggested.

For example when working with someone who’s new to a code base it makes sense to take a back seat role more of the time and allow them to get used to working out where things are whereas when you’ve both been working on the code for a while then a more even distribution of the keyboard time will probably happen more naturally.

If we can work out which context we’re in and what constraints we have then I think it makes it much easier to choose an approach that will work for us.

Reason for everything

This first became more obvious to me when listening to a talk by my colleague Dan North titled ‘Pimp my architecture‘ where he describes approaches that can be useful when confronted with an existing code that you want to make some improvements to.

Liz Keogh described this in such a way that made it really obvious to me in a comment on Michael Norton’s post on technical debt:

The other reason that messy code happens is because people are learning.

Unless you start with a team of developers born to produce beautiful, clean code, the chances are that someone on that team will be learning. In that respect, messy code _is_ a normal part of the development cycle, as is having it left around.

Until I read this I had pretty much decided that if someone wrote what I considered ‘stupid code’ then they just didn’t care about what they were doing.

However, since then I’ve actually come across some pretty terrible code that I wrote a few months ago which I realised I’d written because I didn’t know of a better way to solve the problem.

Quite often the reason for something seems to be because the person didn’t know another way to do it.

We’ve had a few new people join my project recently and it’s always interesting to see the types of things they point out as having been done quite poorly.

In just about every situation there’s a (sometimes crazy) reason for the code being like that and I think the important thing in these conversations is to try and work out whether that reason still holds valid today and if not then perhaps we can make some changes to the code.

Mercilessly changing code

As it’s pretty much impossible to come to a perfect solution the first time around I think it’s quite vital that we have the confidence to make changes to the code we’re working with.

Ideally this is done by coding with a test driven approach so that we have some unit tests providing a safety net to allow us to make changes to the code but if we don’t have this then we should still look to put some tests around the code by using some of the techniques from Working Effectively With Legacy Code.

I’ve been working on the same project for the majority of the last year and I think a lot of the problems we’ve created for ourselves have been from a fear of changing the code. I think this is the worst mindset to end up in because it means that you feel like you can’t improve the situation.

In some areas of our code base we’ve been converting C# objects into a JSON representation which we can then parse on the client side and while this works quite nicely for allowing us to write logic for this type of code on the client side, we have pretty much stopped changing anything to do with those C# objects as even changing the names would possibly lead to the javascript code breaking.

This is where my worry of how well the polyglot programming approach originally coined by Neal Ford and presented at QCon by Dean Wampler will actually work.

I think if we don’t want to sacrifice the ability to change code mercilessly then our IDE tools will need to get to the stage that if we make a change to code in one language then any references made to that code in another language should be changed too.

I’m told that this is what happens if you mix Scala and Java but I’m not sure if that’s the case with other combinations just yet although I’m sure it will be.

In general though I think we need to keep a focus on putting the safety nets in place and designing our systems in such a way that we can change code mercilessly.

If we can achieve that then it doesn’t matter if we make a mistake because we can easily fix it.

In summary

These are the areas that I feel I’ve learnt the mos over the last year and the common threads running through seem to be that I’ve learnt that there’s more than one approach to problems and we rarely get it right the first time.

More recently I’ve found myself drifting towards an interest in how things work under the hood and where some of the original ideas we use today come from.

As a result I’ve found myself reading ‘CLR via C#‘ and ‘Fundamentals of Object-Oriented Design in UML‘ as well as SICP as I mentioned previously.

It will be interesting to see where that will take me to and I’d be interested to see if my experiences at this stage are in anyway similar to what others experienced.

Written by Mark Needham

October 5th, 2009 at 6:52 pm

Coding: Rules of thumb

with 7 comments

I recently came across a post by Ayende where he talks about the need for tests to justify themselves and describes his approach to testing which doesn’t involved TDDing all the code he writes.

While this approach clearly works well for Ayende I really like the following comment by Alex Simkin:

Anyway, this post should be marked MA (Mature Audience Only), so younger programmers wont use excuse to not write unit tests because Ayende doesn’t do it.

This reminds me of a conversation I was having with a few colleagues a while ago where we were discussing whether we should look to test drive absolutely everything that we write or whether we should make that decision on a case by case basis.

Personally, I don’t yet have the experience to be able to tell when it’s appropriate not to drive code (excluding spiking) and pretty much every time that I’ve decided something was ‘too easy’ to test drive I’ve managed to make a mistake and not realised it until much later than would have been the case with a test driven approach.

I’m finding that this applies to more than just testing though and it seems that where an approach is known to reduce a lot of potential pain then it might be useful to favour that approach unless we find an intriguing reason not to.

Thinking along those lines I think it makes sense to follow some ‘rules of thumb’ and not break them unless we absolutely have to.

Some rules of thumb which I’ve come across are:

  • Don’t put anything into the session
  • Don’t put getters onto objects – make all code adhere to the tell don’t ask principle
  • Write production code test first
  • Write classes which adhere to the single responsibility principle
  • Favour composition over inheritance
  • Favour constructor injection over setter injection

Given a situation where I want to reuse some code and I know that I could choose between doing it with composition or inheritance I wouldn’t consider this a 50-50 choice but instead would look to use composition unless it became really difficult to do this and inheritance was clearly the answer in which case I would use that.

Obviously these ‘rules of thumb’ might be a bit restrictive for people at the higher levels of skill of the Dreyfus model and I imagine that even with people with less experience they could be quite dangerous if applied too literally.

I wonder whether being dogmatic about a few rules of thumb would be more or less dangerous than making decisions not to follow a useful practice because you mistakenly believe you have the ability to tell whether or not it applies in a given situation?

Corey Haines wrote a really good post where he talks about the misuse of the word ‘pragmatic’ which seems to address this area although he comes to a slightly different conclusion:

This is a common thing that I hear from software developers: they have a little bit of experience, think that they understand something to the point where they can make their own decisions on what it means to ‘be pragmatic.’ Often times, people use the term ‘pragmatic’ as a way to hide a lack of skill and experience. Or, sometimes, it is used in ignorance: someone doesn’t realize that they don’t understand something well enough. Usually, though, it is brought to play when someone is justifying cutting corners on something…this can come back later to bite you in the ass.

Think your 9 months of trying TDD makes you an expert, someone who can suddenly decide when it is ‘pragmatic’ to not design your system with TDD. Or, don’t even worry about designing your system with TDD, just talk about automated testing.

Are you being ‘pragmatic’ about automated testing, skipping it things you don’t know how to do or are hard?

Typically when people try to justify a shortcut this is exactly the way they will justify it. The irony is that quite often much suffering is gained from that decision so it wasn’t really that pragmatic after all.

I realise that there aren’t really any rules for software development that we can follow all the time and expect to gain success with but it does seem that some approaches have already been proven to be more effective than others so it might be useful to make use of them.

Written by Mark Needham

October 4th, 2009 at 4:59 pm

Posted in Coding

Tagged with

Learn one thing a day

with 7 comments

I came across an interesting post about a month or so written by Chad Fowler on Tim Ferriss’ blog where he suggested that a useful way of ensuring that we are always improving is to ask the question ‘Am I better than yesterday?‘ at the end of each day.

I really like this idea and I think it fits in quite nicely with the approach that I take which is to try and ensure that I learn one new thing each day.

I find that it encourages me to be more inquisitive than I might otherwise be and helps avoid the problem of just cruising through the day and just doing the same thing day in day out.

When we start working on a new project it’s quite easy to achieve this because we don’t know much about the domain, we might not be familiar with the stack, there’s existing code to get familiar with and so on.

It’s much more challenging after you’ve worked on the same thing for a while and it’s certainly tempting to conclude that there’s nothing else to learn and that you need to work on something new to learn new things.

To an extent that’s true because I find that a lot of what I learn comes from working with different people who have completely conflicting opinions on the best way to do things but there’s certainly ways to keep on learning even after we’ve got past the initial fire hose learning stage.

Continuously question what you’re doing

This is much easier when you’re pair programming but certainly possible even when working alone.

I think what you question probably depends on what interests you the most so for me that tends to be a lot around how we can test code more effectively and how to make code more expressive and explicit wherever possible.

In order to do that I’m often looking for patterns that help to describe approaches that worked well and if we get something wrong then I want to try and discover what we would need to do when encountered with a similar situation in the future to not make that mistake again.

Fairly closely linked with the idea of questioning what we’re doing is to try out other approaches and see if they work out better than what we’re currently doing.

For example my colleague Matt Dunn and I were recently discussing where the factory and builder patterns were more applicable for object creation in different contexts.

We already had the factory pattern implemented in one section of the code so we spent a little time playing around with the builder pattern to see if that would have worked out better.

I think this appraoch works quite well because you can quickly see the potential problems you might encounter with another approach which might not be entirely obvious if you only talk about it.

Trawl the code base

An approach which I find quite useful once you are becoming reasonably comfortable when working with a code base is to start trying to find bits of it that you haven’t done much work on or that you are curious to learn more about.

For me this exploration tends to guide me to the edges of the applicatins I work on and the interaction with other libraries that we are making use of.

A couple of examples of ares that I’ve explored on projects I’ve worked on have been the way that we make use of a dependency injection container which can often seem a bit ‘magical’ and the ‘glue code’ that we use to integrate with libraries like Hibernate.

If my intrigue is great enough then I’ll probably end up looking through the code for those libraries as well.

There’s nearly always something new to learn there as the design of frameworks tends to be a bit different than the design of applications from what I’ve seen.

And if that doesn’t teach you anything…

At some stage we probably reach a point where we’re really familiar with the code base and there doesn’t seem to be much else that we can learn from a project.

If this is the case then I’ve found that learning a new language, taking part in coding dojos or participating in a book club can not only be quite useful for helping to learn new ideas/techniques but also perhaps giving you a new perspective on your project code base.

It’s also interesting to talk to other people to see what they’re learning as it can give you ideas of some areas that you might want to improve in as well.

I think people working in software development generally have a desire to learn new things and most of the time it’s quite easy to find those opportunities so these are just a few ideas for things I try to do when it feels like I’m cruising too much for my liking.

Written by Mark Needham

October 3rd, 2009 at 1:58 pm

Posted in Learning

Tagged with

QTB: Agile Governance – Managing the Enterprise Issues

with one comment

I went to watch the latest ThoughtWorks Australia Quarterly Technology Briefing in Sydney on Wednesday where my colleague Lindy Stephens, Suncorp’s Josh Melville and Lonely Planet’s Nigel Dalton presented on ‘Agile Governance – Managing the Enterprise Issues‘.

I was actually unsure of how interesting it would be to me as the title seemed a bit dull but it was actually quite entertaining and not at all what I expected.

These are some of the things I picked up from the presentation:

  • Lindy started out talking a bit about the illusion of control that waterfall plans can lead us to, referencing the intial paper on waterfall written by Winston Joyce which actually criticises the idea of designing everything up front and suggests an iterative approach would work better.

    A recent article by Tom De Marco where he retracts the idea that you “can’t control what you don’t measure” was also referenced. The most interesting part of this article for me is where he points out that projects which provide minimal return are the ones that need the most control but perhaps we should be considering whether we should even undertake them in the first place.

    The idea of having software that is production ready at any time is also a very nice thing to aim for:

    So, how do you manage a project without controlling it? Well, you manage the people and control the time and money. You say to your team leads, for example, “I have a finish date in mind, and I’m not even going to share it with you. When I come in one day and tell you the project will end in one week, you have to be ready to package up and deliver what you’ve got as the final product.

  • Traditional measurements of progress derived from a more waterfall process actually only tell us if we’re proceeding not if we’re succeeding – it’s much more useful to keep our focus on whether we are delivering value to the end user instead of just focusing on whether we have hit our targets on delivery date and promised scope.

    The transparency and visibility that we typically have when following a more agile approach was mentioned by a couple of the speakers – progress is much more visible throughout and we don’t suddenly have a project going from status ‘green’ to status ‘red’ right at the end.

    I think we need to be a little bit careful that we explain things carefully when showing this types of data to people who are new to the agile approach as it can very easily give the impression that we are totally failing when actually it’s fairly normal for initial progress on a project to be slower than it will be once we get going.

    Nigel Dalton described a story where even the Lonely Planet chef knew how one of his teams was doing because the information was so transparent!

  • Nigel also spoke about the idea of outsourcing agile and suggested that the best way to ensure success with this is to work with people in a country on the same longitude so that the timezone difference isn’t too great. He also suggested that having people from both locations going to the other works well for ensuring better communication.

    I went to a QTB last year where this was covered in more detail by my colleague Dharmarajan Sitaraman.

  • The general idea behind what Nigel presented seemed to be that the individual teams effectively provided the governance of projects and that it wasn’t necessary to have massive reports detailing progress every week.

    Josh Melville stressed the importance of looking at the value of all documents and getting rid of them if they don’t provide anything useful. Nigel described how they had massively simplified one of their reports after listening to Josh’s advice!

    Lindy pointed out that sometimes we’ll be executing projects in an agile way in environments which more traditionally follow a waterfall methodology and that in this case it might be necessary for the project manager to spend some of their time converting the data into an appropriate report.

    In terms of the lean approach this seems to me to just be waste, but perhaps a necessary waste.

  • Josh also talked about the importance of moving away from a process centric view of the world to a relationship based one when it comes to managing projects whereby problems could be talked through instead of just writing off a project as doomed because a ‘checkpoint’ wasn’t reached.

    He also suggested that considering whether we delivered features and also whether they were actually used were more useful things to look at rather than looking at budget and time.

  • In the questions afterwards one suggestion to the speakers was that the metaphor of software development as being similar to industrial manufacturing is not really helpful and that perhaps movie making is a better one to use because there is a level of creativity involved and the aim is to deliver something of value each day.

    Nigel pointed out that while traditional manufacturing didn’t have much to teach us, lean manufacturing was a different story as it helps us cope with variation rather than just cost which is quite important in software development.

Written by Mark Needham

October 1st, 2009 at 11:10 pm

Posted in QTB

Tagged with , ,