Get tests on a remote branch with Jenkins

Overview

This topic will take you through an example using Jenkins and GitHub to create a parameterized freestyle Jenkins project that runs Diffblue Cover. The freestyle project will use Diffblue Cover to write tests for a remote change branch and push them onto the branch.

It is recommended that you first follow the quick start. Following the quick start, this introduces the usage of the --patch-only option with dcover create in a CI environment. The --patch-only option writes tests only for the classes in or affected by the code change. This speeds up execution and is a good way to incrementally add coverage to your repository using Diffblue Cover. Furthermore, it introduces a way to get Diffblue tests checked into your repository by pushing them onto a remote branch.

The freestyle project has a build step script that:

  1. Builds your project.

  2. Downloads and unzips dcover.

  3. Activates dcover.

  4. Authenticates with the remote host.

  5. Creates a patch file between the remote branch and its base.

  6. Calls dcover create with --patch-only.

  7. Commits and pushes Diffblue tests to your remote branch.

This topic assumes that you have:

  1. Completed the quick start successfully.

  2. A branch on the remote host that is based on another branch.

  3. The ability to authenticate with the remote host by script and that this authenticated user can push to the branch.

Create a test branch

In the repository you wish to write tests for, create a branch called diffblue-test based on your main branch.

Make a simple change in a single module and commit the change. Push this branch to the remote host.

The diffblue-test branch will be used and modified on the remote host throughout this guide, so make sure you are happy that it is modified.

Create a parameterized Jenkins freestyle project

Create a Jenkins freestyle project for your repository called diffblue-cover-tool. Exactly how you need to configure the freestyle project is out of the scope of this guide, but the sections below point out the minimum required configuration.

You can follow the steps below for a step-by-step guide building the freestyle project.

Add build parameters

Tick the This project is parameterized box. Add the following three string parameters and descriptions:

  1. MODULES - a space-delimited list of modules to write tests for

  2. HEAD_BRANCH - The branch to write tests for and push to

  3. BASE_BRANCH - The remote branch or sha that HEAD_BRANCH is based on, e.g., develop, for making the patch file

Set up source code management

Add and authenticate with the repository you wish to write tests for. This will be similar to how it is set up in the quick start.

You will need to restrict the branches to build to HEAD_BRANCH. In the Git plugin, this is under Branches to build. In the Branch Specifier field, add $HEAD_BRANCH.

Under Additional behaviours select Wipe out repository & force clone.

Add credentials binding

You should already have these credentials stored from the quick start guide and general Jenkins setup. Under Build environment tick the Use secret text(s) or file(s). Add the following bindings:

  1. DB_RELEASE_URL - as Secret text: The URL for downloading the Cover files

  2. DB_LICENSE_KEY - as Secret text: The license key for Diffblue Cover

  3. DB_SSH_KEY - as SSH User Private Key, Key File Variable: The private SSH key authenticating with the remote host. If you don't have this yet, this is explained in the Authenticating with the remote host section and can be added at that time.

Build step

Add a build step of type Execute shell with:

echo "Hello world!"

Post build actions

Add Delete workspace when build is done. This will clean up any Diffblue tests in the workspace.

Build the freestyle project

Save your project. From the Dashboard, navigate to the project and select Build with Parameters.

Enter appropriate parameters for:

  1. MODULES - the module that you changed in the diffblue-test branch above or "." if the project does not have modules

  2. HEAD_BRANCH - e.g., diffblue-test

  3. BASE_BRANCH - e.g., develop

then click Build. The console output should show the result of the build step by echoing Hello world!

If this is not yet working, ensure your project is correctly configured and try again before continuing.

Write the build step to use Diffblue Cover

Navigate back to the freestyle project configure page. The script in the build step that echoes Hello world! will be replaced by a script that writes tests for and pushes tests to the remote branch specified in the HEAD_BRANCH parameter - in this example the diffblue-test branch.

Build project, get and activate Cover

