At Fusion, we take testing seriously.
In this post, we’ll discuss Test-Drive Development (TDD) and Continuous Integration (CI), two of the techniques practiced by our technology team.
Both share the same basic principle — we want to deploy a bug-free application as fast and as smoothly as possible. TDD means we have a growing suite of test coverage for the important parts of our code. CI runs these tests against each commit, so we can be confident in the code we ship.
Why practice Test Driven Development?
As projects mature and teams grow, codebases naturally get bigger and more complicated. Tests are an investment in the future. They help prevent accidental breakage, and allow refactoring with ease. One might argue that practicing TDD is slow and reduces productivity – but if you find yourself in that situation, consider this question:
“Have you ever been significantly slowed down by bad code?”
TDD works when everyone in a team is mindful about its practice.
The TDD loop goes something like this:
- The developer writes a test and runs it.
- The test fails and the build goes red.
- The developer writes code to fix the test and repeats it.
- The test passes and the build goes green.
- The developer refactors as needed and runs the test again.
If refactoring is required, tests are the safety net to catch breakage before any surprises occur in production. The process is repeated until a feature is finished, and ready to be merged into the production branch. Before that happens, a Continuous Integration server (Travis, in our case) runs the same suite of tests against the codebase in an environment as similar to production as possible to check for any coverage gaps.
How do we write tests for WordPress?
Ideally, you want to test each and every piece of your codebase. Developers should think twice before saying that a chunk of code can’t be tested. And now that the WordPress development suite comes with
WP_UnitTestCase to make testing for themes and plugins easier, you don’t have much excuse to ignore testing.
Need some inspiration? Check out this real world example.
The Fusion tech team was given a user requirement like this:
As a user, I want to see a banner for every post that has the ‘tdd’ tag associated with the post, so that the editor doesn’t have to manually add the banner to each ‘tdd’ post.
We started by writing this test:
This test failed when we first ran it. So, to make the test pass, we added the
After adding that function, our test passed when we ran the suite.
The next step was adding a test for the filter that would insert the banner:
This test also failed when we ran it. So, we refactored our code to include:
With that addition, we had test coverage around the two fundamental components of our requirement: checking whether the post had the ‘tag’ tag associated with it, and making sure that when that first condition was true, the banner got appended to the post body.
But what if checking string values isn’t enough?
Glad you asked!
You can also test a filter like this against HTML output. We use QueryPath to achieve the desired result.
After you have tests to cover all the necessary test cases, you can refactor code more freely and confidently.
Next time you feel obligated to write code and then immediately refresh your browser to check it, I’d advise you to write a test first. It’s much easier.
Next time, on Next…
If this topic appeals to you, and you’d like to help us use technology to solve some of the biggest problems in digital media, why not check out our available positions? We’re ramping up to expand the Fusion technology team significantly in 2015.