BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Is TDD a Form of OCD?

Is TDD a Form of OCD?

Leia em Português

This item in japanese

Bookmarks

Key Takeaways

  • In modern software testing developers are writing tests and increasingly responsible for testing their own and their peers’ code
  • Fear of failure or “Evaluation Anxiety” is a very common psychological condition that is directly impacted by self-testing and team-testing
  • TDD’s strict test-everything approach was in part a defense mechanism for developers seeking to avoid criticism of their code
  • New approaches like Behavior Driven Development can alleviate this anxiety and cause teams to take responsibility for failure together
  • A broader measure of code coverage is needed that will shift the focus from flaws in one developer’s code, to a team’s ability to meet customer requirements

I’m never going to write a test, that’s not my job as a programmer.

This was the parting statement of a developer who decided to quit his job, two days after his team leader announced the adoption of TDD, to deal with serious code quality issues he discovered. It was 2006, and that team leader was prominent developer and tester Jeff Langr, who shares the story in his Foreword to the book “Developer Testing” published by Addison Wesley. Langr says:

Thankfully, 10 years on, most developers have learned that it’s indeed their job to test their own code. Few of you will embark on an interview where some form of developer testing isn’t discussed. Expectations are that you’re a software development professional, and part of being a professional is crafting a high-quality product. Ten years on, I’d squash any notions of hiring someone who thought they didn’t have to test their own code.

In the age of agile development and DevOps, developers are increasingly required to take responsibility for all aspects of their code - from quality to maintainability, deployability, scalability and security. Many have written about the cultural aspects of this huge shift, from programmer as “technician of code”, to programmer as a holistic member of an organization that is supposed to deliver value to customers.

In this article, we’ll focus on one specific aspect of that shift - the emotional impact of programmer as tester.

It’s one thing to be responsible for making your code deployable in production. It’s quite another to test and discover serious problems in your code, having to admit those problems exist, fix them and commit them in a transparent way to a shared codebase.

Or, from another direction, consider the common practice in agile teams to display an alert on a huge screen, or even sound a siren, when someone “breaks the build”, and make it visible who broke the build. Inevitably, most developers who experience that will be emotionally affected.

Developer Testing as “Evaluation Anxiety”

Testing is becoming an introspective and evaluative activity. Developers are regularly testing their own work. Their close colleagues and superiors test their work. There are regular code reviews that expose flaws in their work.

Of course, there were always QA teams criticizing developer activity. But they did it from the outside, frequently in a “black box testing” paradigm. And QA testers were, at least in the past, treated as lower-level employees with lower pay, sometimes outsourced or offshore, reducing the impact of that critique.

Coming from a developer, who is higher in the organizational food chain, and understands the code, criticism can hurt much more.

Anxiety is the most common form of mental illness in the U.S., affecting 18.1% of the population. A common type of anxiety is “Social and Evaluation Anxiety”, which is the third largest psychological disorder in the country. It is defined as “Fear of being judged and evaluated negatively by other people, leading to feelings of inadequacy, embarrassment, humiliation, and depression”. Or in plain English, fear of failure. According to anxiety therapist Thomas A. Richards:

If your therapist says, ‘Face your fears and they’ll go away’, [they] do not understand the dynamics of social anxiety. We have constantly faced our fears ever since birth, and yet we feel more fearful now than we did in the past.

We’re not trying to suggest that testing practices can lead to full-blown anxiety disorder (except, maybe, in some extreme cases). But it seems likely that many, if not most, of the programmers participating in modern agile testing practices, are facing this fear of negative social evaluation.

This anxiety will affect developers’ well-being, negatively impact their productivity, and in the long term, stunt professional development.

Test-Driven Development: An Unconscious Defence Mechanism?

A conversation has emerged about the validity and necessity of TDD in agile development. TDD is a strict approach summarized as “red/green/refactor”, in which development of any software unit should begin with a test evaluating that unit, which initially fails, followed by the functionality which will cause that test to pass. Subsequently, any refactoring should ensure that the test continues to pass.

As far back as 2014 prominent calls were heard that TDD is dead. David Heinemeier Hansson, a vocal critic, wrote that while TDD promises a nirvana of clear, predictable code, in reality it became a gospel that developers are compelled to follow even when it causes negative effects:

Over the years, the test-first rhetoric got louder and angrier, though. More mean-spirited. And at times I got sucked into that fundamentalist vortex, feeling bad about not following the true gospel. (...) In public, I at best just alluded to not doing test-first all the time, and at worst continued to support the practice as "the right way".

