Getting started with the Diffblue Cover plugin for IntelliJ

A quick guide to writing unit tests for a demonstration project, using the Diffblue Cover IntelliJ plugin.

1. Quick Start:

Diffblue Cover Community Edition is free and can be used for any project. To obtain a copy of the free Diffblue Cover Community Edition, please go to the download page or to the JetBrains marketplace.

Diffblue Cover Professional Edition contains additional features, such as the ability to write tests for your whole project, plus full support and indemnity. To obtain a copy, please go to the JetBrains marketplace.

To write your first test:

  1. Make sure your project compiles.
  2. Find a method or class for which you want to generate tests.
  3. Right click on this method or class, and select Write Tests.
  4. Look at your new tests in /src/test/java.

2. Full Documentation

2.1 Prerequisites

  • IntelliJ version 2021.1 or later, OR IntelliJ version 2020.3 or later
  • Java 8 or 11 source code (but please note that Java 11.0.7 is NOT supported)
  • Maven or Gradle-based project
  • 2 GB minimum memory requirement (to amend this in IntelliJ, select Help then Change Memory Settings)
  • Your project must compile and run.

Diffblue Cover runs the tests that it writes for your code, so your project must compile and run for Cover to work properly. Your project configuration (e.g., pom.xml for Maven projects) must include all required dependencies, and they must all have been built or downloaded (e.g., by doing mvn clean install for Maven projects). JUnit is always a required dependency.

DependencyWhenVersion
JUnit (junit:junit or org.junit.jupiter:junit-jupiter-engine)Always unless using Spring or Spring Boot4.7-5.7
Spring Boot Test (org.springframework:spring-boot-test)When using Spring Boot (org.springframework:spring-boot)2+, matching version
Spring Test (org.springframework:spring-test)When using Spring (org.springframework:spring-core) unless using Spring Boot5+, matching version

Dependencies listed below may be needed, if they are transitive dependencies of your project. If one of these dependencies is required but missing, tests will be generated for some classes but not others. A message will appear in the Event Log indicating a missing dependency.

DependencyVersion
Java Servlet API (javax.servlet:javax.servlet-api)4+, matching version
JSR107 API and SPI (javax.cache:cache-api)0.2+, matching version
Spring Boot Starter Test (org.springframework.boot:spring-boot-starter-test)2+, matching version
Spring Security Config (org.springframework.security:spring-security-config)5+, matching version
Spring Web MVC (org.springframework:spring-webmvc)5+, matching version

Please note that you can only run one instance of the Diffblue Cover plugin for IntelliJ on a project. Running more than one instance on the same project is NOT supported.

2.2 Installing Diffblue Cover plugin for IntelliJ

Download the zip file to a suitable location.

From the IntelliJ IntelliJ IDEA -> Preferences (macOS) or File -> Settings (Windows/Linux) menu, select the Plugins item.

Click on the cog-wheel icon to the right of the Installed tab at the top of the window. From the drop-down menu, select Install Plugin from Disk...

Navigate to the location of the plugin, select the zip file, and then click Open. Click OK.

When prompted to do so, click to Restart IDE, and then click OK.

2.3 Getting started with an example project

Let’s look at an example project, called the Spring Petclinic project, to show Diffblue Cover plugin for IntelliJ at work.

1. Enter the following commands:

  • git clone  https://github.com/Diffblue-benchmarks/Spring-petclinic
    
  • cd Spring-petclinic
    
  • git checkout a-test-intro
    

2. Open your project in IntelliJ.

3. Navigate to a class, for example CloudStorageService . This class implements a simple service for uploading to and downloading files from an S3 bucket.

@Service
public class CloudStorageService {

  @Autowired
  private AmazonS3 s3client;

  public PutObjectResult uploadFileToBucket(String bucketName, String key, File file) {
    return s3client.putObject(bucketName, key, file);
  }

  public S3Object downloadFileFromBucket(String bucketName, String key) {
    return s3client.getObject(bucketName, key);
  }

}
​​​​​​

4. To create tests for this class, right-click on CloudStorageService and then select Write Tests.

When you open the event log, you see what the tool is doing. First it ensures that the project compiles, then it works out which methods we want to produce unit tests for. To create the tests, it has to load the Spring context and find suitable inputs to the methods to exercise paths through these methods.

Once the first test has been created, you can navigate to the created test source file to see the tests. Further tests will drop in as they are produced.

In the example below, the tested service would communicate with an actual S3 bucket, which we don’t want to happen in a unit test. Thus, we mock the S3 client using Mockito. We have to set up the object returned by getObject appropriately, including the content of the file.

@ExtendWith(SpringExtension.class)
public class CloudStorageServiceTest {
  @MockBean
  private AmazonS3Client amazonS3Client;

  @Autowired
  private CloudStorageService cloudStorageService;

  @Test
  public void testDownloadFileFromBucket() throws UnsupportedEncodingException {
    StringInputStream objectContent = new StringInputStream("Lorem ipsum dolor sit amet.");
    S3Object s3Object = new S3Object();
    s3Object.setObjectContent(objectContent);
    when(this.amazonS3Client
        .getObject(or(isA(String.class), isNull()), or(isA(String.class), isNull())))
        .thenReturn(s3Object);
    assertSame(s3Object, this.cloudStorageService.downloadFileFromBucket("bucket-name", "key"));
  }
....

2.4 What does the plugin do?

The figure below shows the pipeline performed by Diffblue Cover.

  1. It first ensures that your code is compiled. This is required because it performs an analysis on the bytecode.
  2. Then it tries to trigger an execution of paths through each method that it is going to test. It uses inputs that are similar to those a developer would choose. On the way, it mocks dependencies that should be mocked.
  3. Finally, it figures out what useful assertions may be and adds them to the test. Note that the assertions always reflect the current behaviour of the code.

What it doesn’t do, is to guess the intended behaviour of your code.

Diffblue Cover plugin for IntelliJ is significantly faster than writing a manual test from scratch. It therefore is a great help to your test writing. Sometimes it might not  find a suitable test for your code, in which case it may return a partial test for you to complete. 

  @MockBean
  private AmazonS3Client amazonS3Client;
  @Test
  public void testDownloadFileFromBucket() throws UnsupportedEncodingException {
    StringInputStream objectContent = new StringInputStream("Lorem ipsum dolor sit amet.");
    S3Object s3Object = new S3Object();
    s3Object.setObjectContent(objectContent);
    when(this.amazonS3Client
        .getObject(or(isA(String.class), isNull()), or(isA(String.class), isNull())))
        .thenReturn(s3Object);
    S3Object actualS3Object = this.cloudStorageService.downloadFileFromBucket("bucket-name", "key")
    assertSame(s3Object, actualS3Object);
  }

2.5 Next steps

Diffblue Cover is intended to be used for unit regression testing. That means, it creates tests that reflect the current behaviour of your code. Later when you make changes to the code, these tests may fail and show you possibly unintended changes to the code, so-called regressions.

Diffblue Cover also helps you speed up unit test writing for new features because it produces mostly complete tests that would take you a long time to write from scratch. A third application is to find bugs by review.

Please checkout the knowledge base for more guides, videos and information on using the Cover IntelliJ plugin.