The What, When, Why, and How of Testing
Tags: go, testing
Published: 2022-12-11 23:00:36

(Authors Note: The following is an extract from the Advanced Unit Testing Techniques chapter of my upcoming book: [Beyond Effective Go - Part 2 - Striving for High-Quality Code](https://github.com/corsc/Beyond-Effective-Go#section-2-striving-for-high-quality-code))

When it comes to testing, the most common misunderstanding is the motivations of testing itself. Some folks see testing as a burden imposed from on high. Some folks see testing, or more specifically, test coverage, as a metric that determines how well they did their job. Sorry, but neither of these is true.

This series of posts will address these fallacies and give you a different perspective on testing.

## Why do we test?
We write tests to enable us to work faster and more effectively. It seems backward to claim that writing more code can make us go faster but bear with me.

We write code to add behavior to a system; to prove that behavior has been added, we have to test. We could run a quick manual test; this wouldn't cost us much, and doing so would be immediately valuable. However, this value is short-lived. Once we make additional changes to the code, we can only be 100% sure that our desired behavior exists with more manual testing. 

Contrast this with automated tests. It may initially cost a little more than manually testing to write, but they continue to provide value for as long as they exist. We can and should run these tests constantly as they provide a little value every time we do.

Because these tests continuously ensure that the system has the desired behavior, we don't need to waste time going back and manually re-test, nor do we run the risk of regression without noticing. 

Automated tests become a safety net that reduces the risk of any additions or refactoring that we may make. Consequently, they also reduce any fear we might have relating to unknown or complex code.

With sufficient tests in place, our confidence in the code increases to a point where we can make more frequent, faster, and even more adventurous changes, given that the tests will prevent any mistakes.

And finally, automated tests document the author's intent for the code and are an efficient way for newcomers to learn why a piece of code exists and its behavior. This, in turn, improves the time it takes for newcomers to onboard to the project and reduces the cost to existing developers to explain the code to them.

## When do we test?
Our industry has spent a lot of energy debating this point, and we have not found the correct answer. As long as you are testing, it doesn't matter if you write the tests before the code or after. 
That said, I recommend grabbing a copy of _Test Driven Development: By Example_ by Kent Beck. The book's ideas are relevant to all forms of testing, and mastering them will make your tests more efficient and effective. While, most of the time, I do not do Test-Driven Development (TDD), you will find many of the intentions, approaches, and tricks I present compatible with Kent's ideas.

Stay tuned for the upcoming parts of this topic, where we will explore _How much should we test? What should we be testing? And What should we not be testing?_