Mark Needham

Thoughts on Software Development

Archive for December, 2008

Agile: Some misconceptions

without comments

I came across an interesting article written for Visual Studio Magazine about agile methodologies where the author makes what I consider to be some misconceptions.

The first is around the level of experience of people working on an agile team:

For example, agile teams have a tendency to require a high level of experience and professionalism just to join the team.

I wouldn't say I have a high level of experience and I've been working on agile teams for the past two years, just one data point suggesting that this statement is not actually accurate.

I think it is important to have experienced team members, at the Journeyman or Master level to use the lingo of Software Craftsmanship, but I don't think you'd want your team to be completely filled with these types of people.

This is one of the things that is pointed out in Pragmatic Learning and Thinking referring to the Dreyfus Model definition of expert in this case. We need to have people of differing levels of experience if we are to create a successful team.

Ideally you want a mix of skills on a team: having an all-expert team is fraught with its own difficulties; you need some people to worry about the trees while everyone is pondering the forest.

This is referring to the fact that as people become more competent they tend to start focussing more on the big picture than they did when they just started learning. As the authors point out, it's useful to have some people on the team who just want to focus on the details and get things done.

Of course I'm sure there are examples of 'dream teams' of software developers who have worked successfully together, but maybe this is more the exception than the rule.

The second point the author raises whether agile is just about making developers comfortable by allowing them to write more code:

Finally, I wonder how much of agile development exists simply to make developers more comfortable. Most developers love to write code, and agile does a pretty good job of rationalizing why developers don't need to do anything else. Design? Code it with test-driven development. Requirements gathering? I've heard proponents of agile development say that the user doesn't know what they want until they see something, so you might as well get straight to coding.

It is fair to say that when working in an agile way we get to the code more quickly than when following some other approaches but surely that's a good thing?

Although certainly some part of design is best done at the whiteboard, we can't actually know whether our designs are going to work unless we put them in the code so I don't see design by TDD being a problem.

There is a need to do some requirements gathering before we start working on features/stories but quite often we don't find out about constraints and trade offs until we begin implementing a feature, at which time the customer can decide what approach they want us to take. The goal here is to try and provide them quick feedback so that what we develop is actually what they want.

I would encourage the author to go and see an agile team at work (maybe using the Patterns and Practices team at Microsoft as an example) and see whether he believes this points still hold true.

Written by Mark Needham

December 31st, 2008 at 9:04 am

Posted in Agile

Tagged with

Oxite: Some Thoughts

with 4 comments

The recently released Oxite code base has taken a bit of a hammering in the blogosphere for a variety of reasons – the general feeling being that it doesn't really serve as a particularly good example of an ASP.NET MVC application.

I was intrigued to read the code though – you can always learn something by doing so and reading code is one of the ares that I want to improve in.

So in a style similar to that of a Technical Retrospective these are my thoughts.

Things I like

  • The Repository pattern from Domain Driven Design is used for providing access to the entities and provides encapsulation around the LINQ to SQL code.
  • There is some quite clever use of extension methods on FormCollection in the AdminController to create Posts and Tags from the data collected from the page. There are others as well – the developers really seem to grok extension methods in a way that I currently don't. It will be interesting to see if I start using them more as I code more with C# 3.0.

