views:

70

answers:

5

Hi,

This is a relatively open question. If I have built an application in a project in Eclipse and I then want to test this project, should I create the JUnit code within the same project or create a seperate project. For instance...

ShopSystem maybe the name of my main project - should I create a project called say, ShopSystemTest?

In general - how far "away" should the testing code be stored from the main project folder? If I store the testing code within the main project and then export the main project as a runnable jar it will take the testing code with it, which isn't ideal...

Suggestions?

Thanks,

David

+4  A: 

While there is no only right way, the usual approach is to keep unit tests in the same project.

You can create a second source folder (like test), where you put your test classes into the same packages as the classes under test. This also allows you to test package-private classes while not flooding your main source packages with test classes.

Your source folder/package structure would then look like this:

-sources
   -main
       -my.package
             -MyClass.java
   -test
       -my.package
             -MyClassTest.java

You can then configure your build to not include the test source folder when packing the JAR.

Henning
+1  A: 

Typically you have -

/src/main/java   (for codes)

/src/test/java   (for tests)
fastcodejava
A: 

Consider the maven way : In a maven project, soruces are organized this way

src
 |--main
 |     |--java
 |--test
       |--java

Your source code goes in src/main/java, your junit test code goes in src/test/java, they both are source folder (and as a consequence you can put your jUnit code in the same package as your Java code, but in a different source folder).

The interest is that for usual coding, your jUnit classes are in code packages, but on jar creation, you can take classes coming only from src/main/java and not release your tests.

Riduidel
+1  A: 

I like the maven convention a lot: There is a separate source tree for main and test in the same project, main code gets deployed, test code doesn't. Package structures can be (but don't have to be) identical.

project
    src
        main
             java      // source files
             resources // xml, properties etc
        test
             java      // source files
             resources // xml, properties etc

And in eclipse, when you choose new -> JUnit test case, you just change the source folder to src/test/java and leave the suggested package as is.

(One of the benefits of remaining in the same package is having access to protected and package scoped members, although this is not 'proper' unit test behavior)


Update: Here's some code to illustrate my last point:

Main class (in src/main/java):

package com.test;
public class Foo{

    static class Phleem{
        public Phleem(final String stupidParameter){
        }
    }

    String bar;
    protected String baz;
    protected Object thingy;

}

Test class (in src/test/java):

package com.test;
import org.junit.Test;

public class FooTest{

    @Test
    public void testFoo(){
        final Foo foo = new Foo();
        foo.bar = "I can access default-scoped members";
        foo.baz = "And protected members, too";
        foo.thingy = new Foo.Phleem("And I can access default-scoped classes");
    }

}
seanizer
"access to protected and package scoped members" - to have access to protected members, you'd have to subclass the class under test. What you mean is being able to access package-scoped classes, right?
Henning
Oh, and members too, of course you're right. I've used default-scoped members so seldomly that I sometimes forget they exist.
Henning
Ouch! I did not know `protected` allowed access from other classes in the same package. Okay, that clears things up, thanks.
Henning
yes, the whole access level concept is rather stupid. e.g. there's no way to make packages accessible to sub-packages without making the classes public. scala has a much better system there.
seanizer
@seanizer: I agree. If Java was designed today, private would probably be the default, protected would allow access only from subclasses, there would be a concept of sub-packages, and `final` would be the default for classes, local variables and maybe even members. Oh well.
Henning
@Henning final would be default? you mean there would be a keyword to mark classes and methods as extensible? I'm not sure whether I'd want that because you'd have to bug API designers all the time to please add the keyword to this and that method.
seanizer
@seanizer: Well, it would put the rule to either design and document for inheritance or prohibit it (Josh Bloch) right into the language. IMO you can hardly ever extend a class well that wasn't designed for it from the ground up.
Henning
I know, I tried to extend the Hibernate Validator once. I gave up soon and re-wrote most of it...
seanizer
A: 

Rather than having a separate folder for tests in my projects as everyone else has suggested, I opt for keeping it together. I just make a new package called unit.

-src
  -package
      -unit
         -javaTest
      -java

It keeps the test close to the code and you can still compile without them by excluding all unit packages.

As long as it is clear I think it's just your preference.

Andrew