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.

Diffblue Cover plugin for Intellij can be downloaded from our website or from the Jetbrains Marketplace. After installation, you can choose to use the free Community Edition or buy a license for Developer Edition.

For Developer Edition, please follow the instructions below:

1. 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. Activating a Diffblue Cover license

Enter your license information at the welcome screen, and click Activate. Your current license status is shown in Diffblue -> View License information.

 

3. Icons

Indexing - we are discovering your project structure! Meanwhile, click on the icon to write tests.

Write tests - click on the icon to write tests for this method or class.

Untestable - this method or class cannot be tested; click on the icon to find out why.

Private method - this method cannot be tested as it is private but it may be tested indirectly via a public method. Please make this method public or package protected if you would like to write unit tests.

Test writing in progress - please wait while we finish!

4. 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, click on the test flask icon to the left of the line <span class="kd">public</span> <span class="kd">class</span> <span class="nc">CloudStorageService</span> . You can also right click on the line itself and then select Write Tests.

The Diffblue Cover tool panel will appear, outlining the steps performed to write the tests. Cover first 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"));
  }
....

5. 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 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);
  }

6. 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 tests that would take you a long time to write from scratch. A third application is to find bugs by review.

Additionally Diffblue Cover can help developers get started writing tests manually by providing skeleton tests for a given class or method. This can be particularly useful when a known bug needs to be reproduced as a test case in preparation for a fix to be developed.

Please checkout our documentation for more guides, videos and information on using the Diffblue Cover plugin for IntelliJ.