A New Perspective on TDD: Enhancing Team Dynamics
Written on
Understanding the Test Definition That Impedes Teams
It may sound absurd, but there exists a definition of testing that diminishes code quality and creates anxiety among developers.
I vividly recall my initial introduction to Test-Driven Development (TDD) and Extreme Programming (XP). They were presented as practices that fostered happiness among programmers. At a meetup, the speaker showcased images of joyful coders, laughing and enjoying their work. At the time, I struggled to grasp the message.
Years passed before I fully understood that presentation; my biases and misconceptions had held me back. I believed that software development was inherently challenging—an endeavor that could be enjoyable only with the right colleagues. I failed to recognize the stressors as I do now. For me, experiencing roadblocks or needing to refactor—what I now refer to as a rewrite—was just part of the job. I could not have been more mistaken.
In reality, TDD enables developers to maintain momentum, prevents roadblocks, and generates enjoyment through the continuous passing of tests, which stimulates dopamine production. However, there is a crucial catch.
TDD begins with writing a test, specifically a unit test. This is where the complication arises. There are two types of unit tests: QA unit tests and TDD unit tests. Understanding this distinction was challenging for me, as well as confronting the implications.
QA unit tests focus on individual units of code. The premise is that a single failure indicates a problem in one specific piece of code, making it straightforward to identify faulty code. This approach feels robust until we consider its drawbacks. First, in TDD, the code does not exist prior to the test, rendering the notion of testing existing code nonsensical. Second, it necessitates extensive use of mocks, which offer little insight into system behavior and fail to safeguard against refactoring. Third, QA unit tests are tightly coupled with the code; a change in the code requires a corresponding change in the test, hindering the ability to modify behavior without risking test validity.
On the other hand, TDD unit tests center on specific behaviors. A failure indicates a problematic scenario, and since we are employing TDD, it also implies that the last modification was flawed, allowing the programmer to rectify it and try anew. Because these tests focus on behaviors rather than code, they remain decoupled from the code itself, avoid mocks, and facilitate safe refactoring.
I recognized this difference several years ago, marking a pivotal moment between having effective tests and ineffective ones. My revelation stemmed from a desire to find meaning in testing; however, many programmers view testing merely as a requirement to demonstrate quality or to boast. Lacking motivation to advance their practices and unaware of TDD's benefits, they often lean towards the QA definition. These tests may be simpler to construct and more aligned with traditional development, yet they are ultimately ineffective.
Several years back, my team conducted an experiment. For a few months, half of us adhered to the TDD definition while the other half followed the QA definition. Six months later, we discovered that only the TDD approach yielded valuable results. The disparity was so significant that I felt compelled to share our findings, leading me to write my first article on Medium. Consequently, my team abandoned the QA definition in favor of TDD. But what about the other teams?
Years later, two teams had embraced the TDD definition while the remaining teams continued with QA. I am unsure why the others resisted change. They cited the need to maintain delivery speed as justification for their low-quality code, but that reasoning was flawed. Over time, the code produced by the QA teams became increasingly difficult to maintain, resulting in multiple rewrites of certain components. Programmers became apprehensive about making changes, and turnover rates soared, with many new hires leaving within a few months.
What I failed to comprehend nearly a decade ago is now abundantly clear. It’s not that TDD and its associated unit tests create a cheerful atmosphere for developers; rather, they foster a professional environment. With TDD, programmers can function as professionals. In contrast, the QA definition reduces them to fearful, inefficient workers, ultimately dismantling team cohesion.
The first video, titled "S1.E4: Handling risk as a team with risk-storming | QA Therapy Podcast," discusses the importance of effective risk management within teams, highlighting strategies to enhance collaboration and reduce anxiety in the coding process.
The second video, "A/B Testing by Yammer (Microsoft) Product Manager," delves into the significance of A/B testing in software development, showcasing how it can lead to better decision-making and improved product quality.