views:

367

answers:

11

I know that TDD style is writing the test first, see it fails then go and make it green, which is good stuff. Sometimes it really works for me.

However especially when I was experimenting with some stuff (i.e. not sure about the design, not sure if it's going to work) or frantically writing code, I don't want to write unit tests, it breaks my flow.

I tend to write unit tests later on and especially just before stuff getting too complicated. Also there is another problem writing them later is generally more boring.

I'm not quite sure if this is a good approach (definitely not the best).

What do you think? Do you code write your unit tests later? Or how do you deal this flow problem or experimental design / code stage.

+9  A: 

I've written tests after the fact. Better late then never. They are always worth having.

However, I have to say, the first time I wrote them before writing the tested code, it was extremely satisfying. No more fiddling around with manual testing. I was surprised just how good it felt.

Also, I tend to write unit tests before refactoring legacy code - which, almost by definition, means that I'm writing tests to test code that's already written. Provides a security blanket that makes me more comfortable with getting into big blocks of code written by others.

dommer
+2  A: 

I often take the same approach you're talking about. What seems to work well is to treat the exerimental code exactly as such, and then start a proper design based on what you've learned. From here you can write your tests first. Otherwise, you're left with lots of code that was written as temporary or experimental, and probably won't get around to writing tests for all of it.

Jon B
I think putting experimental code aside and planning properly with TDD is a really good point.
dr. evil
A: 

Maybe you are resisting to use test-first approach, because you don't know where unit-tests should be used. I had the same problems when I was learning TDD.

You would recommend to you just to use different tactics in TDD. And with time you will understand it much better. I think it is just matter of time. And it was very hard for me understand it at first grasp. I read the same literature, but couldn't understand it then. Just keep learning it more and more for some period of time.

Fedyashev Nikita
A: 

VS 2008 has a nice feature that will generate test classes for an object, the tests needs to me tweaked but it dose a lot of the grunt work for you. Its really nice for crating tests for your less then diligent co-workers.

Another good point for this is it help to prevent you from missing something, expectantly when your working on code that isn't yours.

if your using a different testing framework then MSUnitTest, it's fairly simple to convert then tests from MSUnit to Nunit, etc. just do some copy and past.

Bob The Janitor
:) That's lovely feature. But unfortunately (or fortunately!) I'm using nUnit
dr. evil
It takes a little bit of work, but you can convert MSUnitTest to nUnit test with some copy and past.
Bob The Janitor
oddly enough going back isn't as easy, go figure
Bob The Janitor
+3  A: 

"I'm not quite sure if this is a good approach (definitely not the best)."

Not good? Why not?

Are you designing for testability? In that case, your design is test-driven. What more can anyone ask for?

Whether the tests come first, in the middle or last doesn't matter as much as designing for testability. In the end, changes to the design will make tests fail, and you can fix things. Changes to the tests in anticipation of design changes will make the tests fail, also. Both are fine.

If you get to the end of your design work, and there's something hard to test in the middle, then you failed to do TDD. You'll have to refactor your design to make it testable.

S.Lott
A: 

Writing the code first is natural when you're trying to figure out how your code is going to work. Writing the test first helps you determine what your code show do (not how it should do it). If you're writing the code first, you're trying to solve the problem without completely defining the problem. This isn't necessarily "bad", but you are using unit tests as a regression tool rather than a development tool (again, not "bad" - just not TDD).

Todd R
+14  A: 

What I've learned is that there is no experimental code, at least not working in production environments and/or tight deadlines. Experiments are generally carried out until something "works" at which point that becomes the production code.

The other side of this is that TDD from the start will result in better design of your code. You'll be thinking more about it, reworking it, refactoring it more frequently than if you write the tests after the fact.

Brian
+1 for "experiments are carried out"
furtelwart
+2  A: 

I would say that for normal development, TDD works extremely well. There are cases where you may not need to write the tests first (or even at all), but those are infrequent. Sometimes, however, you need to do some exploration to see what will work. I would consider this to be a "spike", and I don't necessarily think that TDD is absolutely necessary in this case. I would probably not use the actual "spike" code in my project. After all, it was just an exploration and now that I have a better idea of how it ought to work, I can probably write better code (and tests) than my "spike" code. If I did decide to use my "spike" code, I'd probably go back and write tests for it.

Now, if you find that you've violated TDD and written some production code before your tests - it happens - then, too, I'd go back and write the tests. In fact, on the occasions where this has happened to me I've often found things that I've neglected once I start writing the tests because more tests come to mind that aren't handled by the code. Eventually, you get back in the TDD rythym (and vow never to do that again).

tvanfosson
+1  A: 

I usually write my tests first but sometime while experimenting I write the code after. Once I get an idea of what my code is supposed to do, I stop the code and start the tests.

Dan
A: 

I would like to say that I always write Unit tests first but of course I don't (for numerous reasons well known to any real programmer :-)). What I (ok, also not always...) do is to convert every bug which takes me more than five minutes to find into a unit test. Even before I fix it. This has the following advantages:

  • It documents the bug and alerts me if it shows up again at a later point of time.
  • It helps in finding the bug, since I have a well-defined place to put debugging code into (setting up my data structures, call the right methods, set breakpoints on etc.) Before I discovered unit testing I modified the main() function for this testing code resulting in strange results when I forgot to remove it afterwards ...
  • Usually it gives me good ideas what else could go wrong, so it quite often evolves in a whole bunch of unit tests and resulting in more than one bug getting discovered resp. fixed.
MartinStettner
+2  A: 

Consider the psychological tendencies associated with sunk cost. That is, when you get to the second part of the equation, that laziness gene we all have makes us want to protect the work we have already done. The consequences?

If you write the tests first...

You tend to write the code to fit the tests. This encourages the "simplest thing that solves the problem" type development and keeps you focused on solving the problem not working on meta-problems.

If you write the code first...

You will be tempted to write the tests to fit the code. In effect this is the equivalent of writing the problem to fit your answer, which is kind of backwards and will quite often lead to tests that are of lesser value.

Although I'd be surprised if 1 programmer out of 50 ALWAYS writes tests first, I'd still argue that it is something to strive for if you want to write good software.

JohnFx