views:

210

answers:

12

First let me just state that coding without unit testing is just plain crazy. Without unit tests I'm living in constant fear of breaking something without noticing. So I'm all for unit testing, and I prefer doing it using TDD.

My question however is; when should you introduce unit tests when starting a new project? Living in the spirit of TDD the first code line of the project should probably be a unit test. However, no matter how much I love that fuzzy feeling TDD gives I often find it difficult to start out with unit testing from the beginning when you have nothing. Often I find it easier to "cheat" and code without testing from the beginning, and introduce tests when I see where the project is going.

What are peoples opinions on this? When should I introduce unit tests when starting new projects?

+5  A: 

You should be able to start with a unit test. If you find it difficult to do so, then you probably haven't broken down the requirements to their atomic bits well enough, at least in my experience.

GWLlosa
I don't like to write unit tests until they can at least compile. Hard to do that if the first line of code is a test case.
tster
Then you aren't doing really "pure" TDD
Ricky AH
+2  A: 

IMHO, the first deliverable to the stake-holders should have 80+ % test coverage, and the first deliverable should be at the end of the first (maybe 2nd) iteration.

Beyond that, it is a matter of personal preference as to how close one wants to stay in line with the TDD philosophy.

Michael Easter
+1  A: 

I usually write my first test case right after I write the first function which isn't "obviously correct." For example:

I could have:

class HelloWorld
{

  int value;

  int getValue() { return value; }
}

and not have any tests. But once I do:

class HelloWorld
{

  int value;

  int getValue() { return value; }

  int doSomething() { blah blah blah }
}

I write a test case.

tster
+1  A: 

Hi there.

My pattern is that I usually start coding a new project first, and pretty much as soon as I've got one class with a bit of functionality, I will create a unit test for it. In other words, I introduce a unit test project as part of the solution very early on.

(I'm currently not practising TDD, though I do see the benefits).

Cheers. Jas.

Jason Evans
+1  A: 

Often I find it easier to "cheat" and code without testing from the beginning, and introduce tests when I see where the project is going.

So you're in that state of not knowing what to do next (or first), and your most comfortable action is to code. That's probably not good. If you don't know what to do next, you should be designing, and with TDD we design, and we express our designs, by writing tests. I think you should practice TDD a little more rigorously and see where it takes you; I expect it will take you to writing less buggy code and to getting into the flow more quickly. We need to practice any technique enough to be comfortable with it, and it sounds like TDD still isn't 100% comfortable for you.

How do you get to Carnegie Hall?
Practice, brother, practice!

Carl Manaster
+2  A: 
  • You should definitely introduce TDD on new projects - it's easier.
  • Show them how it would help not just pressuring people into doing it.
  • Having technical leadership setting an example every day makes a big difference.
  • Arbitrary measures like "we need 80% coverage" don't cut it. Why not 81%? It's all about developing a sense of judgement about code coverage and what's worth testing.

You have to have a genuine interest in helping the other person and capitalize on a teachable moment:

A pupil was scolded every day by the TDD guru. He said "Why aren't you doing test first development? You're a developer. You should be doing developer testing!"

The guru hit the pupil with rolled-up newspaper and scolded the pupil every day like this for a year, until one day a jolly, extreme programming coach turned up.

The extreme programming coach heard the developer say "I'm struggling with this damn feature and I can't get it quite right."

The coach smiled and said "show me again how you got to that..."

The pupil set his example up again and ran the failing code.

"When I press this, and move the slider to 4 it should output 42 not 41!. What do you think I should do?"

The jolly XP coach smiled again (he did a lot of that), and said "do that again, but this time let me type..."

Before you know it, the pupil and the coach had written a TDD test together but since the pupil was motivated to get his work done he forgot to resist and was distracted away from having a meta-discussion about the philosophy of agile.

The pupil then said "aha! I get it. So that's why we write unit tests"

... and in that moment the pupil was enlightened. ka-ching!

;-)

cartoonfox
+2  A: 

I usually start with the most important feature and work my way in from there, using an outside-in approach. This often means starting with some UI.

The way I do it is by creating the desired UI. Since we normally can't develop UI with TDD, I simply create the View with the technology of choice. No tests there, but I wire up the UI to some API (preferrably using declarative databinding), and that's when the testing begins.

So I often write a Humble Object without tests, but as soon as I start writing code with a degree of Cyclomatic Complexity higher than 1 I start writing unit tests first.

For libraries this means that sometimes, I even create the test suite library before I create the SUT library.

Mark Seemann
A: 
  1. Create the interfaces necessary to stage a test.
  2. Write the test(s).
  3. Write code to pass the test(s).
  4. Repeat.
Matthew Flynn
+1  A: 

However, no matter how much I love that fuzzy feeling TDD gives I often find it difficult to start out with unit testing from the beginning when you have nothing. Often I find it easier to "cheat" and code without testing from the beginning, and introduce tests when I see where the project is going.

I find that writing tests helps to materialize a problem and a solution, in other words, to design, and I start to write tests as soon as I start to write code. Tests help to know if the code works, they show sometimes how bad an idea was, they help to avoid writing non testable code, they help to refactor. No, really, I like to have tests in the early stage, I find them helpful to see where the project is going :)

Pascal Thivent
+1  A: 

I would recommand starting TDD at the very first line of code.

TDD is to me a "Design" approach which helps me create clean and working object oriented code. When I code a test unit class, I am actuallu describing the dialog I would like to have with the objects I wand to build.

So, it helps actually me doing it, especially when I am not clear of what should do the code.

A side effect, as you explain it, is also to build a great testing tool at a mirror of the builded application.

Bernard Notarianni
+1  A: 

I often find it difficult to start out with unit testing from the beginning when you have nothing.

I first I get a rough idea of the design : I try to envision the classes I might need to implement that bit of functionality. This design will not necessarily be the final one ; it's just a starting point.

Then I choose one bit of functionality to start with and ask "where does it belong ?". This gives me the class I'm gonna begin with, and ask "how can I test it - how will I know the method work ?". I grow a list of tests and pick the easiest one ; this is going to be my first test.

philippe
+1  A: 

Disclaimer: I am an old-school, hard-core, waterfall guy, not TDD (I do understand Agile, X-prog, TDD, etc and don't want to start a religious war).

You ask when to "introduce" unit test, but don't define "introduce". The way I read it, you mean "start testing".

Let's look at it old-school ... as soon as you have reviewed and signed-off on system docs, you can write and review a system/integration test spec. As soon as you have reviewed and signed-off on your detailed design doc, you can begin to write and review your unit test spec.

Don't have a detailed design doc?? To hell with the methodology, you are NOT ready to begin coding, never mind thinking of unit test.

Assuming you have & agreed the detailed design doc, the rest is a matter of taste.

You can write the test cases first, or have someone else write them in parallel with you writing the code; you can test as you code if you want to, etc.

Old school says write the code, then run it through some static code analysis tools (Splint, CppCheck, etc), and only then begin to run unit tests (which may have been completed before the code was).

Just don't forget the golden rule - if requirements, architecture, design are not complete and reviewed you are building a house on sand - do not n coding or unit test.

But the ordering is your choice. What works best for you, your team, your current project? And ymmv

Mawg
Well, can't say I agree with regards to the extensive demands on the requirements documentation before starting. But +1 for the old school take on this.
stiank81