When Diffblue Cover creates tests, it must be able to execute your code in a similar way to your unit tests. Thus, a necessary prerequisite for using Diffblue Cover is that you are able to compile and run your existing unit tests. Your code must also compile successfully before you can use Cover.
Being able to execute your unit tests means that all class files that are produced by compilation of your project must be available. Furthermore all the dependencies, i.e. other modules in your project and jar files which are downloaded by your build system (e.g. Maven, Gradle), are needed. Jar files again contain class files and may depend on other jar files. Your build system typically takes care that all these jar files are downloaded transitively. Strictly speaking you also need the Java Class Library provided with your JDK, but Cover will figure out which JDK version you use and search for it in the standard installation paths.
Sometimes you might succeed compiling your code, but when you run your application or your tests you get an error that a class was not found. The reason for this is that classes in dependencies are missing that were not necessary for compilation, but they are still required for execution. This usually indicates that you have not compiled your project correctly and something is wrong in your build configuration (e.g. pom.xml) or environment (e.g. JDK installation). Diffblue Cover will run into trouble in such situations and will also complain that a class cannot be loaded successfully.
What can you do in this situation?
First, ensure that you have correctly compiled your project. Most multi-module projects require you to compile your code from the root of the project with a command such as
mvn clean install -DskipTests
Even though you have to run Diffblue Cover’s CLI dcover from within the module you want to create tests for, you have to run the command from the root of your project, not from within the module.
Anything other than a complete build from the root is often insufficient for complex build configurations that may require installing jar artifacts into your local .m2 repository, for instance. This happens quite often and you might not even be aware of it. So, play it safe and compile the whole project first.
Let’s see this in an example. Consider the multi-module Maven project JDMN. We first download the project and switch to the release 3.10.0:
$ git clone https://github.com/goldmansachs/jdmn $ cd jdmn $ git checkout 3.10.0
We should now run mvn clean install -DskipTests, but for the sake of an example let’s try to simply mvn compile first:
$ mvn compile
So this doesn’t work. Let’s illustrate another mistake: we use mvn clean install -DskipTests, but do it inside a module:
$ cd dmn-tck-it $ mvn clean install -DskipTests
We see that the compilation succeeds. This is only possible because all the required dependencies were downloaded by Maven from the central repository. One of these dependencies was dmn-core, a module provided by the same project. But the version of that module that Maven downloaded may not correspond to the code we have in the local module dmn-core. Note that dmn-core has not even been compiled:
$ ls ../dmn-core/target ls: ../dmn-core/target: No such file or directory
This could be a problem if we have, for instance, introduced a bunch of changes in dmn-core and we expect the code in dmn-tck-it to exercise those changes.
We really have to go back to the root and run mvn clean install -DskipTests from there as we suggested earlier:
$ cd .. $ mvn clean install -DskipTests
If you are using Diffblue Cover’s CLI, you can now change directory into the module that you would like to create tests for and run dcover create.
If this still does not work, then you have to inspect your build configuration. Typical problems arise from system scope dependencies and exclusions. System scope dependencies are sometimes used to bake commonly used dependencies into a prepared environment (e.g. server or CI image). So it could happen that these dependencies are not installed in your local environment.
The solution is to ensure that your local environment conforms to the runtime environment on your servers or CI system. Exclusions specify that certain transitive dependencies should be excluded from your classpaths. It can happen that such an exclusion is incorrect and classes are excluded that are actually needed. The solution in this case is to find the faulty exclusion and fix your build configuration.
So remember: always compile your entire project from its root before using Diffblue Cover.