Things I'd change

  • Testing wise there are some tests covering the MetaWeblogService class although it feels like the setup in each of the tests is a bit heavy. I'd refactor the tests using compose method to try and remove some of the noise and rename the tests so that they follow the BDD style more closely.
  • When time is used in the code it is done by directly using the DateTime class. Testing time based code is made much easier when we can control the time in our tests, so have a Time Provider or System Clock class can be a very useful approach here.
  • A classicist approach has been taken towards testing with no mocks in sight! It feels like a lot of work went into creating the fake versions of the classes which could maybe have been done much more easily using a stub in Rhino Mocks for example.
  • A lot of the ViewData code is weakly typed by putting values into an array. We started with this approach on a project I worked on and it's so easy to misspell something somewhere that we came to the conclusion that if we can get strong typing we should strive for that. Jeremy Miller's Thunderdome Principle works well here.
  • AdminController seems to have a massive number of responsibilities which is perhaps not surprising given the name. I think it'd be better to have the administrative tasks handled from the individual controllers for those tasks. This would also help lead the design towards a more RESTful approach
  • The Domain model is very driven from the definition of the database tables from my understanding. The domain objects are effectively representations of database tables. If we want to create a richer domain model then it would make more sense to design the classes in terms of what makes sense in the domain rather than what makes sense at a database level. An ORM tool could then be used to map the database tables to the code.
  • A lot of the domain objects implement an interface as well which I don't think is really necessary. Although there are exceptions, in general when we refer to domain objects we care about the implementation rather than a contract describing what it does.
  • The Routes collection is passed around quite a few of the controllers, seemingly so that URLs can be generated inside other pages. It seems a bit overkill to pass this around to achieve such a simple goal and my thinking is that maybe a wrapper class which generated the URLs might be more intention revealing.
  • There is a bit more logic than I'm comfortable with in some of the views – I think it would be good to move this logic into ViewModel classes. This will have the added benefit of allowing that logic to be tested more easily.

Want to know more about

  • I'm curious as to why LINQ to SQL is being used as the interface to the database as I was under the impression that it is being phased out by Microsoft. The syntax seemed quite readable but I think the problem of interacting between code and the database in a clean way has been largely solved by NHibernate although the Entity Framework is a newish addition in this area.
  • One interesting thing I noticed was a lot of Background Services running in this codebase – I've not come across this in a web application before. They are actually being used for creating trackbacks, sending trackbacks and sending email messages.

My learning from reading the code

  • I asked for some advice on the best way to read code on Twitter and the most popular advice was to debug through the code. Unfortunately I couldn't seem to do this without having a database in place so another approach was necessary. Instead I started reading from the tests that were available and then clicked through to areas of interest from there. I think it worked reasonably well but it wasn't as focused as if I had debugged and I couldn't see the state of the program as it executed.
  • I wanted to find a way to read the Oxite code and navigate to areas of the ASP.NET MVC source using Reflector without having to do so manually. TestDriven.NET was recommended to me and it worked really well. Clicking the 'Go to Reflector' option from the menu takes you to the current class in the Reflector window. Impressive.
  • Changing the Resharper find usages menu to show 'Namespace + Type' makes it much easier to try and work out what the code is doing rather than the default setting of just 'Namespace'.
  • From looking at some of the ASP.NET MVC code I realised that a lot of data is stored in static variables in order to make the data globally accessible. It's something I had never considered this before and it makes sense in a way but feels a little nasty
  • I found that I was getting side tracked quite a lot by irrelevant details in the code. I'm used to having a pair guide me through a new code base so looking at this one alone was a bit different for me. Separating noise/signal when reading code and identifying common patterns to allow me to do this is something I am working on.

Overall

I think it's really cool that the Oxite team put their code out there for people to look at and learn from. A number of highly experienced developers have made suggestions for improvement so clearly this is quite a useful way to get feedback and code better in the future.

From what I understand, Rob Conery is working on some refactorings for this code base so it will be interesting to see what it looks like when this is done.

Written by Mark Needham

December 31st, 2008 at 1:26 am

Posted in .NET, Reading Code

Tagged with , , ,

Talent is Overrated: Book Review

with 8 comments

The Book

Talent is Overrated by Geoff Colvin

The Review

I came across this book on Jason Yip's Twitter feed while the idea of 10,000 hours to become an expert at any given skill was being discussed. I'm reading Outliers as well and the two books seem to complement each other quite well.

I'm interested in how we can apply deliberate practice in software development, perhaps using the medium of coding dojos, to become better developers in a more effective manner than just normal practice.

