views:

852

answers:

11

(This is a not a question to survey the merits of TDD. There are other places for such discussions. Thanks in advance.)

I've been experiencing too many developers who are novice at the technique, who are also reporting dissatisfaction with, test driven development and NUnit.

I hear negative comments like:

  • "I don't like NUnit. I tried it a year ago, but I forgot how to use it. Let's just use this Windows Form app I just wrote ad-hoc as a test harness instead. Test code is throwaway code anyway, what's the difference? Anyway, my way worked well enough in the past."

  • "I have reservations about TDD. On our last project (which was my first and only project experience with TDD, by the way), we don't even know what the design is any more."

  • "More code-comments are BAD? Are you crazy? I really have some work to do if you don't mind." (From the old school of more comments are better comments, and you can never have too many comments.)

When a novice complains that TDD supposedly 'did not work' to their satisfaction on their first-ever project using TDD, is it really TDD that has failed them, or is it the developer himself whose skills are not yet sufficient to get good results?

And how can I communicate that without them hating me for saying it?

The crux of the question is, what can be communicated diplomatically to developers to encourage them to take a more honest appraisal of their own nascent and insufficient capabilities with new development technologies, without endangering our important work relationships?

Typically, many developers are clearly not yet equipped with a working mastery of the many important elements of TDD to pull it off very well, when on their very first project.

For example, it is typical that complainers in the development community that I have talked to:

  • Have never even attempted to look at or remember the list of code smells.

  • Have never even attempted to study the catalog of refactorings, nor have they practiced any of them ever either in real projects or in toy projects for learning. For some people there there may be a lot more OOP to learn, in order to simply be able to do refactoring very well. There is far, far more to refactoring than just "rename method" and "rename variable" which appear as items on the Visual Studio 2005 Refactoring menu.

  • Have never even attempted to study or participate in real projects implemented using emergent design (via refactoring), versus doing a whole project using design in advance, versus a whole project writing the unit tests only after the code is written, and knowing the differences and tradeoffs and applicability between any of the them.

They all seem to have used NUnit, once, so whatever they did with it, it was TDD,by golly, they seem to think. The presence of NUnit or unit tests, simply does not imply TDD, but they don't understand enough yet to even know that.

These are smart people. Developers are smart people because that's the bar to entry to the entire occupation. You can't be in the occupation for too long otherwise. Of course they could understand it, if they applied themselves for a while to study these materials.

How can people honestly tell themselves a methodology is weak, when their sum of experience and knowledge is what's obviously far too weak to even be able to make an appraisal of a methodology or its results?

Yet they do... It's self-protective behavior, I believe. Or it's laziness. If you can't even name three refactorings from the catalog of Fowler's Refactoring book, or if you can't name several code smells, you are a rank novice at refactoring, and probably also the entire TDD methodology, and your so-called 1 or 2 project experience is evidently not enough.

What can I say to people or what materials can I direct people's attention to, to get them to do what it takes to learn much more about the skills that success with TDD depends crucially on, like:

  • unit testing,
  • refactoring,
  • design patterns,
  • OO design and analysis?

There are whole books on each of these topics, some very good. Maybe there are some easier-to-swallow learning techniques too? I can teach people by example, but my own time to give to them is limited, and furthermore, I am not yet a black-belt in all these techniques either.

Furthermore, they go together. They don't work very well without each other. Unit testing and refactoring go together like peanut butter and jelly. If you can't grep unit testing, then you surely won't have very good results at all with your refactoring!! (Ask me why if you don't know yet, I am happy to explain it to new people.)

It is also vital that whatever I do or say, that it does not backfire:

I must not alienate my colleagues from the TDD concepts; and moreover, I must not alienate my colleagues from me. I shall have to work with them every week for many more years to come.

It's particularly hard to not upset other long-time senior developers, who have already established themselves as being highly proficient in other facets of programming. They are rightfully proud of their past accomplishments, but their egos or their self-concept of mastery of all things in programming, can be almost insurmountable to deal with, without hurting their feelings. Some senior developers are unready to face up that they don't know some newer techniques that they should learn from someone else. Senior developers can be more accustomed and comfortable to being the experts in the room when it comes to programming, and sometimes they demand to be regarded as such, even when it's wholly unrealistic when it comes to TDD and associated techniques and technologies.

I am happy to report that one way I've had pretty decent success in turning around one of our resident "resisters" on writing structured automated unit tests, is by using pair programming with them, one on one. Pair programming gives trainees some real life examples and experience, I guess, along with the direct tutelage of a more experienced and knowledgeable practitioner.

