chris01
chris01

Reputation: 12321

JUnit: best strategy for placing test-methods

I started a project and using JUnit for the 1st time.

Whats the best practice of putting testcases?

As far I see I can technically do every 3 ways but I do not have experience in that so I ask for some guidance to do it right from the very beginning.

EDIT

I am talking about code unit testing. I am using maven too but I think that is not important for my question.

Upvotes: 1

Views: 384

Answers (4)

Gray
Gray

Reputation: 116858

1 test class for every "real" class.

I typically go with this pattern. Of course, tests for interfaces don't make much sense and there are times when small "entity" classes with getter and setter methods only (i.e. no logic) don't need a corresponding test class.

That said, I've been surprised at what utility I've found in unit tests even on very small classes. For example, even entity classes with only get/set methods which are stored in databases through DAO methods should be tested in case some of the database wiring is incorrect. You never know when you have a mismatched get/set method or if the toString(), asymmetric hashcode() or equals(), or other issues.

The entire point of "unit" tests is (IMHO) to test the smallest unit of your code in isolation -- this is the class. So therefore when I have a ContainerUtil class, I look for a corresponding ContainerUtilTest class in the test directory. I run coverage tests often and I expect just about any logic portions of all classes to be covered.

1 test class for every package or even the complete project.

I might have this as well but then I'd consider these to be "integration" tests. Tests that bridge between classes or between various parts of the project to ensure that your project works as a whole.

But these would be in addition to your unit tests.

Test methods in the "real" class without a test class.

Yeah, no. Really bad idea. You don't want your production code to include test code if at all possible. It decreases the readability of your classes, increases the change that you break something while trying to test, etc.. Just say no.

I also keep my test classes away from my sources. I usually use maven so I have my sources in src/main/java and my tests in src/test/java. You don't want your tests to end up in the jar or war files where they might confuse others.

Upvotes: 3

gdfbarbosa
gdfbarbosa

Reputation: 835

I would suggest you try the first approach. It is very useful because you can track using some tool as Sonar the percentage of coverage from your unit tests.

Also, I strongly recommend you apply TDD to develop your code: first you write your test code to fail, then you write code to make your test pass and then you refactor.

Allow me to suggest two sources of reading to help you with that:

These are the same reading resources I used to start building tests and using TDD.

I woudn't recommend you to use the other approaches, as you don't need to ship test code to production and using a single test class would cause a code smell known as "Large Class".

Upvotes: 1

Christian H. Kuhn
Christian H. Kuhn

Reputation: 355

For unit testing, i so far have used one test class for each tested class. FOR ME, it seemed to be the least messy order. I put the unit tests under src/test/java in the same package tree as the tested classes in src/main/java. Integration tests are different and have their own files each.

One testclass has different disadvantages. Source code will become unreadable. You will do a lot of unnecessary work in @Before and @BeforeEach methods.

And i don’t get the point of putting tests into the tested class. Lots of imports, and how would you differ between „real“ and test methods? And because of the additional methods, source code will become unreadable.

Upvotes: 1

Alexis
Alexis

Reputation: 463

It really depends on how big your project is, but in my experience the best approach would be one test class for every "big" functionality (this may not apply for unit testing), or in this case, for every "real" class.

About the other 2:

1 testclass for every package or even the complete project.

This may grow to big and messy, wouldn't recommend mixing different things in the same test class, the same way that you wouldn't mix classes within the same file

Testmethods in the "real" class without a testclass.

I do not recommend this one either as you lose track of where are the tests and which things have tests implemented vs are missing. Also, your code may require accessing other classes as well, so this may become a mess as again.

Upvotes: 1

Related Questions