Testing was considered, (and still is considered in some companies), the last stage of software development, developers would hope that they will build from scratch their applications without errors, so the testing phase would be just a formality where only minor errors would be expected, thankfully we are moving from that utopian parading to a new concept where testing is an integrated part in the development process. What follows is a few “best practices” to take the most from this new test paradigm.
1.- Test code is as important as production code.
One of the most common reasons to fail for teams starting TDD is that their test code is not clean, so it will eventually cost more to maintain the tests than the actual production code, to avoid this scenario, it is important to keep in mind that having clean test code is as important as having clean production code.
Reuse fixtures. If you need some data to be available for different tests, make it reusable and make it available in a single place.
Write you own asserts. If you are testing some data in 5 different scenarios, and to prove that everything works fine for each of the scenarios you need 5 different asserts, write your own assert that performs those other 5 ones and call it from your code instead of writing 25 different asserts.
In general, use the same principles you apply to write good production code: In this other post you can find some more directions to write good code: 10 commandments for creating good code.
For further reference, I highly recommend you to read the following book: xUnit Test Patterns: Refactoring Test Code
2.- Test as much as possible, test as soon as possible, test as often as possible.
As I said on my previous post, I am a convinced TDD developer, but maybe you are not, what is important is that no matter if you write the test before or after, you don’t go forward with new code until you have a test that proves that the code you just implemented works as expected. This attitude of testing as much as possible, as soon as possible and as often as possible will prevent you from entering new bugs into the system, and for this reason it will also make you more confident and productive.
3.- Test at different levels.
Don’t try to cover your application with tests that only cover both the UI and the backend, they take too long to write, are hard to maintain and slow to execute, it is also very difficult to test all the different elements of your application if you don’t separate them, the best approach is to test at different levels. Consider having at least the following set of tests:
Unit tests. Tests that check all your components by themselves, without taking into consideration their interaction with other components.
Integration tests. These tests are not identified by the product owner in his/her acceptance tests but are developed either by QA or development to compliment them.
UI Tests. UI testing is slow, also the UI is likely to be changing during development and so do its respective tests, by keeping the UI tests separated from the backend tests we won’t be affecting them every time the UI changes.
4.- Testing as an integrated part of the development process. Continuous integration
Testing has to be an integrated part of the development process, something is not done until is tested, forget about having a different stage where someone else takes care about the testing, everyone is responsible and accountable for testing, from development to QA to the product owner. Ideally you will also apply continuous integration, which goes further of the testing scope, for more information on continuous integration check this excellent article from Martin Fowler.
5.- Use testing tools and frameworks.
Luckily there is a set of tools and frameworks developed lately to help us testing our applications, a selection of these tools are:
Fitnesse. A tool to create acceptance tests, non technical people can write their own test cases.
xUnit. Framework to develop unit tests, integrated with the most popular IDEs and programming languages.
CodeCover. A code coverage plugin for Eclipse, useful to know what parts of the code we are testing, and what parts we are not.
Jira. A reporting and tracking tool, mostly use to track bugs.
Mercury. Popular testing suite, includes different tools for different types of testing, including UI testing.
Selenium. UI testing tool for browser applications.
Hudson. Continuous integration tool, used to ensure that the code is always ready to build and that it passes all the different tests.