But pair programming is not enough. There are many more refactorings, code smells, OOP concepts, and OOD&A concepts which they need to learn, and I can't teach all of them in a single project, not even close.

+1  A: 

rome wasn't built in a day + other cliches for patience

continue pairing and setting a good example, and others will see the light and follow your lead

you can lead a horse to water, but you cannot make him drink. And if you push him into the water, he'll either drown or run away. ;-)

Steven A. Lowe
-1: Thanks for the effort. ;)
Jim G.
+15  A: 

It is just about impossible to force your ideas on other people and have them be accepted. You can use your own methods and perhaps others will want to learn when they see good results. Are you just expecting these things like TDD, pair programming, etc. to magically reap benefits?

You also don't point out your role. (or at least I didn't find it)

You might try a different tack:

Offer a lunch time seminar about TDDor nunit. Show the benefits as you see them. Provide REAL examples and real benefits to developers/the company. Without those you will not have a receptive audience.

At least you have people who wrote their own test harnesses - that is a good thing. I would praise that and ask to see more of it.

Ask the developers what they see about the issue and what kind of testing they want or how the company can improve. You have to stop imposing your ideas and let it come from them.

EDIT - from experience

Years ago I had a similar experience. I had read many books about process and The Right Way To Develop Software (tm) and proceeded to tell everyone I saw about the right way to do things... No one wanted to hear it. I realized that I ran the risk of being marginalized was not really getting anything useful accomplished. So I just shut up and implemented some good practices in the group I was just given leadership of. After about 4 months people started asking us how we were getting the results we were delivering.