I regret that now.

Maybe it was necessary to use test-first as the counterintuitive ram for breaking down the industry's sorry lack of automated, regression testing. (...) but I've long since moved on from the design dogma. I suggest you take a hard look at what that approach is doing to the integrity of your system design as well (emphasis added, G.D.M)

The current fanatical TDD experience leads to a primary focus on unit tests (...) I don't think that's healthy. Test-first units leads to an overly complex web of intermediary objects and indirection (...) It's given birth to some truly horrendous monstrosities of architecture. A dense jungle of service objects, command patterns, and worse.

It is easy to see that most organizations are shifting away from TDD as a testing paradigm and towards Behavioural Driven Development (BDD). Atlassian’s Heather Krebsbach writes unequivocally in 2016:

This test-first approach became increasingly popular and was coined as test driven development (TDD), but businesses quickly realized it didn’t give them the visibility and coverage they needed for the most important business cases in their systems. So, a variant of TDD was born called behavior driven development (BDD), focusing on the behavior of the system rather than its technical specifications.

This is a dry description of why “TDD doesn’t work”, but we’d like to dig a bit deeper. Taking David Hansson’s description of a “fanatical” and sometimes irrational practice, combined with Krebsbach’s description of TDD as ineffective, conjures up the psychological concept of intellectualization. According to Wikipedia:

In psychology, intellectualization is a defense mechanism where reasoning is used to block confrontation with an unconscious conflict and its associated emotional stress – where thinking is used to avoid feeling. It involves removing one's self, emotionally, from a stressful event. Intellectualization may accompany, but is different from, rationalization, the pseudo-rational justification of irrational acts.

Could it be that TDD, the practice of “compulsively” testing each and every line of code, was unconsciously a mechanism to protect developers against criticism of that code?

This is a strong statement, and we’re not suggesting that TDD is only that. We are suggesting that this emotional subtext is in the background of the methodology, and might be the cause of its uncompromising, dogmatic and sometimes short-sighted nature.

Is BDD an Emotionally Healthier Approach?

Is BDD any better than TDD? In this context, it might be. Behavioral Driven Development focuses on business requirements rather than code. It specifies an agile “story” in a formal language, and allows development teams to test that story.

This takes us from an exercise of testing code written by one specific developer, and a search for the developer who “broke the build”, to a broader exercise that evaluates the performance of an entire team.

After all, an agile team shares responsibility for the value delivered to customers, and it is recognized that value is a team effort between developers, testers and ops. In BDD, testing the story rather than the unit of code takes the “heat” away from individual developers and becomes a group introspective activity, much like the “scrum retrospective” which is done together as a team.

We posit that while TDD was, at least in part, a defensive mechanism allowing each developer to justify their own code, BDD is a healthier approach. It allows devs to evaluate their work as a team and share responsibility for the flaws found in it, addressing and easing Evaluative Anxiety, instead of just intellectualizing it.

Towards a Broader Concept of Test Coverage

SeaLights, a startup focused on helping agile teams increase test coverage, writes that test metrics in today’s agile development world are often skewed (disclaimer: I am an advisor for SeaLights). “Test/code coverage”, a much-coveted metric, is almost always taken to mean “unit test coverage”. This would appear to be a throwback from the TDD years, in which unit testing was considered the primary and most important part of agile testing.

In a BDD methodology, tests are broader and more inclusive, but test metrics have not evolved accordingly. Teams are making increased use of automated UI tests, integration and acceptance tests - but continuing to measure “coverage” as a percentage of their code covered by unit tests.

Unit test coverage is not a true measure of how comprehensive test suites are, in a BDD world, nor is it a metric for management to evaluate the effectiveness of a testing program.

A more holistic measure of code coverage is needed, which also takes into account integration, UI and acceptance testing. Instead of the somewhat compulsive drive to test each and every line of code, teams should move towards ensuring that every business function or “story” covered by the agile teams is tested.

Measuring that holistic coverage, and working together to achieve it, will be a true way to reduce developer anxiety. It can help face flaws in our code together, instead of trying to intellectualize them, prevent them, or justify them.

About the Author

