The red-green-refactor process

The red-green-refactor process is the most important part of TDD. It is the main pillar, without which no other aspect of TDD will work.

The name comes from the states our code is within the cycle. When in red state, code does not work; when in the green state, everything is working as expected, but not necessarily in the best possible way. Refactor is the phase when we know that features are well covered with tests and thus gives us the confidence to change it and make it better.

Write a test

Every new feature starts with a test. The main objective of this test is to focus on requirements and code design before writing the code. A test is a form of an executable documentation and can be used later on to get an understanding of what the code does or what are the intentions behind it.

At this point, we are in the red state since the execution of tests fails. There is a discrepancy between what tests expect from the code and what the implementation code actually does. To be more specific, there is no code that fulfils the expectation of the last test; we did not write it yet. It is possible that at this stage all the tests are actually passing, but that's the sign of a problem.

Run all the tests and confirm that the last one is failing

Confirming that the last test is failing, confirms that the test would not, mistakenly, pass without the introduction of a new code. If the test is passing, then the feature already exists or the test is producing a false positive. If that's the case and the test actually always passes independently of implementation, it is, in itself, worthless and should be removed.

A test must not only fail, but must fail for the expected reason.

In this phase, we are still in the red stage. Tests were run and the last one failed.

Write the implementation code

The purpose of this phase is to write code that will make the last test pass. Do not try to make it perfect, nor try to spend too much time with it. If it's not well written or is not optimum, that is still okay. It'll become better later on. What we're really trying to do is to create a safety net in the form of tests that are confirmed to pass. Do not try to introduce any functionality that was not described in the last test. To do that, we are required to go back to the first step and start with a new test. However, we should not write new tests until all the existing ones are passing.

In this phase, we are still in the red stage. While the code that was written would probably pass all the tests, that assumption is not yet confirmed.

Run all the tests

It is very important that all the tests are run and not only the last test that was written. The code that we just wrote might have made the last test pass while breaking something else. Running all the tests confirms not only that the implementation of the last test is correct, but also that it did not break the integrity of the application as a whole. This slow execution of the whole test suite is a sign of poorly written tests or having too much coupling in the code. Coupling prevents the easy isolation of external dependencies; thus, increasing the time required for the execution of tests.

In this phase, we are in the green state. All the tests are passing and the application behaves as we expect it to behave.

Refactor

While all the previous steps are mandatory, this one is optional. Even though refactoring is rarely done at the end of each cycle, sooner or later it will be desired, if not mandatory. Not every implementation of a test requires refactoring. There is no rule that tells you when to refactor and when not to. The best time is as soon as one gets a feeling that the code can be rewritten in a better or more optimum way.

What constitutes a candidate for refactoring? This is a hard question to answer since it can have many answers: it's hard to understand code, the illogical location of a piece of code, duplication, names that do not clearly state a purpose, long methods, classes that do too many things, and so on. The list can go on and on. No matter what the reasons are, the most important rule is that refactoring cannot change any existing functionality.

Repeat

Once all the steps (with refactor being optional) are finished, we repeat them. At first glance, the whole process might seem too long or too complicated, but it is not. Experienced TDD practitioners write one to ten lines of code before switching to the next step. The whole cycle should last anything between a couple of seconds and no more than a few minutes. If it takes more than that, the scope of a test is too big and should be split into smaller chunks. Be fast, fail fast, correct, and repeat.

With this knowledge in mind, let us go through the requirements of the application we're about to develop using the red-green-refactor process.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.158.32