What did I learn?

  • The first section of the book is spent dismissing the notion that innate talent is what makes people who are world class in their field so good at what they do. Research is cited showing that it is only through 10,000 hours of practice that world class performance can be achieved.

    Although I agree that the best performers do have to put in a lot of practice to become good at what they do, I'm still of the opinion that people have some skills they are naturally better at than others and if these are the ones they chose to practice they are always going to be better than someone who didn't start off with that ability. I think this idea is discussed more in Outliers than in this book though.

  • Deliberate practice is described as something which is:
    • Designed to improve performance
    • Can be repeated a lot
    • Feedback continuously available
    • Highly demanding mentally
    • Not much fun

    Some examples are given of people who have engaged in deliberate practice and approach seems to entail finding something very specific that you want to improve on in a practice session and then working on that repeatedly while maintaining the self awareness to analyse how it is going and adapt accordingly.

    Benjamin Franklin's approach to improving his writing involved comparing his efforts to those of the Spectator, the standard which Franklin strived to reach. Software development wise perhaps this could involve picking an area of improvement such as trying to write code using small methods (less than 5 lines per method for example) and then comparing that code to some open source code written by someone like Uncle Bob for example, analysing where improvement is still needed and then practicing in that area.

  • I am keen to work out whether we can design coding dojo sessions to be about deliberately practicing in a certain area. From the dojos we've run in Sydney we've found that the more specific we can make the problem to solve the more we gain from the session as the practice is much more focused. Areas of practice for future coding dojos could be: Refactoring a code base, using tiny types, coding in a functional way, and so on.

    The key with any approach that we take seems to be to ensure that the tasks we're working on are just slightly above our level of competence, an idea I have previously read about in Apprenticeship Patterns and Pragmatic Learning and Thinking.

  • With regards to improving skills, three models are suggested for non-work related practice:
    • Music Model – Break down activity into smaller pieces; analyse each for ares of improvement; repeatedly practice each area. This is a useful approach for practicing presentations and speeches where we know beforehand what we want to do.
    • Chess Model – Study real games; practice the situations from the games; compare what you did vs what happened in the real game. This approach has been applied in business for many years, disguised as the case method.
    • Sports Model – re-learn the basics of the field; simulate situations that may come up in real life.

    I think some parts of each of these models can be applied to software development. From the sports model we can take the idea of re-learning the underlying principles of computer science and how our code is actually working behind the abstractions languages create for us; from the chess model we can take the idea of considering different options when we have a choice to allow us to select the one which will best solve our problem; and from the music model we can take the idea of identifying specific areas of improvement in our work and relentlessly working on these.

  • Domain knowledge is identified as being one key area where experts have a very important advantage over everyone else. Having a mental model of the domain that we work in provides a framework for learning new information and allows us to learn new information in context rather than on its own, making it much more likely that we will remember this information. I think this is particularly applicable in software development and is something I've forgotten about lately. Knowing the industry that you're working in makes you much more effective when it comes to understanding what users need and what features will be the most valuable to them.
  • Closely linked to this idea is chunking of information to allow us to hold more data in our memory. The example given is around expert chess players being able to remember the positioning of pieces on a board much better than novices since they see the moves which have happened rather than memorising the absolute positioning of the pieces. This can be applied when reading code bases – I've noticed that people more experienced at doing this than myself are able to notice patterns more easily and can separate noise and signal much more easily.
  • I found it quite interesting that the author speaks about creating organisations which are all about building people. This is a very similar idea to that of creating learning organisations which I came across while reading Lean Software Development. A failure to create this type of environment in a consultancy, for example, would result in it effectively being a body shopping operation.

    The problem is that putting people into the roles that best allow them to improve mean that they won't be working in their strongest role and therefore the organisation is not getting the benefits of those skills. Ideas expressed around creating a balance include encouraging employees to take part in communities and giving them additional 'growth projects'.

    I guess the equivalent in the software world would be to contribute to open source projects and participate in user groups and mailing lists to gain skills and insights that we would not otherwise gain.

  • The importance of feedback is also emphasised in helping people to achieve great performance. I'm not convinced that the typical approach to reviewing performance is the optimal approach and my current thinking around this is that it might be useful to measure out progressing skills in different areas against the Dreyfus model and then work out ways to progress to the next level. Retrospectives on agile projects are a way that we share feedback at a project level but I think we need to create shorter and more effective feedback cycles for individuals to help them to get better.
  • The idea of letting employees choose their own projects is raised as one which can help lead to greater innovation inside organisations since people will be working on something they are passionate about and are therefore going to do a much better job at it. Google's 20% time is an example of this idea proving to be reasonably effective. I don't know how that would be achievable at a project level but certainly on agile projects an approach which lets developers choose which stories they want to work on tends to be the most effective approach from my experience.
  • The myth that innovation comes about by accident is addressed and instead an alternate theory, that "the aha moment comes out of hours of thought and study" is proposed. The majority of innovations are shown to have been derived from something that previously existed but was modified to be even better. I think this is true in software too. For example, Mockito is the predominant Java mocking framework at the moment, and although it allows mocking/stubbing in a different way than was previously possible, that idea would not have been possible without JMock and EasyMock having been invented first.

    It is also suggested that creating an environment where time is available for people to try things out is important if we want innovation to actually happen.

  • The idea of motivation is touched on – the suggestion being that intrinsic motivation is predominant in people who are prepared to put in the practice necessary to become world class at something. It is also suggested that for some people practicing skills puts them in a state of flow, meaning that practice is actually enjoyable and not hard work as had been suggested earlier.