This script is taken from the quick start guide. If you had to modify how you build the project, get or activate Cover, modify this script as you did in the quick start guide before proceeding.

#!/bin/bash

echo "Build project, you may need to update this to reflect your project"
mvn clean install -DskipTests --no-transfer-progress

echo "Get and unzip dcover jars into directory dcover, store dcover script location for later use"
mkdir --parents dcover
wget "$DB_RELEASE_URL" --output-document dcover/dcover.zip --quiet
unzip -o dcover/dcover.zip -d dcover
DCOVER_SCRIPT_LOCATION="dcover/dcover"

echo "Activate dcover"
"$DCOVER_SCRIPT_LOCATION" activate "$DB_LICENSE_KEY"

Authenticating with the remote host

The script will need to authenticate with the remote host in order fetch and to push Diffblue tests to the remote branch.

On GitHub, this is done by a deploy key with write access as follows

  1. In the GitHub repo under Settings, add the public SSH key as a deploy key on GitHub.

  2. The previous step used the key gen procedure, obtain the private SSH key as described there and add the private SSH key to Jenkins as SSH user name with private key.

  3. If you have not already, add the private SSH key as a binding in the project configuration with variable name DB_SSH_KEY.

Once this is set up, you can authenticate in the bash script by appending

echo "Remote host set up"
eval "$(ssh-agent -s)"
ssh-add $DB_SSH_KEY

to the script started above.

Furthermore, the user needs to be configured.

git config user.name db-ci-bot
git config user.email db-ci-bot@yourorg.com

At this point you can trigger the parameterized build and ensure that the authentication has worked before proceeding.

Create a patch file

The dcover create command will use the --patch-only option to restrict the number of classes analysed. To create the patch file, append to the build step

echo "Create patch file, store absolute path to patch file for later use"
PATCH_FILE="changes.patch"
git fetch origin
git diff origin/$BASE_BRANCH...HEAD | tee "$PATCH_FILE"
PATCH_FILE=$(realpath $PATCH_FILE)

BASE_BRANCH is the parameter from the freestyle job. If your remote is not origin, update this to your remote name.

This creates a patch file with the differences between HEAD_BRANCH and BASE_BRANCH on the remote host. See the Patch files topic for more on creating patch files.

You can trigger the parameterized build with appropriate parameters. The patch file is output to the log so check that the output patch file is what you expect before continuing.

Run Cover create

As in the quick start guide, call dcover create. In this guide, the parameter MODULES will specify the modules to write tests for, so several calls are made in a loop.

Append to the build step:

echo "Run dcover create for each module and output the diff"
MODULES_ARRAY=(`echo $MODULES`) # requires bash shebang, #!/bin/bash
for MODULE in "${MODULES_ARRAY[@]}"
do
	"$DCOVER_SCRIPT_LOCATION" create --working-directory "$MODULE" --batch --patch-only "$PATCH_FILE"
done
git diff "*DiffblueTest.java"

You can trigger the build again and check that the appropriate tests are created. After the loop, the diff is printed to the log. Diffblue Cover should write tests for most classes, but if no tests are written then you may wish to make another change to your remote branch to verify that it is working correctly before proceeding.

This assumes that the Diffblue tests have the suffix "DiffblueTest.java" which will be the case unless you have modified the dcover create call to change it.

Pushing tests to the remote branch

Now add, commit and push any Diffblue tests to the remote branch.

Append to the build step:

echo "Pushing Diffblue tests to $HEAD_BRANCH"
git add -f "*DiffblueTest.java"
git commit -am "Add Diffblue tests"
git push origin HEAD:$HEAD_BRANCH

Trigger the build with the appropriate parameters. If tests are created, they should appear on your remote branch as the commit Add Diffblue tests when the build completes. Note that if the remote branch already has Diffblue tests, only the differences will appear in the commit and no commit will be made if the tests on remote and the ones Diffblue Cover just wrote are identical.

What's next

You may like to trigger the above job using a webhook for every pull request in a Jenkins multi-branch declarative pipeline.

Last updated