Take It From the Top, Part Three
Yesterday I wrote about the moving parts that allow you to write acceptance tests for a Java webapp without going insane. We talked about XPath and how wonderful it is, as well as the roles and responsibilities of the various classes within the system. I also mentioned that I was undecided about what to blog about because there were two things that I really liked and wanted to tell you, my dear reader, all about. Well, now it's time for this mysterious second thing.
I can tell that you're on tenterhooks. It's why I blog so often.
Let's take a step back from our webapp and think for a second. We want the acceptance tests to be fast, but we'd also like to be able to run them against a stack as similar to that used in production as possible. Unless you happen to be deploying to Jetty it's likely that deployment takes the better part of 5-10 minutes and dozens of mouse clicks (yes, WebSphere, I'm looking at you) Our two goals appear to be mutually exclusive. And what about running our integration tests? You know, the ones that check that we're using Hibernate correctly. At the other end of the scale, those pesky QA people will probably have their own test environments that they'll want to use, and we'd like to be able to run our automated acceptance tests against those too.
Hang on! "Test environments"? There's a pattern in there somewhere (bear with me, I've not written one of these before)....
Automated tests could be run in a variety of test environments
Therefore, create a class to represent each expected test environment. This class can be used to obtain information about resources used or presented by the application, such as DataSources or the base URL of a webapp.
Ideally, a TestEnvironment should be created by calling the default constructor, and before being created a check should be performed to see whether or not another TestEnvironment is in use:
private TestEnvironment setUpEnvironment() throws Exception {
if (TestEnvironment.isEnvironmentAlreadySetUp()) {
return TestEnvironment.getCurrentEnvironment();
}
return new AcceptanceTestEnvironment();
}
The smarter amongst you will probably tell me not to use statics for this sort of thing, and will suggest a better solution. I can live with a bit of constructive criticism.
As an aside, if a particular environment doesn't require a resource (such as an app server in your integration tests) then I've found it best for the TestEnvironment to throw an exception rather than simply returning null. YMMV. You'll also find that instantiating the TestEnvironment in a TestSetup decorator or in a TestSuite is a Good Thing.
Posted in: /tech /tech/java
You may comment...