After all, any putz with a web site can stand up and declare whatever they want. But this is an area riddled with so many problems, I think it would benefit all of us if we could say "yes, that's spot on" or "I agree with all of it except" or ... whatever. Let's figure out at least what we do agree on!
There will be several threads tying back to that article. This thread is only about the section about the directory structure.
Originally posted by Lasse Koskela:
One thing in the presented directory structure that got my attention is that you've got production code ("<ROOT>/src") and test code ("<ROOT>/test") living in separate top-level directory trees. Personally, I prefer having them within a single directory tree like "<ROOT>/src/main" and "<ROOT>/src/test". While this does lengthen the overall file paths by 5 characters (shocking, isn't it...), it also tends to simplify any scripts that need to deal with source code--because you only need to specify one path, not two, in order to cover all your source code. Again, this is a rather minor thing and definitely a matter of personal preference.
A matter of taste I suppose.
I guess to me "src" means production source. So I wanna keep all my test related junk out of there.
Ever afterwards all I've care about is that there is *some* convention for keeping track of which resources are which, and if file naming conventions get me that, I'm content. Ant does just fine with file name patterns when I need to create clean functional vs test build products for release. While keeping the test stuff separate makes sense to me, having it not compile was more grief than any hypothetical issue associated with not having separate directories. When the files are in one directory hierarchy, bad practices of others have less impact on you. The hacks that won't run tests don't quite so constantly break everybody else's test-driven work approach.
Above all, I wonder about the subject line of this thread - how does the directory structure *facilitate* testing?
We have all our (J)unit tests in the production code source directory, and the functional (FitNesse) tests are in its own (eclipse) project. I don't think that changing that structure would lead to better testing.
In fact I'd argue that seeing a "test" package right beside the class you are currently writing is a motivation to write a unit test for it. If the tests were in its own directory structure, you wouldn't see that.
I've done that on some small projects as well ("small" as in "just prototyping something that will go to the trash can after I'm done") but I quickly reached a point where I had trouble getting a "visual" of what's in a package when there were 2-3 classes containing test stuff (test classes, mock implementations) per each production class.
Originally posted by Lasse Koskela:
I quickly reached a point where I had trouble getting a "visual" of what's in a package when there were 2-3 classes containing test stuff (test classes, mock implementations) per each production class.
Well, the test classes still are separated from the production classes - they are in a separate package.
One of my coworkers has written a small Eclipse plugin to visually distinguish between test- and non-test-packages: http://www.jave.de/eclipse/labeldecorator/ - that might help a bit, too.
As far as not compiling unit tests, well, that's why we use cruisecontrol. We also use cobertura for unit test coverage, and I keep upping the "totalbranchrate" and "totallinerate" whenever we add a bunch more unit tests.
People had created test programs in a test directory underneath the directory of the classes to be tested.
This became a problem when it was time to move to production because we didn't want the test programs to be in production. We first branched the make files, which wasn't a great thing to do.
Later, we used an environment variable as a switch for what goes and doesn't go. But, each make file still needed this variable.
Later, when we started using JUnit, we made sure we had a parallel test directory structure. This allowed us to control all tests with the environment variable to be sure the test directory did not go into production.
So, we have carried on this tradition.
Now, we are creating a new development environment. So, it is good to see the discussion on these items.
Originally posted by Reid M. Pinchback:
Ant does just fine with file name patterns when I need to create clean functional vs test build products for release. While keeping the test stuff separate makes sense to me, having it not compile was more grief than any hypothetical issue associated with not having separate directories. When the files are in one directory hierarchy, bad practices of others have less impact on you.
I have to agree with this. Keeping different types of code in parallel directory structures seems seductively sensible, but in practice, it's more of a pain than it's worth. In my experience, on real projects, it's much less hassle to keep all the code in the same directory structure, reflecting the package structure. You can ensure that your production code doesn't depend on your test code by having your integration tests run a target that compiles only the production code - easy to do, since the tests have to be identifiable to run them anyway.
Originally posted by Warren Dew:
You can ensure that your production code doesn't depend on your test code by having your integration tests run a target that compiles only the production code - easy to do, since the tests have to be identifiable to run them anyway.
Well, it's easy to separate them with file patterns if they're identifiable but it's not just about "Test*" and "*Test"--there are also numerous "Mock*", "InMemory*", "*Matcher", etc. prefixes/suffixes that one easily introduces throughout a project. Again, it's just a personal preference, but I prefer keeping parallel source trees and not worry about having forgotten or overdone some file pattern thing in the build script.
Our agile XP shop runs three teams at once, each with a different project. We have a
folder checked into CVS that keeps all the development teams in sync, and our ant build copies each of the desired jars out of the libraries into our build folders (/test or /libraries). The ant build then references the build directory classpaths to do the compile.
This approach simplifies keeping all the jars for all the projects in one place and in sync. We end up having several versions of jars in c:\java\libraries as we upgrade and each project picks what they need. One of the guys even wrote a test to make sure the IntelliJ project file and the Ant classpaths both had the same jars so that Ant didn't get out of sync with Intellij. Referencing a jar in your IntelliJ project without adding it to the ant build breaks a test. A simple and effective way to keep all your jars in one place and in sync. Currently managing just under 200 jars. Works great if you want to attach the jars source too!