In Summary

This area of study still fascinates me and this book certainly gives a great deal of insight into the way that world class performers have made themselves so.

Software development wise I'm looking forward to reading Corey Haines' thoughts on how ideas such as his pair programming journeyman tour can help us to improve as developers and seeing how our understanding of the value of coding dojos continues to develop.

Written by Mark Needham

December 29th, 2008 at 8:52 pm

Posted in Books

Tagged with

Internal/External Domain Models

with one comment

One of the underlying characteristic of most of the projects I have worked on is that we have defined our own domain model.

On my current project due to the fact that most of the logic in the system is being handled through other services we decided to use WCF messages as the domain model, meaning that our domain model is being defined externally by the team defining the message contracts.

Internal Domain Model

This is the approach I have seen on my previous projects and if our system does have some level of business logic/behaviour in then it is the approach we want to take if we are following a domain driven approach.

We can then make use of an anti corruption layer to ensure that incoming data from other systems is converted into a format that had meaning in our domain before we made use of it.

If we don't have sufficient behaviour then the anti corruption layer will start to become a burden for the benefit it provides and we might be better off not defining our own domain model.

External Domain Model

The reason you might decide to take the approach we have chosen is if the domain in our system is the same as that defined elsewhere, in which case the mapping code would not be adding much value.

The problem with this approach is that we don't have control over the messages and when changes are made to it our code breaks all over the place. I guess one way to try and overcome this problem would be to use consumer driven contracts.

An additional problem is that it is quite difficult to change the domain when we learn new information since this would require changing the message definitions which are being done by another team. The domain model we have therefore seems less expressive than ones on other projects I've worked on and I don't think we achieve the ubiquitous language as much although certainly the domain terms exist in the code.

Overall

Both of these approaches have their merits and each may be appropriate given the right situation.

From my experience the majority of the time we will want to build our own domain model of rich objects. I actually think coding is much more fun when you have your own domain model.

I've started to come to the conclusion, while writing this, that if your domain is defined as message contracts then maybe it's not Domain Driven Design at all, perhaps it's more about SOA with a Ubiquitous language.

It does feel to me like some of the aspects of DDD are present though, just not all of them.

Written by Mark Needham

December 28th, 2008 at 12:19 am

Posted in Domain Driven Design

Tagged with , ,

C# lambdas: How much context should you need?

with 5 comments

I had an interesting discussion with a colleague last week about the names that we give to variables inside lambda expressions which got me thinking about the context that we should need to hold when reading code like this.

