The typical testing tool pays for itself after one or two projects by either increasing the number of tests that can be run with a given budget or reducing the cost to achieve a reliability goal. Reduction of testing due to schedule slippage is a frequent problem. The fact that it happens does not mean that testing is unwise. This kind of schedule compression can usually be avoided by starting test activities earlier in the project. We don't need to use any information about the implementation to select these tests and their test inputs.
Effective testing is guided by information about likely sources of error.
The combination of polymorphism, inheritance, and encapsulation are unique to object-oriented languages, presenting opportunities for error that do not exist in conventional languages. Our testing strategy should help us look for these new kinds of errors and offer criteria to help decide when we've done enough looking. Conventional testing is useless for objects. Objects are so different, everything we know about conventional testing is useless. Conventional testing doesn't deal with state and collaborations.