views:

199

answers:

5

When building a suite of unit tests for Java code, is there a convention for where to place test code in relation to source code?

For example, if I have a directory /java that contains a bunch of .java source files, is it better to put the test cases in /java itself or use something like /java/test.

If the latter is preferred, how do you test the internals of the code when the private /protected members of a class aren't available outside the package?

+12  A: 

You can put the tests in the same package as the original classes, even if the source code is under its own directory root:

PROJECT_ROOT
    +--- src/
    +----test/

You can declare a class com.foo.MyClass under src and its test com.foo.MyClassTest under test.

As for access to private members, you can use reflection to invoke the methods (altering their accessibility via Class.getDeclaredMethod.setAccessible), or you could use something like testng/junit5 to put some annotation-driven tests on the source code itself (I personally think this is a bad idea).

Why not check out some projects on java.net to see how they've organized things, for example swinglabs (the SVN repository is pretty slow I'm afraid)?

oxbow_lakes
+2  A: 

Most of the times is done like this:

<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java

So, you keep them separated and you can still test the package/protected functionality because the test is in the same package.

You can't test private stuff, unless it is declared inside the class it self.

Upon delivery, you just pack the .class generated by src, not the tests

OscarRyz
+10  A: 

I recommend following the Apache Software Foundation's standard directory structure, which yields this:

module/
  src/
    main/
      java/
    test/
      java/

This keeps tests separate from source, but at the same level in the directory structure. If you read through how Apache defines their structure, you'll see it helps partition other concerns out as well, including resources, config files, other languages, etc.

This structure also allows unit tests to test package and protected level methods of the units under test, assuming you place your test cases in the same package as what they test. Regarding testing private methods - I would not bother. Something else, either public, package, or protected calls them and you should be able to get full test coverage testing those things.

By the way, the link above is to Maven, Apache's standard build tool. Every Java project they have conforms to this standard, as well as every project I have encountered that is built with Maven.

SingleShot
+1 Even if you don't use maven, it's a good idea to follow this layout (a kind of de facto standard based on industry best-practices).
Pascal Thivent
Sorry, I don't like Maven at all. The answers recommending /src and /test, with identical package structures underneath, are the way to go.
duffymo
The only reason Maven is mentioned here is because its website is one place where the Apache standard directory layout is documented. Your like or dislike of it is irrelevant with regard to whether the directory structure in question is a good one. Perhaps you can comment on an answer that aligns with your opinion to indicate why that directory structure is superior.
SingleShot
I would not like to follow this recommendation because you cannot just export the "src" foulder to a jar/war. You have to explicitly exclude the test package and would rebuild the whole package structure under the test package.
furtelwart
If you are coding in pure Java, the `java` directory is an unnecessary addition
oxbow_lakes
Well, it should be mentioned that usually both the `main` and `test` folders have a `resources` source folder that compiles into the same output folder the `java` folder does, allowing easy separation of Java code and resource files at the source level. I also like this structure because it keeps the top level free of multiple source folders... it's a very logical organization. And yes, this has nothing to do with whether or not one likes Maven.
ColinD
A: 

Actually it makes a lot of sense to separate your Production and Test projects into 2 separate entities, but have the same package structure in both projects.

So if I have a project 'my-project' I also create 'my-project-test', so I have the following directory structure:

my-project
  +--- src/com/foo
my-project-test
  +---test/com/foo

This approach ensures that test code dependencies do not pollute production code.

In my personal opinion, package private and protected methods should be tested as well as public methods. Hence I want my test classes in the same package as production classes.

Alexander Pogrebnyak
A: 

This is how we have it set up and we likes it.

build/
src/
test/build/
test/src/

All testing code compiles into its own build directory. This is because we dont want production to contain test classes by mistake.

Christian