views:

236

answers:

9

First a little background. The company I work for writes web based software that is a hosted solution for our customers (ie ASP (Application Service Provider)). We are adopting agile practices such as Scrum and we execute sprints to build new features for our product.

I am a proponent of TDD (Test Driven Design), and as a part of what I deliver in a sprint I always write tests and I always get them integrated with the build (ie ccnet); however the other developers do not follow this practice and it is not enforced.

Is it a good practice to force a development group into providing unit tests as a part of what is delivered in a sprint?

+8  A: 

Unless you are a position of authority, the best thing you can do is to convince them of the value of the test suite.

It's very difficult to get developers to see the light on this issue if they aren't seeing it done right.

Try to pair with another developer and show them the benefits and the clarity that comes from writing the tests FIRST. If you don't do this, they are likely to write all of their code, get it working, and then write tests. So, from their point of view, it will feel like simply an extra task that doesn't help them get things done.

Also keep in mind that people often do not understand how to write good tests. Even more, some do not know how to make use of tools like jmock, which can lead to them getting stuck and giving up on writing a test.

TM
I think that, once seen done right, the best developers will see the high value in creating a simple but efficient unit test suite. +1 since I can say "Go Blue" here, too!
Jeff Wilcox
My brain filter caused me to read that as "Go Green!". So, given that: "Go White!"
TM
Position of "authority"? Maybe you can create change. Position to determine compensation and rewards? Then you can change people's coding habits. A test suite has to pay some reward. If you reward bug-free deliveries, for example.
S.Lott
@S.Lott I'm not suggesting that you should force it, even if you are "the boss". I'm just saying that if you are talking about coworkers, there's no way you could even attempt to force something or or make it "required".
TM
I have done pair programming with some of the developers on the team already. I have taken it upon myself to get the tests integrated with ccnet; however the team does not seem interested and management does not seem interested either. I have done an internal presentation on TDD also to the team to explain the practice and the approach that I personally take in TDD. I am thinking the best way to convince at this point is to show a lower defect rate overall.
Michael Mann
A: 

it depends on your Version Control, but there are Version Control Software that enable you to run scripts before check-in or before merge to the Production branch. and it will not let the developer check in if the unit testing is failed.

Baget
This won't really fix things: unit tests just won't be created. If you put in some test to force a test for each class/method or something, people will just write bad tests that don't test anything.
TM
+5  A: 

Forcing anything onto anybody is not a good practise in my view. I would show them the benefits of TDD at every opportunity I get. This should automatically get the rest of the team to voluntarily practise TDD.

msvcyc
+1: You can't force anyone to do anything. You can, however, reward someone for doing the right thing. Then it's their choice.
S.Lott
My personal view, "at every opportunity I get" might be too often. Choose "the opportune moment", for example when someone made a change that altered behaviour of a method unintentionally etc.
Ula Krukar
If you do force it as a practice then that will cause a few things to happen: 1. Define a standard way of writing unit tests 2. Force the experienced TDD developers to mentor the other developers in the practice 3. Increase code coverage 4. As developers get more experience with the practice it should reduce the number of defects
Michael Mann
@Michael Mann: "If you do force it as a practice" -- your premise is faulty. "force" doesn't work except to cause arguments. You need to reward good behavior. "force" leads to people subverting what you're "forcing" them to do.
S.Lott
I generally do feel that forcing is a bad idea, but when I am looking through the code and I see inconsistency, not well thought out design, and technical debt I wonder what would be the harm in having an expectation that as a deliverable you will deliver tests. I do understand that much of what I am talking about can be addressed through pair programming, code reviews, mentoring, development standards etc, but it seems to me that these actions are not important to companies developing software. What matters is work product.
Michael Mann
+3  A: 

Considering unit-testing improves code and software quality on a long term, I would say that, yes, it is good practice to have your developpers provide unit-tests -- be it part of some kind of sprint or not.

The two main barriers to unit-tests I've seen are :

  • the developpers don't get the point : "why would we write more code just to test ?"
  • "we don't have time to write unit-tests"

To answer the first point, you'll have to provide some sort of demonstration / formation, I suppose ; if you can get developpers to see why unit-tests are useful, they will like them, and use/develop them ; but they need to seen why those are useful : unless you are their boss, you cannot force people to develop unit-tests.
And, even if you are their boss, they will probably not do the best possible job if they are being forced : unit-testing is often done better if people understand why and how !

