Is it advisable to write a test case for every class in your program?
Im am just getting introduced to unit testing and test driven development. Thus far, I have only used Junit as testing framework. A question which emerged and for which I have not yet found a definite answer is: 开发者_Go百科how much test cases do I need to write? Do I have to write a test case for every single class in my program? Or is this a stupid question because unit testing implies testing at the lowest (i.e. class) level?
I think writing a test case for every class is probably the more safe way to go (after all the more you test the lower the number of unforeseen bugs). But I was wondering if there are any widely agreed upon strategies regarding the amount of test cases to write?
If you're trying on TDD, then you shouldn't be writing any code at all without having a failing test that tells you to do so. By implication, then, you'll never have a class that doesn't have one or more tests for it. A rule of thumb that tends to get quoted is that you should end up with about 2.5 times as much test source as main source.
There are no strict rules in this area, only guidelines. You usually have one test case per class, but there are different strategies:
- TestCase Per Class
- TestCase Per Feature
- TestCase Per Method
- TestCase Per User Story
For example you can use 'Per Class' approach for classes that are relatively small and follow SRP. But if you have legacy code with a giant *Manager class it is fine to use 'Per Method' and have dedicated test case for only one of its methods. I think that choosing naming strategy for tests is at least as important as test code organization.
Using code coverage tool can help you find spots of untested code. It is less useful as metric. Having high code coverage does not necessarily mean that you have good tests. At the end of the day what matters is that you have meaningful and readable tests.
I wouldn't recommend a strict mapping of one test per class. Some classes may not have much worth testing on their own. Some classes may require multiple tests because you want to specify different setups for different cases. You should use a code coverage tool like Cobertura and try to cover as much code as possible. Also you should look at the code you're testing and see what kind of different data should break it, and try to test it with different combinations of sample data (so 100% code coverage is not the end of testing, of course).
Though better than 1:1 ratio or over 100% coverage is ideal, in general I tend to abide by "test that which could possibly break".
This means only testing code with 'working parts'. This excludes POJOs, DTOs, thin wrapper/adapter classes and classes that only exist to fit a framework, and so on.
Also, "test only code that is under your control". This generally means not writing explicit tests for generated code—such as Web service clients generated from WSDL (but it still makes sense to cover them as part of tests written for your own classes).
If you're doing TDD and extreme programming, (I think this helps explain it), you program in pairs. The first person writes a test for a feature that doesn't yet exist. The test should prove that the feature is 100% functional and handles all required cases. The second programmer then writes the code that makes the test pass perfectly. It must be rewritten until it completely satisfies the test. Usually you maintain a test suite for TDD which can be rerun constantly, detecting any failures and generating a report - though this is ambitious for personal use.
In any case, for TDD a new feature cannot exist without a new test being made first - the test Drives the Development. So, your test is there for every feature by default if you're doing it right.
I'm not strict as other commenters about writing the test fist and code afterwards. You should do that, but not many people actually do that. The important thing is to write tests ideally before writing code, or right after you wrote the code. But not days/weeks/months/years after that, because you wouldn't do it and the test would suck.
I usually divide application to several parts: application logic, business logic, data access layer, domain objects and helper classes. It is most important to test completely business logic and helper classes. Other parts of application are less important, but you can test some parts. Also do some integration tests.
The most important thing is not to overthink it. Just try to do it on some small project and you will see by yourself.
精彩评论