views:

185

answers:

3

In a J2EE web application, how do people manage resources so that they are visible to both the web context and to unit/integration tests?

I find that often you end up having your source/resource folders configured a certain way during development (i.e., what Maven expects) and so your unit tests will run in your IDE. But once the web app is built and packaged into a WAR file (i.e., when your Continuous Integration server has done a build) your unit tests won't run anymore because the resources are located elsewhere.

Do you end up keeping resources in two different places and manually keeping them in sync?

A: 

I won't package testing resources nor tests in a WAR file neither run unit tests from the WAR. Why you are trying to do so?

Arne Burmeister
+1  A: 

Normally this is the reason for multi-module builds. The external services are in a separate build unit than the web application. So you build, package and run your integrations tests when you build that module.

Another module can contain your domain model and its unit tests, which are also run at build time.

It is quite common for a module that results in a WAR to not have any java code in it at all, but only web related artifacts. Although not necessary, this is often done because code that is in a war module cannot be included into another module.

The last special case is the module containing web-tests. This module may often need test-scoped artifacts from the other modules (because it is testing the application from the outside, but may need data from the inside). This can be solves by also packaging test-resources in jar files, creating a separate set of "test" jar files for each modules.

Multi module builds are the norm for maven projects, and are also easy to set up for other build systems like ant.

krosenvold
I left this question pretty wide-open, but I guess I'm looking more specifically at a scenario closer to your "web-tests" description. And in this case, it sounds like you provide your resources on the classpath (in a separate jar).
ayang
A: 

We tried using unit tests in the container but gave up on it years ago. It's much better (for us at least) to make each unit test cover a single class and nothing else, mocking out the dependencies on other classes (see JMock or its many competitors). A good basic rule is that if it touches the database, network, or the filesystem, it isn't a unit test. (It may be useful for something else, but it isn't a unit test. See these unit testing rules for more on this.)

Unit tests written this way can be run anywhere, and they are blazingly fast (we have thousands and run them in under 60 seconds on medium-spec hardware.)

You may also want to run integration tests that check a subsystem or the whole application. We find that subsystem tests can also use mocking at their borders - for instance, we fake an external pricing feed - and that end-to-end tests work best with tools like Selenium or WebDriver, which let you deploy the whole application on a server and then hit it with a browser just like users do.

(By the way, our method of unit testing makes us mockists, rather than classicists, in Martin Fowler's taxonomy.)

Douglas Squirrel