How To Deal With Test And Production Code

Written by fagnerbrack | Published 2016/04/05
Tech Story Tags: software-development | programming | tdd | software-engineering | software-testing

TLDRvia the TL;DR App

Test Code and Production Code are different and maybe they require a separate development approach for each context

The picture of a yellow lemon surrounded by a bunch of green limes. It definitely stands out as something different.

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

Still on the subject of performance, if we are developing JavaScript applications for the web and depending on the scale of the project, every byte in Production Code that the user downloads matter. However, in Test Code, code size is totally irrelevant because most of the time it will run locally in the developer machine or the CI.

There are people who make some tradeoffs to spare bytes in JavaScript code and compensate that with tests. Sometimes it makes sense to duplicate functionality in Production Code to account for the way the GZIP algorithm handle multiple occurrences of characters, for that it might compress into a smaller file or a bigger one depending on how it's done. Sometimes it makes sense to apply techniques that reduce the legibility of the code but in contrast will help to reduce the code size.

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.

Thanks for reading. If you have some feedback, reach out to me on Twitter, Facebook or Github.


Published by HackerNoon on 2016/04/05