In the field of testing, there are many ideas and movements, some of which have formed into schools. But there is really no universally accepted standard for what testing is and how it should be performed.

The attempts to establish such a standard (such as the infamous ISO 29119) are met with either ice-cold indifference or hell-hot opposition. Why? Well, because professional developers want to be able to choose approaches and tools that fit particular projects, time frames, budgets and business goals, and deep down they know they will continue to do what’s best to perform their duties well.

Test-driven development (TDD) and automation debates
In this context, I am no longer surprised articles claiming that “TDD is dead” are published all the time. The word “automation” also provokes intense reactions from both extremes; Continuous Deployment still encourages everyone to automate, while the context-driven testing aficionados claim it dehumanizes the process. I believe this happens because there is no real understanding of what testing (not to mention TDD) stands for.

According to a popular misconception, the term TDD is only associated with testing (unit or integration). Not everything should be taken at face value, however. First and foremost, TDD is about quality—quality of design and code. TDD means writing good code. But what does “good” code even mean? The question is a contention point for generations of programmers, with such metrics as spaces vs. tabs, brace positions, line lengths, as coupling, dependency matrixes, and more used to decide whether a piece of code is “good” or not (or if it’s at least “better” than the previous version).

In my opinion, code can be called “good” when it’s easy to read and understand. After all, we are writing code to be read by humans, not for computers or compilers.

However, there are several factors that can make code better:

1. Modularity, independence, single responsibility principle. Modular code is easy to test. Coupling is your enemy. Far too many people don’t want to test, since they don’t understand the value of testing.

Writing first, testing later is time- and effort-consuming. If the system is interconnected, it’s hard to check whether the individual parts work properly. Writing modular code by dividing functionality into independent and interchangeable modules, responsible for one aspect of functionality, helps to test those parts of the system without integrating everything together. This allows developers to avoid regression risks and enhance transparency for the client since, in test suites, results are apparent, not implied or described only in documentation. Modules are also great since they are self-sufficient and can be used in another product or exchanged for another module.