Test automation—especially, when it is applied (as usual default) as regression test automation—suffers from static test data. Without variation in the data or execution path, bugs are located with decreasing frequency. The paradox is that the reduction in bugs that are found per test pass is not representative of the total number of bugs that remain in the system. Bugs are only less common on the well-exercised code paths that are represented by the static data. Bugs that remain in untested areas of the application are resistant to the testing methods (the automation pesticide paradox).
The lack of variation sometimes can improve the stability of the test code somewhat, but at the detriment of good test coverage. Effectiveness of testing—as measured in the detection of new bugs—is improved significantly by the addition of variation, each test pass using different values of data within the same equivalence class. Automation should be designed so that a test-case writer can provide a common equivalence class or data type as a parameter, and the automation framework will vary the data randomly within that class and apply it for each test run. (The automation framework should record the seed values or actual data that was used, to allow reruns and retesting with the same data for debugging purposes.)
In some cases, working with dynamically selected input data can be problematic because determining the expected outcome might be difficult (the Oracle problem). However, in many cases, there are tests that can be selected and verified automatically, even without requiring sophisticated approaches to determine the correct test output for a particular input.
Test-automation strategies too often are based solely on the automation of regression tests, putting all of the eggs in that basket alone. This is analogous to buying insurance to protect against failures that are due to regression: It is expensive, and it mitigates failures in the areas that the insurance (automation) covers, but it does not reduce or prevent the problem in uninsured (unautomated) portions of the application. Wise insurance-purchasing strategies usually are based on the selection of the optimum amount, and not on the spending of all available resources on a gold-plated, zero-deductible insurance policy. In testing terms, some teams spend too much time on automation—at the expense of lost mindshare that could be dedicated to other types of testing, and putting their projects at increased risk of detecting only a small portion of the real problems.
The cost/benefit ratio of test automation can be tilted in a positive direction by concentrating on adding stability to development processes, identifying sources of regression failures, and fixing them systematically. When pursued with vigor, it soon becomes inappropriate to over-invest in a regression test-automation strategy, and much more important to invest in other more leveraged forms of test automation. Otherwise, the dominant problem changes quickly from creating tests to find bugs to trying to manage and maintain myriad redundant, overlapping, obsolete, or incorrect regression test cases.
A regression-focused approach can result in automated tests that are too static. The cost/benefit ratio is marginal for these tests, when all of the maintenance and management costs are taken into account; they do not find many bugs. If test systems are designed to challenge dynamically the full range of data-dependent failures, alternate invocation modes, and number iterations, they can accomplish much more than regression testing.
By increasing the abstraction of test automation to "find all strings on the form and test them with all generic tests (apply random data variations until an error occurs or 100,000 conditions are tried)" and running the tests continually, testing is elevated from a marginally valuable static regression suite to a generic tool that has a much higher probability of adding value to the project. (This has the added benefit of providing technical opportunities for extending Software Test Engineers, instead of just chaining them to a desk to maintain legacy automation.)
The other benefit of higher-level abstraction and making tests more generic is efficiency; adding test cases should be simple and quick, and not require hours of custom test-case coding of minutiae. Having test automation designed at the level of "test this control()"—instead of 50 lines of "click here, type this, wait for this window"—empowers a broad range of testers to automate tests and focus efforts on planning meaningful tests, instead of having to slog through the implementation details of simplistic scenarios that are coded against poorly abstracted test frameworks.