The particular discussion was around an example like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Foo
{
    private String bar;
    private String baz;
 
    public Foo(String bar, String baz)
    {
        this.bar = bar;
        this.baz = baz;
    }
 
    public override string ToString()
    {
        return string.Format("{0} - {1}", bar, baz);
    }
 
}
1
2
3
4
var oneFoo = new Foo("bar", "baz");
var anotherFoo = new Foo("otherBar", "otherBaz");
 
new List<Foo> {oneFoo, anotherFoo}.Select(foo => foo.ToString().ToUpper()).ForEach(Console.WriteLine);

I suggested that we could just replace the 'foo' with 'x' since it was obvious that the context we were talking about was applying a function on every item in the collection.

My colleague correctly pointed out that by naming the variable 'x' anyone reading the code would need to read more code to understand that x was actually referring to every 'Foo' in the collection. In addition naming the variable 'x' is quite lazy and is maybe equally bad as naming normal variables x,y and z (unless they're loop indexes) since it is completely non descriptive.

The only real argument I can think of for having it as 'x' is that it makes the code a bit more concise and for this particular example I had to change the name of my first Foo to be 'oneFoo' so that I could use the variable name 'foo' inside the block since other variables in the same method are accessible from the closure.

I'm not sure what the good practice is in this area. I've done a little bit of work with Ruby closures/blocks and the convention there seemed to be that using single letter variables for blocks was fine.

In this case the extra context wouldn't be that great anyway but I think trying to keep the necessary context that someone needs to remember as small as possible seems to be a reasonable rule to follow.

Written by Mark Needham

December 27th, 2008 at 11:15 pm

Posted in .NET

Tagged with , ,

TDD: Does it make you slower?

with one comment

There have been several times where we have been writing code in a test driven way and it has been suggested that we would be able to go much quicker if we stopped writing the tests and just wrote the code.

I feel this is a very short term way of looking at the problem and it does eventually come back to haunt you.

One of the problems seems to be that in many organisations only the first release of a piece of software is considered, and in this case then yes maybe it would be quicker to develop code in a non TDD fashion.

The issue you have is that the majority of the overall cost of software does not come in that first release – if we assume a total life time for a piece of software to be 3 years and the first release takes 6 months (being generous here!) then if we go at full speed in those first 6 months and don't write a good suite of tests, we leave ourselves with 2 1/2 years of maintenance hell.

This is where the real cost in software lies. The end of development on a piece of software is very rarely after that first release – bugs need to be fixed, new requirements come in and changes have to be made. Without the tests in the former we are left fixing something and hoping it works – I have broken stuff in production by making changes in non test driven code unaware that it would break elsewhere.

Even if we look at the development cycle of a single release, at some stage we are going to have to test the code we've written to ensure it actually works.

The TDD approach to doing this encourages early testing whereas the traditional approach is to do a lot of the testing at the end. The problem with the latter approach is that any bugs are being discovered quite a long time after the code was written which means it will take much longer to try and identify where they came from. Alex has a nice post showing the risks we assume when deciding to cut back on testing effort.

In terms of whether or not actual development time takes longer with TDD, Microsoft recently released a paper which suggested that code written using a TDD approach takes longer to write originally but puts less bugs in production.

Since the goal of software development is to get code into production I think perhaps we need to consider the whole period of time from when a feature was worked on until it is in production as being development time.

Clearly there are times when time is the biggest driver for when something needs to be released but the majority of the time having software with less bugs is probably preferable and TDD is helpful for achieving this.

Written by Mark Needham

December 25th, 2008 at 9:41 am

Posted in Testing

Tagged with , ,

Testing First vs Testing Last

without comments

I recently posted about my experiences of testing last where it became clear to me how important writing the test before the code is.

If we view the tests purely as a way of determining whether or not our code works correctly for a given set of examples then it doesn't make much difference whether we test before or after we have written the code.

If on the other hand we want to get more value out of our tests such as having them the tests act as documentation, drive the design of our APIs and generally prove useful reading to ourself and others in future then a test first approach is the way to go.

Testing last means we've applied assumption driven development when we wrote the code and now we're trying to work out how to use the API rather than driving out the API with some examples.

In a way writing tests first is applying the YAGNI concept to this area of development. Since we are only writing code to satisfy the examples/tests that we have written it is likely to include much less 'just in case' code and therefore lead to a simpler solution. Incrementally improving the code with small steps works particularly well for keeping the code simple.

As Scott Bellware points out, the costs of testing after the code has been written is much higher than we would imagine and we probably won't cover as many scenarios as we would have done had we taken a test first approach.

I think we also spend less time thinking about exactly where the best place to test a bit of functionality is and therefore don't end up writing the most useful tests.

Obviously sometimes we want to just try out a piece of code to see whether or not an approach is going to work but when we have gained this knowledge it makes sense to go back and test drive the code again.

As has been said many times, TDD isn't about the testing, it's much more.

Written by Mark Needham

December 22nd, 2008 at 9:39 pm

Posted in Testing

Tagged with ,

Try it and see what happens

without comments

Another of the ideas I have picked up from my lean reading is that of trying things out without understanding exactly what is happening.

Or as The Toyota Way puts it…

There are many things one doesn't understand and therefore, we ask them why don't you just go ahead and take action; try to do something?

This is an approach which several colleagues I have worked with recently have been encouraging me to follow.

I am generally quite inquisitive and want to understand why something works as well as actually getting it to work, and while I wouldn't want to encourage not reading the manual, taking this approach is sometimes less effective because it slows down our feedback cycle and, particularly when pairing, can be a less effective way of getting to a solution. Failing early and failing fast is particularly important when pairing, and that is exactly what this approach encourages.

The 'try it and see' approach is particularly effective when working with some open source software when the best way to find out how it works is to use it rather than to rely on the documentation which may not be completely up to date anyway.

From my experiences so far I think it works best when we have some sort of direction over what we want to do and how we want to do it. If we don't have any direction then looking in the manual might be more effective.

Written by Mark Needham

December 21st, 2008 at 5:43 pm

Lean Software Development: Book Review

with 3 comments

The Book

Lean Software Development by Mary and Tom Poppendieck

The Review

I'm keen to learn how the ideas from The Toyota Way can be applied to software development and as far as I know this is the first book which addressed this, hence the reason for me reading it.

What did I learn?

  • I found the idea of financial based decisions particularly interesting – I've often had situations when developing software where there are trade offs to make and it would have been much easier to make them if we had a dollar value associated with each potential solution. I'm not sure how willing the business would be to expose this information to the development team though.
  • There is mention of setting up incentives at one level higher than you would normally expect – Nicor is cited as an example of a company which does this. For example, a plant manager would be incentivised based on the performance of all the plants rather than just his plant. The thinking here is to try and get everyone thinking about the bigger picture. I'm not convinced that financial incentives work particularly effectively for motivating people to achieve goals although several colleagues disagree with me in this regard. For me making sure that everyone believes in the project and its goals is more important.
  • The role of the master developer is recognised as being key for ensuring the success of development teams. I'm not sure if this role maps directly with that of a Technical Lead, to me it seems to cover more responsibilities on the business side than a Tech Lead would typically have. It doesn't seem to quite describe the Software Craftsmanship idea of a Master either. Toyota's idea of a Chief Engineer most closely describes a role which sounds like that of the master developer.
  • There is a lot of emphasis placed on concurrent engineering – taking a breadth first approach to development over a depth first one. This would involve spiking lots of different ideas before working out which one is the most appropriate. While I have done this on agile projects, the way it is described in the book suggests considering even more options for longer periods of time. The key is to ensure collaboration with the customer and to design change tolerant systems.
  • The way to ensure systems are tolerant to change is to keep things which change together – in the same layer or module for example. Creating code which has high cohesion and separation makes change easy when it eventually needs to happen.
  • I liked the idea of considering development as a cycle of experiments with a test at the end of each cycle. As is pointed out, we are going to test our code anyway so it makes sense to capture the test so that we can reuse it. When written well tests can be very useful as documentation but as Jimmy Bogard points out, there are some important steps that we need to follow to ensure that our tests achieve this goal.
  • I found the reasoning around why we try to maintain a sustainable pace quite interesting. It mostly focused around the need to maintain some slack in the system so that if emergencies come up then we are able to respond to these. This would clearly not be the case if we already had our team working flat out. This seems to me to also be a case of non optimising locally at the expense of the whole system.
  • The ideas around product integrity were new to me but quite intriguing – perceived integrity is about the value of a product in the mind of the customer, while conceptual integrity is about ensuring that different parts of the system work together in a consistent way. The Chief Engineer/Master Developer would probably spend a lot of time ensuring this actually happens.
  • Towards the end of the book the authors talk about systems thinking and how we need to ensure that we solve the right problem correctly otherwise we will just end up creating even more problems. Reading this reminded me a lot of The Logic of Failure which talks of the difficulties humans have envisaging the effects of the actions they take will have on the world. The 5 Whys was suggested as a way to get to the root cause of a problem rather than focusing on the symptoms.
  • I like the ideas around not locally optimising systems by trying to allocate defects to individual developers for example. In this case we should look to create information measurements rather than performance measurements. I am still intrigued as to whether there are any types of measurements that we can use to evaluate the performance of developers but at the moment I'm not convinced that there are.
  • My favourite quote came from the last chapter of the book which described instructions for using the material contained within the book. 'Think Big, Act Small, Fail Fast, Learn Rapidly' – a good motto to follow I think.

In Summary

Reading this book has helped provide some more relevant examples of how to apply lean thinking in my work. I think there is quite a lot of overlap between the ideas in the agile and lean worlds in that both are trying to achieve a software development process which results in an end product that the customer actually wants.

I am keen to see how the authors suggest introducing some of these ideas in Implementing Lean Software Development.

Written by Mark Needham

December 20th, 2008 at 5:29 pm

Posted in Books

Tagged with ,

TDD: Mock expectations in Setup

with 2 comments

One of the ideas that I mentioned in a recent post about what I consider to be a good unit test was the ideas that we shouldn't necessarily consider the DRY (Don't Repeat Yourself) principle to be our number one driver.