Gilad David Maayan is a technology writer who helps leading technology brands elucidate their products to new audiences. He is also CEO and founder of Agile SEO which brings together developers, IT leadership and relevant content via the search engines.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • TDD and Test First

    by Matt Baker,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This article seems to conflate TDD and Test First.

    In my own experience, TDD is not used to "compulsively" test each line of code. Rather, TDD is used to discover what lines of code need to be written. More so than attempting to "validate" code and achieve code coverage, TDD has been about discovering design.

    Adding to that, Double Loop TDD begins with what you've referred to as an "agile story" -- the difference being it is called an "acceptance test".

  • TDD is not what you appear to think it is. TDD isn't a form of testing.

    by Ron Jeffries,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I'd be interested to read about your own extensive experience doing TDD, Gilad, at least to the point where you'd be deemed good at it by a TDD expert. I would also like to hear a bit about your experience in diagnosing psychological "disorders", and about how many TDD practitioners you examined in formulating this diagnosis.

    Then there's test coverage, which is rarely if ever mentioned as a metric when we do TDD, because TDD well done produces good coverage, but isn't the point of doing it. TDD is certainly a confidence-building practice, but it is as much an analysis practice (what are we going to do next) and a design practice (refactoring). One objection to calling it testing at all is that the check is written before the code, and conventionally we test the code AFTER we write it. That may be a quibble, as might all of this.

    Now it certainly is true that TDD can produce a pleasing "rhythm" of work, but one doesn't have to be OCD to enjoy rhythm. I imagine that TDD might appeal to people who were some combination of afraid their code might not run and OCD, but in all my work with it I've never found anyone who seemed actually to approach it that religiously.

    All that said, I certainly agree that working together is important and that many forms of confidence-building are used. I don't see the value of imputing anxiety and OCD as reasons why people might use a good practice, or in support of even better practice, the latter being the sole point of value to me in this article.

  • Re: TDD is not what you appear to think it is. TDD isn't a form of testing.

    by Paul Kearney,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I was going to make the case that TDD is not a testing activity but I see it has been made by a much more authorative source.

    In my opinion, what the author may be describing is the development 'box-ticking' that seems to be replacing thoughtful and deliberate use of good practices. Too often do I hear that there are 'must haves' when developing software which get applied and demanded out of proprtion and context of what is required. Personally for any project of any substantial size I would consider both TDD and BDD approaches.

    There are however no silver bullets.

  • Re: TDD and Test First

    by Gilad David Maayan,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hi Matt. I know that the stated objective of TDD is to provide a structure which allows developers to think their code through and thus produce better code. And this was proven to be the case in many organizations, including some I have worked for. However, according to some of the sources I quoted, and many others in the industry, while TDD was originally intended to promote better design, in many cases it ends up doing the opposite.

    My article was attempting to argue that behind the stated goal is an unconscious motivation - I precede every piece of code I write with a test because at some level, I'm afraid of breaking the build or getting negative feedback from my co-workers. This is a psychological hypothesis which is totally open to debate, I'm merely raising the question - is there a subtext of anxiety or fear of failure behind the rigorous practice of TDD?

    As for Double Loop TDD, I wasn't aware of this strand of the methodology, but having read a bit about it, it sounds closer to BDD, in the sense that the units being tested are broader and belong to the development team as a whole.

  • Re: TDD is not what you appear to think it is. TDD isn't a form of testing.

    by Gilad David Maayan,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hi Ron, honored to get your response to my post. I'll respond as best I can :)

    I'd be interested to read about your own extensive experience doing TDD, Gilad, at least to the point where you'd be deemed good at it by a TDD expert. I would also like to hear a bit about your experience in diagnosing psychological "disorders", and about how many TDD practitioners you examined in formulating this diagnosis.


    I don't have experience as a tester or developer. This article was written from the position of an outside observer, like a commentator might write about politics or defense without having actually served as a Minister or a General. I wasn't attempting to actually diagnose TDD practitioners with mental illness, and I don't have the expertise to do so. I was just drawing a line from the practice of TDD to a certain common form of emotional distress, asking the question if this distress might be in the background of this practice, at least for some practitioners. As I replied to Matt, the answer may well be no - it's a very subjective discussion. But I feel it is valid to raise the question.

    Then there's test coverage, which is rarely if ever mentioned as a metric when we do TDD, because TDD well done produces good coverage, but isn't the point of doing it. TDD is certainly a confidence-building practice, but it is as much an analysis practice (what are we going to do next) and a design practice (refactoring). One objection to calling it testing at all is that the check is written before the code, and conventionally we test the code AFTER we write it. That may be a quibble, as might all of this.


    I didn't attempt to make the argument that TDD is all about code coverage or intended to achieve code coverage. My closing section merely stated that code coverage is important to many people, although it is a very partial measure of real test coverage. I am arguing that the exaggerated emphasis of code coverage could be an influence of TDD. If you're saying that I went on a bit of a tangent from the preceding TDD discussion, point is taken.

    Now it certainly is true that TDD can produce a pleasing "rhythm" of work, but one doesn't have to be OCD to enjoy rhythm. I imagine that TDD might appeal to people who were some combination of afraid their code might not run and OCD, but in all my work with it I've never found anyone who seemed actually to approach it that religiously.


    Some critics of TDD certainly do describe it in these terms. Of course this is completely subjective and could be reflecting their own experience or a limited subset of practitioners.

    A note - I may have gone too far with my title, "Is TDD a form of OCD". Reading inside my article I don't think you'll find a real argument that TDD practitioners suffer from OCD. I was mainly arguing that in the background of TDD there may be a form of Evaluation Anxiety, which is a very common form of emotional distress which most of the population experience at some point.

    All that said, I certainly agree that working together is important and that many forms of confidence-building are used. I don't see the value of imputing anxiety and OCD as reasons why people might use a good practice, or in support of even better practice, the latter being the sole point of value to me in this article.


    We can't dispute that there are many in the industry who believe TDD is not a good practice, or at least, has some negative side-effects. Taking the side of these critics, I tried to investigate what might be the psychological background behind those negative side-effects. I totally respect your disagreement, both with the first point (TDD as a good practice) and the second (side-effects arise from psychological background).

  • Re: TDD is not what you appear to think it is. TDD isn't a form of testing.

    by Gilad David Maayan,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I was going to make the case that TDD is not a testing activity but I see it has been made by a much more authorative source.

    In my opinion, what the author may be describing is the development 'box-ticking' that seems to be replacing thoughtful and deliberate use of good practices. Too often do I hear that there are 'must haves' when developing software which get applied and demanded out of proprtion and context of what is required. Personally for any project of any substantial size I would consider both TDD and BDD approaches.

    There are however no silver bullets.


    Hi Paul,

    I agree that TDD could be in principle an excellent practice, but may sometimes be taken to extremes to the detriment of the software development project. In the article I conjecture what may be the emotional or psychological motivations to take this type of practice to an extreme.

  • Re: TDD is not what you appear to think it is. TDD isn't a form of testing.

    by Paul Kearney,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hi Gilad,

    Is that not a self fulfilling argument? Surely anything you take to extremes is likely to be harmful whether that is TDD, BDD or brushing your teeth!

    A key element of most skills is knowing when and how to apply them. Something done badly is just that. And if a group mandates you do something to an extreme then it is that peer pressure to do something regardless of the value that is the unhealthy element not the practice itself which may or may not be appropriate if done proprtionally. Software development does have its fair share of zealots and KPI driven dev which in my opinion you might be better considering instead.

    I get you are trying to find an empathetic angle here but at the risk of sounding harsh here none of your arguments really stack up for me or chime with my experience. Whilst I appreciate you are trying to be subjective it seems to me you have jumped to a conclusion without the context that would support it.

  • BDD is not what you think either!

    by David Farley,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I agree with Ron Jeffries comments on your understanding of TDD. I am afraid that you, like many others, have misinterpreted BDD as well.

    I was one of the early contributors to the thinking behind BDD. Chris Matts and Dan North did most of the original work in defining and popularising the concepts though.

    BDD was invented as a "better way to teach TDD". There was a group of us who were reasonably expert in the practice of TDD. During the course of our work we spent a fair amount of time introducing the idea to developers and organisations.

    We found that most missed the point, and so missed the real value of TDD. BDD was invented to overcome this problem.

    It has since become more associated with higher-level, more complex, scenario-based testing, which I tend to refer to as "Acceptance Testing". These are useful, even important things, but they don't replace TDD style unit tests.

    BDD as an approach, and technique, is equally applicable to the low-level unit tests of TDD as to the high-level scenarios of Acceptance Testing. You don't need additional tools, like Cucumber or JBehave to practice this form of BDD, regular unit test tools like JUnit or NUnit are fine.

    The important thing is to focus the specification (test) on the desired behaviour of the code from the consumer of that behaviour's perspective. At the unit level, the consumer isn't an end-user, it is another piece of code!

    BDD (TDD) is fractal, it works at multiple levels of resolution, and needs to be applied at multiple levels of resolution to be effective.

    TDD is NOT about testing, it is a design discipline. When practiced well it is my argument that TDD amplifies the skills of a software developer. It makes bad developers a bit less-bad, and great developers a bit more great!

    Dave Farley

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT