I have to admit that in the last little while I have strayed from the path, and I regret doing that now for even a couple of minutes. Tests are not something that you can easily add in later. Well, not good tests. One of the reason that I like unit tests is that I can "see" the different paths that things can take easier. When using any kind of UI I tend to do it the exact same way, every time. This isn't great if you are doing UI functional testing, because you're only hitting part of it every time, instead of a consistent path, all of the time.
I think that I really have to harp on my co-worker for doing test first, I think that I have to show it to him really... I have to find a better way to address it I think. Ah well. We'll see how things go.
Listening to: K's Choice - Not an addict (acoustic)
A fascinating perspective I read in a book called "Testing Extreme Programming" was that programmers are always used to seeing things that work, while testers are always used to seeing things that break.
ReplyDeleteSo testers can look at a requirement and identify far more branches/conditions that need to be tested, while the programmers just like to focus on the "happy path" -- the one case where the requirement works as expected.
How does this relate to TDD? Well given that during proper TDD you're only writing enough to make the test pass, you aren't writing supporting code for all of these other error branches/conditions. When you need to cover a new one error condition, you write a test for it, make sure it fails initially, then write the implementation, then retest until it passes.
Sometimes I start on the happy path, but usually I start by writing tests that ensure the method checks the parameters that were passed to it.
Some people might look at that and say "well shouldn't I cover all error cases from the beginning?". No. Keep your code as simple as possible and no simpler. Introduce error cases only as you need to handle them because they are just more cases to maintain later!
So here's the point: the reason I think you're having a hard time going back and writing tests later is that the code you're writing without tests is trying to cover too many error cases without testing/organization. It sounds backwards, eh?
I think it all depends on time!
ReplyDeleteDo you have time to take the TDD path? We know its all good and that... but do you have the time to do it?
Companies are looking for results. Most of the time, instant results, and if you waste time doing tests for every other method, you can be wasting money in the view of most managers.
Yes yes... I hear you out! Tests are very important, but you will be viewed as a slow po.
Andrew and I had this discussion a while back. Tests are the only way to ensure that your code does what you think it does. They are also an important regression testing mechanism.
ReplyDeleteSpecifically Andrew was asked "how long would it take you to code X with and without tests?". Personally they would probably take me about the same time, and my confidence in the tested version would be much higher than in the untested version. Which would you rather have in your software?
As well, testing is about thinking LONG TERM. To say that you can write a method quicker without testing is dangerous short-term thinking. Managers, unlike programmers, are paid to think about the long-term quality and health of the project. Advocating not writing tests for short-term gains is not good project management, in my opinion.
With a lot of code I write, my confidence is probably about 60% without doing any testing. Do a couple runs through with a few values, my value shoots up to around 90%. But to acheive that extra 10% of confidence, i'd probably have to spend twice as long as I did writing the code just to write the tests.
ReplyDeleteIf you don't write code that doesn't pass a test, where does that leave your confidence? That's what TDD is all about. :)
ReplyDeleteOh, and like anything else test-driven development (TDD) gets faster and easier with more practise.
ReplyDeleteI just wanted to point out (which Ryan sort of did) is that if you don't have automated tests, you have to figure out how if it works AT LEAST ONCE manually *anyways*, so if you write that one test as a unit test, that's your one time.
ReplyDeleteBut now everyone else can test this part of the system, without knowing about it, all the time.
Just to address Jimmy's comments about "wasting time" and doing things slower, yes, maybe for the first couple of weeks it might be slower, but it starts getting faster and faster compared to doing manual testing at the end where it gets slower and slower...
ReplyDeleteI think (and hope) that managers look at total turn around time for adding new features. If it takes 5 ppl 2 weeks of testing to make sure that nothing is broken, that is a lot slower and more expensive than a developer hitting a button and running through 100's of tests in seconds (and generating reports on this, code coverage, performance / load tests, ....).
Turn around time is where automated tests kick ass.
Speaking of turnaround time, I should write a blog post about one of my former employers (who shall remain nameless) and their bug handling process, specifically the time wasted on process for fixing simple regressions. It was right around the time I started learning XP, and it pushed me HARD into TDD. I never looked back really. :)
ReplyDeleteOK, that rant is up on my blog now. ;)
ReplyDeletehttp://www.ryanlowe.ca/blog/archives/001562.php