I consider putting mock expectations in the setup methods of our tests to be one of those occasions where we shouldn't obey this principle and I thought this would be fairly unanimously agreed upon but putting the question to the Twittersphere led to mixed opinions.

The case for expectations in setup

The argument for putting expectations in the setup method is that it helps remove duplication and helps us to fail more quickly.

This would certainly be the case if, for example, we instantiated our object under test in the setup method and there were some expectations on its dependencies on creation.

The case against expectations in setup

The reason I'm so against putting expectations in setup methods derives from the pain of trying to debug NMock error messages when we put expectations and stubs in the setup method on a project I worked on about a year ago.

The number of times we were caught out by a failure which seemed 'impossible' from looking at the failing test was ridiculous.

After that experience we made sure that it was always obvious which expectations belonged to which test by inlining them and taking the duplication hit.

I believe a lot of the value of tests comes from the way that they fail, and if we can write tests in a way that the failure message and subsequent fix are really obvious then we are going the right way.

My current approach

My current approach to try and get the best of both worlds is to follow the approach Phil describes in his post on Domain Driven Tests.

If we have repeated expectations across different tests then I now try to extract those into an appropriately named methods which can be called from each test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
[Test]
public void ShouldDoSomething() 
{
	ExpectServiceToReturnSomeValue();
 
	// rest
	// of
	// test
}
 
private void ExpectServiceToReturnSomeValue() 
{
	// code describing expectations
}

This creates a little bit of duplication in that we have to call this method individually in each test which uses it but I think it makes the test more readable and easier to debug.

I'm still not sure what I consider the best way to name these types of methods – Phil uses a combination of a comment and method name to create readable tests but I'm keen to try and have the intent completely described by a method name if possible.

Written by Mark Needham

December 19th, 2008 at 8:57 pm

Posted in Testing

Tagged with , ,