Unit testing is for lazy people
The other day I was talking to a guy about a possible freelancing gig and he said how wonderful it was that I should bring up the topic of unit/automated testing without being asked. He said that most (many?) developers don’t have the level of rigor to use automated testing.
My reaction was one of disbelief “Rigor!? But automated testing is one of the laziest things a developer can do! It speeds stuff up so much!”
As luck would have it, last night I was hit over the head with my own words and nearly died debugging a single function.
I was working on Stripe webhooks and for security reasons decided not to use the event data sent in request body. Makes sense right? Take the event id from request body, then fetch the actual event from Stripe.
It’s the only way to be certain you aren’t responding to bogus events sent by an evil person trying to make you look bad (nothing actually bad can happen, at worst a customer would get extra paid invoice emails).
Due to poor decoupling – I didn’t really want to decouple a 6 line function into two functions – everything was now difficult to test. I can’t create events on Stripe’s servers with unit tests and without actual events existing I can’t test the function works as it’s supposed to.
How many bugs can you put in a 6 line function anyway?
A lot of bugs!
When the client tested on staging … it didn’t work. Invoice email wasn’t sent and Stripe complained of a 500 error.
It took me almost two hours to fix all the bugs because my testing cycle looked like this:
- change code
- commit to develop branch
- switch to staging branch
- merge develop branch into staging
- push to github
- change to other terminal window
- pull from staging branch
- restart python processes
- go to Stripe dashboard
- pick customer
- create invoice item
- create actual invoice
- choose invoice
- pay invoice
- go to Stripe logs
- find invoice.payment_succeeded webhook
- scroll down to response
- look through raw html of django’s error page
- find symptom
- GOTO 1.
That’s right, a whopping 20 step debug cycle all because I’m an idiot and couldn’t find a way to automate this. Or maybe I was too tired to do the unobvious thing … although I still don’t want to split a 6 liner into two functions.
With proper unit testing the debug cycle would look like this:
- change code
- run tests
- symptom thrown in face
- GOTO 1.
Much lazier right?
For the record, those six lines of code contained 4 bugs ->
- forgot to import a module
- different event data structure than I understood from the docs
- twice^
- misnamed variables from one line to another
Yes, all of those could easily have been caught if my test coverage was actually any good! And then not only would I not look like an idiot in front of the client, I’d probably spend no more than ten minutes fixing this.
From http://swizec.com/blog/unit-testing-is-for-lazy-people/swizec/3752
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Mason Mann replied on Thu, 2012/03/01 - 7:45am
I know ZERO good programmers who do unit testing. It's so idiotic I can't believe people are still doing it when the right answer is code review. Don Knuth was right all along... as usual.
Unit tests invariably misses important bugs because the tests are out of date, not covering enough ground or buggy themselves, and to make things worse - they make people NOT want to properly refactor code because it breaks the tests. That's pretty lame.
Unit testing is for morons. Are you one?
Liam Knox replied on Thu, 2012/03/01 - 7:58am
in response to:
Mason Mann
I think this is perhaps the most moronic comment I have ever read.
Christ you can barely write English. Please don't tell me you try and code also.
Mitch Pronschinske replied on Thu, 2012/03/01 - 10:08am
in response to:
Liam Knox
Attila Király replied on Thu, 2012/03/01 - 11:29am
in response to:
Mason Mann
Chuck Dillon replied on Thu, 2012/03/01 - 11:44am
To the original post... Am I getting this correctly? You had some code that you couldn't unit test but needed to system test. Apparently you didn't system test but pushed it to staging where someone else would do the system test. If I have that right your "look like an idiot" sensation has nothing to do with test methods, it's apparently because you didn't test?
Another possibility is that you didn't do a good job system testing which makes this a valuable learning experience. One common thread I see with current generation developers is that they often are so focused on applying unit testing frameworks/paradigms (e.g. xunit et al) and are so overly confident that coverage means good - they are often just bad at testing in general, particularly at system testing.
To your, it's just six lines of code, scenario - we've all been there. You have a small amount of code with broad and complex dependencies. Do you use an inefficienct (e.g. 20 step) debugging cycle or do you build a potentially complex test harness? It's a judegement call we have to make from time to time.
Karl Peterbauer replied on Thu, 2012/03/01 - 12:32pm
Erin Garlock replied on Thu, 2012/03/01 - 2:02pm
in response to:
Karl Peterbauer
Mason Mann replied on Thu, 2012/03/01 - 4:40pm
in response to:
Liam Knox
Liam Knox replied on Thu, 2012/03/01 - 5:55pm
in response to:
Mason Mann
Mason Mann replied on Fri, 2012/03/02 - 4:14am
in response to:
Liam Knox
Liam Knox replied on Fri, 2012/03/02 - 5:48am
in response to:
Mitch Pronschinske
what are you going to do
Witold Szczerba replied on Sun, 2012/03/04 - 9:46am
in response to:
Mason Mann
Misko Hevery was right. Once he said that writing testable code is a skill most of the progeammers just do not have. More than that: they will never ever admit it. He also said, it takes about 2000 hours working on a project with proper coding practices to actually get how to write and maintain tests (a.k.a. executable specs). Without proper knowledge, tests are brittle and they turn against developer.
What also characteristic, all the (so called) tests haters always bad-mounth them providing worst testing related practices ever.
Some time ago I saw a wondeful presentation called "Why You Don't Get Mock Objects", by Gregory Moeck:
http://www.confreaks.com/videos/659-rubyconf2011-why-you-don-t-get-mock-objects
During this presentation he says, among others, something very very clever:
---
Regards,
Witold Szczerba
Mladen Girazovski replied on Mon, 2012/03/05 - 6:54am
You should have splitted the method. 6 lines of code is by no means to small for refactoring.
As for the rest, wrtiting unit tests is easy (if you write testable code), but a lot of unit tests will make some considerable sized code, and this code needs to be maintained (refactored, avoiding redundancies, decoupling dependencies, etc. pp.), if you fail to do this, your test suite will slow you down when writing prod code.