The way Maven file structure is defined is a great way to separate unit tests and production code. Unit tests are fast. So fast that developers developing using Test Driven Development, TDD, doesn’t have any performance problems when applying the Red-Green-Refactor cycle in their work. A large unit test suit is expected to be executed in seconds.
There is, however, no standard on how the files should be structured for slower tests (integration/acceptance/system et.al.). A common property for these tests is that they are slow. They often require a complete system setup in a known state. They use the filesystem, network, database and similar slow resources. Slow tests are normally not executed often. Developers seldom have the patience to wait for a build a long time before writing the next thing. Using them in a Red-Green-Refactor cycle is not practical. It takes too long time.
So what options do we have to separate the fast units tests and the slow tests? There are two main tracks that I have explored.
- Separating tests with name or package conventions
- Separating slow tests in a test module
A colleague asked that question the other day. What is a good test? It is a really difficult question to answer. There are a number of properties that hold true for a good test. I will list some of them and discuss why I think they are important. Others may think that the order of importance is different or that other properties are more important then those that I list.
I will show some examples using Java and JUnit of what I think are bad tests and how they can be refactored to something better.
Tests are automated in my world. I always try to avoid manually testing. The main reason for this is that manual testing is slow and hard to repeat arbitrary many times. Therefore, test should be read as automated test in for the rest of this text.
Why should the step definitions be separated from the driving JUnit class when using Cucumber for Java?
We want to perform an integration test of a system using Maven. The application must be deployed on an application
server and the application server must be started before we can perform the integration tests. The application
should be undeployed and the application server should be terminated after the integration test has been performed
no matter what the result of the test was.
How can this be achieved with Maven?
We want to run the same test more than once and only vary the parameters. The solution is to use JUnit and run our
tests with the Parameterized JUnit runner.
We want to build a web application and we want to test it automatically.