Code coverage tells you how much of your code is covered by tests. It does not tell you much about the quality of the tests.
For example, a code coverage of, say, 70% might be obtained by automated tests exercising trivial functionality like getters and setters and leaving out more important things like verifying that some complex computation delivers correct results, corner cases, and so on. Even if you have 100% code coverage, your tests might not consider special inputs to your code that cause it to fail.
So, a relatively high code coverage does not necessarily imply that the code is well tested and therefore important defects may still not be detected by the tests.
On the other hand, a low code coverage means that a lot of the code is not tested at all, so it can be that some important modules are not properly verified. Sometimes it makes sense to have a relatively low code coverage for automated tests, e.g. it can be more effective to click on a GUI button and verify that the appropriate dialog opens (manual test) than to write a corresponding automated tests. Nevertheless, even in this scenario the combined coverage for automated and manual tests would be high.
So, IMO code coverage alone is not a good indicator of the quality of your tests because it only works in one direction:
- a low code-coverage score can correctly point out code that is not tested, and may be buggy or even dead code;
- a high code-coverage score can hide poor testing and can give you too much confidence in the quality of your code.
NOTE
Thanks to gnat for pointing me at code coverage for manual tests.