Search code examples
javaspring-bootjunit

Acceptance test within maven structure?


My question is about the directory location for a docker based acceptance test.

My project is a Spring Boot based command line application which extracts data from a table and builds a spreadsheet. It has unit tests and a JUnit based acceptance test. The JUnit runner for the acceptance test is a standard JUnit runner, not a Spring based runner.

Finally, I have an acceptance test structure which tests the Docker components against a dedicated DB2 instance created specifically for each test. At this point, there's a docker-compose file that:

  • Launches a DB2 container instance exclusively and solely for this test.
  • Launches a Flyway migration container to load test data.
  • Launches a container that does the above mentioned Spring Boot command line application.

After the close of the docker-compose, a comparison is done against the generated spreadsheet and an expected file. If they're byte for byte equivalent, the test is considered passed.

Given the acceptance test above is heavily docker laden and a few steps removed from the Java side, is it still appropriate to put this test under /src/test/acceptance?


Solution

  • There are many approaches to this. In general maven has two plugins: surefire and failsafe. They are very similar in terms of configurations, however surefire is mainly aimed for running unit tests, and failsafe is for integration tests.

    So, first off you probably want to configure acceptance tests with a failsafe plugin. You will:

    • Run them during a different building phase (at least way after the unit tests run)
    • If your build was broken and some unit tests do not succeed you won't even want to run the acceptance/failsafe tests - it might save some build time.
    • You will get different reports for integration and unit tests (technically these plugins create different report folders surefire-reports and failsafe-reports)

    Now to physically separate the tests you can:

    • Merely rely on the naming convention. These plugins look for tests named differently, say: SampleTest.class will be run with surefire while SampleTestIT.class will be run with the filesafe plugin. Of course its all customizable at the level of plugibs configurations in the pom file. Usually unit tests are required to be put to the same package as a real class conceptually. For example: if you have a class Foo in com.myorg.Foo.java, so you place it in src/main/java/com/myorg/Foo.java and the corresponding unit test for it will be in src/main/java/com/myorg/FooTest.java. For integration tests is not usually the case so you can simply create a folder it or something and use run them with different plugins automatically, again because you'll name the tests differently.

    Another approach is to separate the folders within the same module, it was already described above. So technically you maintain src/test/java and src/test/resources and next to it you will have something like src/it/java and src/it/resources. Probably you'll still want to use both surefire and failsafe plugin as I've described above. You'll still run both types of the tests in the same maven lifecycle.

    The most "radical" approach is to separate the acceptance tests to different maven module. This will give you the ability to run the module with acceptance tests separately in a different build step. This might be handy in CI tool for example. Of course you can achieve a similar effect with properties or with maven profiles.