To answer the second point... Well, you obviously need to get your developpers some "special" time to developp unit-tests ; it can mean less time to do manual testing, btw.

Another thing is : it is hard to know "what to test", and "how to test" : you will need to explain / demonstrate that to your colleagues : some things cannot be tested, some things don't need to be, and some things are not "unit-testable" -- well, I suppose, unless you software is really well engineered ^^

Pascal MARTIN
On the "writing more code" point -- I find that if I have to test my code to high coverage, I end up putting in more thought ahead of time and writing more succinct code as a result. That is what sold me on the idea -- and what should sell it to any seasoned developer. The hurdle to overcome is the fact that it punishes the lazy approach of cut-and-paste coding, a habit which is all too easy to fall into.
Steve Gilham
A: 

No. In my experience, TDD isn't all that useful in practice. I sometimes use it for really general fundamental classes (like geometry or generic data structures) that lend themselves naturally to automated tests. But for UI components or business logic, I find it's more trouble than it's worth.

C. Dragon 76
Unit tests aren't for UI. I belief you that they're trouble there. But they're definitely for business logic!!
Juri
It would be interesting if you could explain why you find TDD is not useful. TDD stands for Test Driven Development not testing an individual class. I can guess why you would get mileage out of an individual test but I have difficulty understanding why you would dismiss the methodology based on your implementation being troublesome.
grenade
@grenade: My experience with TDD is that it hasn't really uncovered a lot of bugs and many of the bugs it has uncovered would easily be revealed with simple black box testing. It also hasn't influenced my class design much, but perhaps I have a tendency to overthink class design anyway. I'm not outright dismissing the methodology. I'm just saying that in my personal experience, the time spent designing and maintaining TDD tests is generally better spent elsewhere.
C. Dragon 76
A: 

First, talk to your manager. If he is convinced that testing is a good thing, add a coverage test to your build system. If the coverage of your unit tests falls below a certain level, you can handle it as a failed build. This gives your colleagues a measure, a way to see when the fail to deliver tested code.

In your case, NCover seems to integrate nicely into CC.NET.

Malte Clasen
+4  A: 

You don't want lip-service unit testing, you want whole-hearted unit testing. That isn't something that can be forced. What you need to do is influence your teammates over time to see the benefits of unit testing and to develop a unit testing culture.

To start with you need to understand that different people change for different reasons. In Crossing the Chasm terms, visionaries will adopt new techniques because they are better, but pragmatists adopt new techniques either because they solve a problem/pain the currently have or because everyone else is adopting it.

Your mission then it to show how unit testing can solve a pain your team currently feels. As you win over people one-by-one eventually you can reach a tipping point where unit testing is the norm and everyone goes along with it. However if you can't tie unit testing to a pain your team feels then your efforts to convince them will likely fail.

Jeffrey Fredrick
+1  A: 

I've gotten in that position on many jobs and contracts in the past, so I've finally gotten discouraged and embraced the darkness by advocating Development Driven Development.

I've found that when most managers embrace XP, they're embracing throwing out the documentation, not really doing TDD. Programmers on most teams are rewarded for quick hacks that get the defect out of their queue, and it's one manager in about ten who has the guts to stand up to senior management as an advocate of the overall quality of the product as opposed to the bottom-line-for-this-quarter way of doing business. After all, most software jobs that pay anything are corporate sponsored, and Freud proved that corporations are insane.

Or at least, he should have.

John Lockwood
+1  A: 

There is a great Joel on Software article on this called Getting Things Done When You're Only a Grunt. His strategies applied to united testing would be the following:

  1. Just Do It

    Most important, I think. Regularly write tests, do not make it appear as if you yourself see them as a minor part of development.

  2. Harness the Power of Viral Marketing

    If you see an error in someone else's code, write a test that triggers it and present both to him. Maybe he sees your point.

  3. Create a Pocket of Excellence

    Identify the team members who are open to the idea but not quite sure how to work with unit tests and set up a number of test classes until everyone of them knows how to do it. Then turn towards the other ones. Things are a lot easier to establish once you are not the only one anymore.

  4. Neutralize The Bozos

    There will be team members who are almost impossible to get to write tests. Maybe those should be dealt with by regularly breaking their code with a new commit - and then pointing out that since they don't have tests it was hard for you to notice.

Ozan