Test-Driven Development

Test-Driven Development

The “eXtreme Programming” methodology promotes the test-driven development approach (TDD). What that means?

It is common to see a developer jump headfirst into a functionality. However, TDD advises otherwise.

Short blanket syndrome

You might be wondering “I don’t see what is wrong with that approach”. Let me ask you this question – have you ever implemented/updated/fixed a functionality and by some black-magic, other “way off” functionality broke? I call this the short blanket syndrome. When trying to cover one spot, another is uncovered.

test-driven development diagramXP advises to develop in repetitive short cycles. The developer should write a test and execute the program. The test will fail, we don’t even have any real code to run. Time to write some code, but just enough for the test to pass. If green light occurs, the developer should revisit the running code and refactor if needed.

Write a test, fail. Write code, pass. Refactor.This cycle will continue on and on.

There are many possible tests – unit, integration, functional, acceptance. All of them, as we will find out, are extremely important in the software life cycle.

Unit Tests

This type of testing, as the name implies, should evaluate the smallest unit of code. It should test, typically, every public method and with no interaction with the rest of the system. Basically we will be evaluating the input and output of data to every method. If, in a future update, a developer write some code that will change the necessary input data or the type of output, the test should fail and let the developer know that it may break the entire logic.

It is quite common to find developers using the, so called, “code-driven tests”. That is the same to say that a developer will write the running code and afterwards will write the adapted test.  This inverse process will make your code base really difficult to test, and it is wrong.

When these tests are well written, they may be used as documentation. And this is really interesting.

How many unit tests should a code base have? Well, Robert “Uncle Bob” Martin use to say that 100% of the code base should be covered by tests !!!

Integration Tests

After unit testing, where the small units of code were tested, is time to integrate all the pieces. There are several approaches to this sort of testing – “big-bang”, “top-down”, “bottom-up”, “mixed” and “risky-hardest”. I will let the explanation for those for future posts. However, and if with unit tests one should cover 100% of the code base, integration tests deserves a more concise reflexion. J.B.Rainsberger explains in this talk that we may be creating a small monster. I advise you to watch that presentation (or at least read the article).

Functional Tests

Functional testing belongs to the Quality Assurance (QA) process. Like the name implies, in a functional test we will test a functionality against some specific requirements. The internal process isn’t important, that is why this sort of testing is called a “black-box” test.

Acceptance Tests

We might consider acceptance tests as the last stop before the release. We will write user stories, with the client help, and the test should mimic that story. Let me show you an example:

  • user will access the login screen
  • user will input authentication data (user: admin, pass: password)
  • user will be redirected to screen X

Basically, we will test several possible scenarios, emulating real users. Like I say previously, this is the last phase before the release, therefore QA team and client should be working really close.

Mutation Tests

This sort of testing takes the approach of modifying small pieces (mutations) of your code base. Those mutations should be detected and resolved by your testing suite that would be running in each commit. As you may think, this testing typology is primarily to test your test suite and to help design new tests.

The example provided by Wikipedia, transpilled to PHP:

The mutation might be just transforming the logical condition && to the condition ||.

For PHP we can refer to the Infection framework, and for JavaScript we might choose the Stryker framework.
Following another XP best practice, the entire code base should be continuous integrated, so all these tests must be automated. Worry not, I’m writing another post about this subject.

Have I convinced you that writing code with tests are really beneficial ? Let me know your opinion.

Leave a Reply

Your email address will not be published. Required fields are marked *