Why are we embarrassed to admit that we don’t know how to write tests?

July 7th, 2009 · 17 Comments ·

Take your average developer and ask “do you know language/technology X?” None of us will feel any shame in admitting that we do not know X. After all there are so many languages, frameworks and technologies, how could you know them all? But what if X is writing testable code? Somehow we have trouble answering the question “do you know how to write tests?” Everyone says yes, whether or not  we actually know it. It is as if there is some shame in admitting that you don’t know how to write tests.

Now I am not suggesting that people knowingly lie here, it is just that they think there is nothing to it. We think: I know how to write code, I think my code is pretty good, therefore my code is testable!

I personally think that we would do a lot better if we would recognize testability as a skill in its own right. And as such skills are not innate and take years of practice to develop. We could than treat it as any other skill and freely admit that we don’t know it. We could than do something about it. We could offer classes, or other materials to grow our developers, but instead we treat it like breathing. We think that any developer can write testable code.

It took me two years of writing tests first, where I had as much tests as production code, before I started to understand what is the difference between testable and hard to test code. Ask yourself, how long have you been writing tests? What percentage of the code you write is tests?

Here is a question which you can ask to prove my point: “How do you write hard to test code?” I like to ask this question in interviews and most of the time I get silence. Sometimes I get people to say, make things private. Well if visibility is your only problem, I have a RegExp for you which will solve all of your problems. The truth is a lot more complicated, the code is hard to test doe to its structure, not doe to its naming conventions  or visibility. Do you know the answer?

We all start at the same place. When I first heard about testing I immediately thought about writing a framework which will pretend to be a user so that I can put the app through its paces. It is only natural to thing this way. This kind of tests are called end-to-end-tests (or scenario or large tests), and they should be the last kind of tests which you write not the first thing you think of. End-to-end-tests are great for locating wiring bugs but are pretty bad at locating logical bugs. And most of your mistakes are in logical bugs, those are the hard ones to find. I find it a bit amusing that to fight buggy code we write even more complex framework which will pretends to be the user, so now we have even more code to test.

Everyone is in search of some magic test framework, technology, the know-how, which will solve the testing woes. Well I have news for you: there is no such thing. The secret in tests is in writing testable code, not in knowing some magic on testing side. And it certainly is not in some company which will sell you some test automation framework. Let me make this super clear: The secret in testing is in writing testable-code! You need to go after your developers not your test-organization.

Now lets think about this. Most organizations have developers which write code and than a test organization to test it. So let me make sure I understand. There is a group of people which write untestable code and a group which desperately tries to put tests around the untestable code. (Oh and test-group is not allowed to change the production code.) The developers are where the mistakes are made, and testers are the ones who feel the pain. Do you think that the developers have any incentive to change their behavior if they don’t feel the pain of their mistakes? Can the test-organization be effective if they can’t change the production code?

It is so easy to hide behind a “framework” which needs to be built/bought and things will be better. But the root cause is the untestable code, and until we learn to admit that we don’t know how to write testable code, nothing is going to change…

Tags: Uncategorized

