8

My Classes normally have about 5-20 methods maximum, that implies that the class that has the unit tests has about the double of methods (counting dataProviders, setUp, ...)

I have thought to separate the tests in 2-3 classes, because even if I try to follow the single responsibility principle, I prefer 2 tests classes with 10 methods each, than one with 20.

Is it a bad practice?? Is good to have all the tests for a class in only one, although the test class grows in vertical?

closed as primarily opinion-based by durron597, gnat, GlenH7, user22815, user40980 Apr 5 '15 at 16:08

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    having too many unit tests looks like a symptom of class violating single responsibility principle. Instead of working around symptoms, address the root cause in a class design – gnat Apr 2 '15 at 15:48
  • 1
    possible duplicate of How to determine if class meets single responsibility principle? – gnat Apr 2 '15 at 15:49
  • One advantage to having all your tests in one file is that it helps some IDEs automagically know which tests are associated with which classes based on their names. But at some point, this is not much of a consideration compared to keeping your tests well-organized. – Kevin Apr 3 '15 at 1:23
  • Thanks gnat for your answer, I have updated the question to focus it only about separate the tests. – luisandani Apr 3 '15 at 17:23
16

To answer the specific question, it's absolutely possible that grouping tests into multiple classes is a good decision, event when the class under test is well designed.

Unit test code is like any other code: it should follow good design principles (DRY, GRASP, KISS, SOLID, YAGNI, etc). Because the logic that makes up test code is often simpler than domain logic, a lot of the specific points won't come up as much, but keep them in mind while writing your tests all the same.

There are a couple of principles that come to mind that can easily apply when thinking about your question:

Readability

Ideally, once a test is written, you never have to look at it again; but the same can be said for any code. The reality is that requirements change, so we find ourselves reading code much more than writing it. Even when doing your best, you may find that the test you wrote didn't quite verify what you thought it did, at which point you'll have to go back in and figure out what was wrong. Finding that test method in a class of 40-50 test methods is going to be tough, not to mention the complication of naming those methods so they can be differentiated easily.

High Cohesion

Each test class (like any other class) should have a clear focus. If you have a lot of different test cases for a given method of the class under test, as when a given test verifies a single thing, put those test methods in a separate class and name it to reflect its focus.

  • 3
    Actually, you might want to look at a test even if no requirements change – just to understand how the tested class is meant to be used, for example. – Paŭlo Ebermann Apr 2 '15 at 19:00
7

It is almost of no importance how your unit tests are organized compared to having them in the first place.

A module or class of business code is something you have to understand as a unit and develop further. That's the main reason we strive to make it coherent, easy to grasp as a whole, etc. A test suite is only a collection of cases that must all pass; the don't have any particular relationship to each other. Ideally, you'll never have to deal with it again; if you do it's usually to add more tests that again have no particular relationship to any other test, and they're never called by client code except the unit test framework.

Therefore, the question of how to organize the classes containing unit tests is much less critical than how to organize the classes that make up your application itself. You're not supposed to deal with them as a well-architected macrostructure anyway.

  • While I think you're generally correct, there are few things worse than buggy, fragile, unclear, and hard to follow tests. Spaghetti test code isn't great. – Paul Draper Apr 3 '15 at 2:35
3

Put the tests in one file. Typically for every class file I would have a test file. Usually append "Tests" to the file name.

For example, if there is a class called "Foo" there would be a corresponding "FooTests" file. This way for every code file there is a 1 to 1 relationship between code file and the test file.

This provides consistency and makes it easier for developers to locate the tests and keep them up to date. Tests are usually excluded from code analysis/metrics so if the file is big, it doesn't hurt the overall code health metric, so I don't consider it bad form to have a test file with lots of unit test code.

3

If we say that definition of bad practice in software development is anything that doesn't help you cope with and encapsulate change then I would say not keeping your classes and tests in one to one relationship is bad practice. It is a code smell that might arise because of the things mentioned below.

Obviously there are exceptions just like with anything but just keep that in mind as you are writing your tests.

My Classes normally have about 5-20 methods maximum.

If any of your classes have 20 (or a little less) methods that kind of shows me that the class is doing too much in the first place. This is where unit testing should hint you that you might need to break down your class a little more and distribute the responsibility before going about testing.

As for keeping them in the same class or not I would suggest trying to keep them in one class if possible because it is better understandable - one to one connection is easy to grasp after a lot of time has passed. Just from experience.

If you see that the unit tests are huge even when you have 5 methods or less then that tells me that your setup code is doing too much or your objects are abnormally big.

If you haven't tried already check out the builder pattern for building your objects - this could cut down code drastically on how you are building your objects before testing them. Therefore making the unit test class shorter and less need for you to cut it down into more classes.

  • This is excellent advice, but is not an answer to the question. (Still upvoted) – Jon Raynor Apr 2 '15 at 15:59
  • @JonRaynor thank you! I just updated my answer with a conclusion, specifically answering the question. – AvetisG Apr 2 '15 at 16:07
  • Could you please elaborate on the downvote? – AvetisG Apr 2 '15 at 16:22
  • 1
    @AvetisG: People don't have to elaborate on their downvotes and it's unfair to ask them to. But I'll try to help you ... Only the first paragraph here even attempts to answer the question. The rest is an opinion, which some people wouldn't share. I, personally, agree with your opinion but I don't agree with the one paragraph that's relevant to the question, and I don't see the connection you're making. Mike's answer is correct: "Each test class (like any other class) should have a clear focus." That may or may not be the same focus as for your classes under test. – pdr Apr 2 '15 at 17:30
  • @pdr that makes sense. Thanks for expanding on that. – AvetisG Apr 2 '15 at 17:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.