Instead of seeking out others people came to find us. (that wasn't my plan, but in retrospect it makes sense. People want results, not hot air)

Tim
+8  A: 

I think the biggest problem with TDD is that people become focused on these tests.

The tests are, to an extent, immaterial. Passing all of your tests only prove that you have passed all of your tests. Plus, you can pass all of your tests, have complete coverage, and still have a bad, unusable application that no one wants.

The gap between passing 100% of your tests and making excellent products is that bit of the profession known as craft.

Plus, TDD is just another way to specify a design. That's the important bit of TDD, getting the design locked down to some degree.

toast
I disagree, it's about having the confidence to change the design! When I rework my design and tests start breaking for unknown reasons I still know that they failed and go and fix them. TDD enables change, never locks something.
Tigraine
I disagree with what you said on tests : the tests TDD produces are there to test the code - not the application. Functional/acceptance tests are still useful.
philippe
+4  A: 

Just to play devil's advocate, why are you so sure TDD is really effective? Personal experience? Empirical Research?

Here are two studies that reported positive results from TDD:

And two inconclusive:

I'm not sure it's a good idea to present the methodology as if it's perfect. It's one approach that may be effective. As far as we know, there are still better approaches. Maybe invite all developers to design a mixed methodology that's a good fit for your organization.

Corbin March
+1  A: 

More likely it is the question of whether a reduced productivity while getting used to the style of TDD and creating the culture that is required in TDD is where I think things are going wrong.

Can those senior developers have a big drop in productivity and this be acceptable to everyone? If you could get the sense that everyone would be OK with relearning how to develop code then you may have something, but remember that most developers have their own personal optimizations for writing code that I'd think TDD would take down, e.g. taking a guess and then working out the bugs may be a common approach that doesn't quite cut it if you use a strict form of TDD.

JB King
+6  A: 

Maybe it isn't that TDD is a problem, but have you considered whether it is really appropriate for the environment you're working in, and the type of project you're working on? You haven't mentioned anything about what problems you currently have (or even what methodologies and practices you currently use) and why you thing adopting TDD would solve these problems. Are you sure the resistance you're seeing is not as a result of a resistance to change, but because you're trying to solve a problem that doesn't exist?

TDD isn't appropriate in all environments. It sure as heck isn't appropriate where I work because we work too fast, with specs that typically are written roughly to start and refined/changed/rewritten throughout each iteration, so we don't have any defined behaviours to test against most of the time. In addition, we have developed practices that means code simply doesn't need testing in many cases because the method is a one-liner that static type checking ensures must work.

There are many comments in your post that mark you out as somebody who may be relatively inexperienced, and who has latched onto a methodology which you believe is a silver bullet that can solve all problems, and which your colleagues must learn if they are to keep up with you. Unfortunately there is no silver bullet in software development, and if they are senior developers with a lot of experience, and they don't believe that TDD is appropriate then maybe, just maybe, it's worth listening to them.

You should also be aware that TDD is not a pre-requisite to refactoring, as much as people who love the "red green refactor" mantra wish to think it is. If you're refactoring a small area and you know what it affects, and it can be easily manually tested, then you can manually test that area during and after refactoring.

Greg Beech
+4  A: 
  • No one likes to be told they are less than expert in their profession. The more senior the person, the more resistant they will be to adopt a new methodology that makes them feel like a newbie.

  • The best success I've had with promoting testing was to create graphical reports of test coverage, and publish them to the team (or have an internal team web page hooked up to continuous integration test reports). Yes, test coverage isn't a total measure of quality, but it's a pretty easy way to show who's writing tests and who isn't.

  • Let there be collegial competition to see who can maintain their code coverage at the highest percentage. People like competition. As they fall behind, or if they write code with untestable "code pockets," maybe they'll think about ways to refactor it so that their tests do show code coverage. If they don't like being "schooled", then let them discover refactoring techniques themselves. That way they can continue to feel smart.

  • Or else have brown-bag lunches in which people can show off some clever refactoring they did to achieve greater testability. People like to show off! More than they like being shown their ignorance.

  • This is a long way from TDD, but at least it's some progress toward better QC. Once they're more comfortable with the tools and a few simple ways to refactor, then you can introduce some more advanced stuff gradually: pair programming... code reviews... detecting code smells... tracing requirements to tests. Then you can get around to TDD.

As Steven Lowe said on this thread, Rome wasn't built in a day.

Bill Karwin
+8  A: 

To distil your question into one line:

And how can I communicate that without them hating me for saying it?

By being such a good developer that you earn their respect, and then they'll listen. There really aren't any short cuts here. My advice would be to become a better developer and a better evangelist. If you learn from the people you're trying to teach, then they might start learning from you.

And with all due respect, your attitude towards TDD comes across as rather reverential. That won't help either. Combine this with the big culture change that TDD involves, and your chances of successful evangelism are starting to shrink dramatically.

RoadWarrior
+1: For *By being such a good developer that you earn their respect, and then they'll listen*.
Jim G.
+3  A: 

Your real question is "how to I persuade my colleagues to try something new?"

That is a really good question, and sorry it is really hard. I did a talk on the subject with Alistair Cockburn a couple of years ago and I've posted the slides, but haven't written up the text, but I can give a short version here.

Are you familiar with Technology Adoption Lifecyle or Crossing the Chasm? These deal with segments of the population and their motivations to change. The key idea that is relevant to your situation is that only people on the left side of the chasm -- the innovators and early adopters -- are interested in changing to try and make things better. The people on the right side of the chasm -- the majority of people -- are more resistant to change, and when they do change it isn't for the same reason as the people on the left side. As a result the two groups tend to talk past each other.

You are left side of the chasm. Your colleges are on the right side. If you keep giving them your reasons to change you will not persuade them.

What will persuade them to try something new is if it offers the credible promise of relieving some current pain that they feel.

Talk about how TDD is better and what you should be doing and you're talking past them.

Talk about how TDD can fix some current pain, you'll have their attention.

And the killer part? If there is no current pain, you're not likely to get them to change, period.

That's why the options are "change your organization or change your organization".

Good luck!

Jeffrey Fredrick
+1: For *That's why the options are "change your organization or change your organization"*.
Jim G.
+1  A: 

The first thing that caught my eye was: "Test code is throwaway code anyway". I mean, wow.

Of course, the opposite is true with TDD. Your tests become your regression firewall, and allow you to refactor and add features with confidence.

In my experience, there are two things you must have to introduce a practice like this into a resistant (but not utterly recalcitrant) company culture: You must have the practice mandated by a manager who gets it, and you must have an engineer on the team who has made it work before. This engineer's time will have to be split between actual project work and mentoring, with the mentoring taking the form of a group presentation, code reviews, and (brace for it) bouts of pair programming to show people directly how the practice may be applied to the problems they're trying to solve.

Beyond having made it work in the past, this engineer must also be a skilled teacher and (because you're asking people to change, which most will take as a personal attack) have a non-threatening personality and approach to teaching.

Good luck with it.

bradheintz
+1  A: 

It takes time, and it takes (for lack of a better word) marketing. TDD (or, Unit Testing in general) won't be accepted until it's advocated for by someone that the team members respect.

If you're not already one of the more-respected members of the team, you'll either have to become one (by demonstrating excellence), or focus on one or more of the technical leaders, and get them over to your side.

Everybody is different, of course, and you'll have to figure out how to present TDD to the various tribal leaders so they're as open to the idea as possible.

One thing that absolutely must happen is that it has to be made super-easy to create tests and run them. If you're starting from a position where people are skeptical of the advantages of TDD, then any minor bump in the road to trying it out will be very de-motivating.

Mark Bessey