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

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

BT