If you’ve been exposed to automated testing it has probably been with unit tests. Unit tests are the most common type of automated test, and sometimes the types listed below are called unit tests. For me it is easier to classify each type of test to have a better idea of the tools to use and to determine the goals of the test. A lot of my experience has been with acceptance tests and unit tests. Unit tests are essential to having quality code. However, along with unit tests the following test types represent a complete package of testing that can help you develop high quality code.
Component tests: should test a collection of classes that make a working component. For example, let’s say you have a component of your code that calculates how much tax to take out of a paycheck. You likely need several classes to help make this calculation. You would write a component test to make sure those calculations are being handled correctly.
Integration tests: would validate multiple components working together. Using our previous example you would write tests against all the components that are used to calculate a paycheck. This would include tax components and benefit components. These tests also could be running against a web service layer to test that the web service returns the right values.
Acceptance tests: are testing the way your users will run the application. In a web based scenario you can use tools like Selenium to run the browser and click through the application. For windows applications you can use coded UI tests available in Visual Studio. These tests are mainly concerned about the GUI, and can be volatile because the GUI changes so much. Depending on the tool you use there are ways to make them less volatile and more reliable. One way is to rely more on the IDs of elements in your html instead of relying on element types. IDs tend to be more consistent even with drastic UI changes.
Manual tests: should be reserved for items that are difficult to automate. Some tasks are just not suite well for automation. Sometimes the testing tools have trouble with certain scenarios, and that is fine. If you find yourself spending more than a day to automate a test you probably shouldn’t be writing that test. Certain features need human interaction. Manual testing should be a small part of your testing effort though. Test scripts are for machines, not people. Let your QA person try to break the application, and have fun with some of the complex scenarios. Giving them a boring list of buttons to click is not fun. Either automate tests that QA writes up, or help QA write their own automated tests.
It seems like having tests at each of these layers is redundant, and to a certain extent that is correct. If your component tests fail there likely will be a ripple effect with tests higher up failing. What this buys you (in addition to more confidence in the software) is the ability to pinpoint a problem. If all your component tests pass for the tax calculation feature, but the integration tests fail then you know the problem is some interaction between the components. This gives you a huge advantage when trying to debug problems in the system. A full suite of automated tests will give you peace of mind as you make changes, and give your customer new releases without stress.