17 responses so far ↓

  • Ivor McCormack // Jul 8, 2009 at 1:39 am

    Misko, you have opened a can of writhing snakes!

    For many years I have seen development groups blame the fact that a bug was found by a customer on a lack of testing. To offset this management put in testers who are a filter to stop the bug getting out into the wild.

    Developers now have someone to blame.

    Most of the developers I meet nowadays are thoughtful people who do not deliberately try to bugs in their code. And yet… When I asked a developer recently how he had implemented an ambiguous statement that involved a fairly complex algorithm to process financial info into a set of actions and outputs, the reply was “I picked this way as it looked like the best one”.

    Did he talk to the person who came up with the idea? No. Did he mock the functionality up and walk it through? No. Did he come up with a set of usage ideas and see if the functionality solved the problems? No. Was it discussed as part of peer review? No. Did it work? Yes!

    The reason I asked the questions was because the user when presented with the functionality got very irate, threw the problem upstairs and a shower of S$%^ rained down. On the Testers.

    The functionality worked, but the testers should have figured out if it met the requirements. The functionality worked, but the tester only found out how it worked by talking to the developer after the build was released to test and then only for 15 minutes. Were there bugs? Yes. Were they fixed? Yes.

    The problem as you describe it is very critical to the fundamental nature of the software industry. Until each and every person involved in some way with the production and deployment of software takes personal ownership and responsibility for their part of it, we are constantly going to be fighting the image of bad quality, untested software that doesn’t deliver on its promise.

    And that is not about developing any skillset, or learning new technologies or delivering better bigger software. It is a fundamental principle of personal integrity that is involved.

  • Mark Simpson // Jul 8, 2009 at 3:02 am

    You hit the nail on the head regarding developers being sheltered from the pain of their own mistakes. If developers fail to write testable code and then shunt the burden of ‘unit’ testing to a separate team, it is has limited value (I say unit in hyphens, as this arrangement invariably tends towards integration testing due to the units of code having unbreakable dependencies).

    If a developer writes no tests and then throws it over the wall to someone who is expected to write the automated tests for them, it has causes multiple problems:

    A: The tester has to learn the code and infer the expected behaviour. While this is valuable in terms of determining whether the API is adheres to the principle of least surprise, it is not a good use of a tester’s time.

    B: The tester is now faced with a situation akin to testing legacy code. The code is written and it’s probably not going to change… so they do their best with it. They are often not allowed to change the code.

    C: The developer learns nothing of the pain of testing the code and consequently writes code in the same fashion.

    There is some value in this adversarial role, but if developers write good testable code and good tests, it’s much more valuable.

    In my opinion, it’s much better to have developers responsible for the bulk of their own automated testing. Testing specialists can provide support to make the code testable and also ‘top up’ / fill in some of the areas areas (and since tests already exist, the tester can get up to speed much more quickly).

  • igorbrejc.net » Fresh Catch For July 8th // Jul 8, 2009 at 6:02 am

    [...] Why are we embarrassed to admit that we don’t know how to write tests? [...]

  • David // Jul 8, 2009 at 7:10 am

    Miško, You’re my hero.

    “There is a group of people which write untestable code and a group which desperately tries to put tests around the untestable code. ”

    Sad, but so true.

  • misko // Jul 8, 2009 at 7:51 am

    @Ivor,

    l love your coment.

  • misko // Jul 8, 2009 at 7:54 am

    @Mark,
    I could not agree more.

  • Anand // Jul 8, 2009 at 1:57 pm

    Misko, this article was really good. Thank you for coming up with such write ups that awaken people and explain in such a clear manner.

    I have one wish: Please do a post that tells best resources (books, websites) where developers can learn how to write testable code.

    Thank again.

  • Tomek // Jul 8, 2009 at 11:27 pm

    Wow! So straight to the point! Congratulations!!!

  • Arjun // Jul 9, 2009 at 3:50 am

    Hi,
    I recently happen to bump into your blogs and from that day i have been following, must say it was a great find for me. its been an 2 years now that i have been working as a software developer and I admit that I haven’t been the writing unit tests , worse actually never followed TDD at all . My question is that how one can develop the skill of writing Testable Code. Do you have any name of some of the books or links where practical examples on how to write testable code are shown (Some of your own experiences)? Can you share it.

    Many thanks,
    ~Arjun

  • misko // Jul 9, 2009 at 6:44 am

    @Arjun,

    I don’t have any book to recommend, but you can start with the testability guide: http://misko.hevery.com/code-reviewers-guide/

  • Tomek // Jul 9, 2009 at 1:37 pm

    @Arjun The testability guide is like “Working effectively with legacy code” but the guide is much shorter read.

  • Sridhar visvanath // Jul 9, 2009 at 11:45 pm

    I do not think we can word it any better. I face it everyday in my workplace…it is like trying to communicate to someone who cannot understand your language…I feel testability is actually not just about testability…it just scratches the surface…we all had our old way of thinking about coding…that forces us to sort of be in a coding camp vs testing camp…It takes an actual medium-complex program excercise, a lot of patience and a lot of hand holding to learn to write testable code…and then go on to the nice Red-Green-Refactoring rhythm…I do not think it can be explained to people…it has to be felt like a spiritual excercise…once we get the Aha feeling…then that is when we cannot go back…

  • Sridhar visvanath // Jul 9, 2009 at 11:46 pm

    Also, from the nice red-green-refactoring rhythm…we then focus on code smells…and refactoring…and start looking at our code like we had never done before…It is an enlightening…eye-opening experience

  • fqqdk // Jul 10, 2009 at 5:40 am

    Reasoning about code is just like reasoning about a scientific theory, and tests are just like experiments. Experiments should be repeatable, just like tests.
    If the predictions of a scientific theory cannot be validated with experiments, then it is a useless theory, and if tests are hard to write, because the code is untestable then that code is bad. QED.

  • fqqdk // Jul 10, 2009 at 5:42 am

    And coding without having tests in place is just like religious fundamentalism :D

  • Random Links #9 | YASDW - yet another software developer weblog // Jul 13, 2009 at 10:01 am

    [...] Why are we embarrassed to admit that we don’t know how to write tests? Was ist jetzt wirklich genau testbarer Code? [...]

  • Sarthak // Jul 13, 2009 at 12:09 pm

    I know developers who think that unit testing is not their responsibility… Also, testing team sometimes writes unit tests and sometimes just does black box testing (depending on their schedule) …. so by the time the testing team receives the code, its so hard to test, that testing team generally writes one full blown integration test… So if the developers dont write unit tests anytime, how would they come across any pains… the right thing to do is have the developer write some tests… I am of the opinion that the developers should do majority of the testing using Unit Testing/Functional testing/Integration Testing … and only some of the black-box testing should be left to plain QA…

Leave a Comment