There are patterns we can identify while working with Test Code and Production Code. For the purpose of this post, we will call as “Production Code” the part of the system that contains the logic of the project and is run in production. We will call as “Test Code” the part of the project that contains the tests which verify if the application (Production Code) work as expected. The existence of those patterns and how they differ according to the context can make us handle Test Code and Production Code differently.
We all know Test-Driven Development is useful, at least for all those who can apply it correctly in the proper context. However, neither TDD or Test-First are essential for writing software. Of course, they increase quality, but they are not essential.
It's possible to test a piece of functionality that internally may execute more than one interconnected "unit". A "unit" can be a module, a function, a class… anything that composes the application. While Production Code represents the composite of several interconnected units where each one of them should know, to some extent, about the existence of other units, a single test doesn't need to know about the existence of other tests.
There are differences between Test Code and Production Code
With integration tests that cover important parts of the system, preferably resulted from the use of TDD, it's safe to refactor the whole Production Code in a Big Bang with a very good confidence that the system will still work as expected. Given all the complexity and entropy that a developer will have to keep in their mind that doesn’t mean it will be easy to refactor, it just means the confidence is high.
However, we can't just refactor all the Test Code and hope for the best. We need to refactor one test at a time, and for every test, we change it's necessary to make sure we understand the intent of what that test is trying to do (that's why sometimes duplication is acceptable). After that, intentionally break the test by changing or commenting the Production Code related to it. We don't have the same confidence when refactoring Test Code as we do when we refactor Production Code. In this case, additional care is a must.
We don't have the same confidence when refactoring Test Code as we do with Production Code, therefore we need to do it one by one with care
When we have a system with good coverage, it's possible to search and replace in Production Code with a low chance of causing bugs. However, we should strongly avoid search and replace in Test Code because there's no way to make sure false positives won't be created.
There are tests that run very fast, like unit tests, and tests that run very slow, like integration tests. Speed is an important factor for either Production Code or Test Code but they are not measured using the same formula. It all comes down to the cost, either the cost of the developer or the cost of user engagement.
Production Code is the final product. Depending on the scale of the project and the part of the system it impacts, 100 milliseconds can have a huge difference in user engagement and reflect on the revenue. For a single user it doesn't matter, but at a scale, the impact can be relevant.
The impact of 100 milliseconds may not be relevant for Test Code. If tests are slow, the feedback cycle to the developer will impact productivity. However, if there are 20 developers, the increase of 100 milliseconds in Test Code execution may not have the same cost as 100 milliseconds in an application serving hundreds of millions of users.
Performance is as important in Production Code as it is in Test Code but most of the time they are not on a par with each other
In Production Code there are cases where it might have value to optimize code size. However, Test Code will never care about it and therefore can serve as a tool to support those tradeoffs
Kent Beck, one of the most famous advocates of TDD, once said:
I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence …
— Kent Beck on StackOverflow
To write software that works we need to test, otherwise, it may not work in the future. Project owners will always assume everything works by default so we need to assume for ourselves that stability is nonnegotiable.
There are differences between Production Code and Test Code. It can be in the form of duplication, refactoring or performance. However, one is not less important than the other.
Test Code is different but still essential.
Create your free account to unlock your custom reading experience.