Icon for gfsd IntelliJ IDEA

Smart Java Unit Test Generation for VS Code and IntelliJ

Generating unit tests for Java in VS Code and IntelliJ with Symflower.

Performing unit testing has become standard practice in modern software development. Doing adequate unit testing is simply necessary if you’re aiming to shift-left your testing and fix bugs as early as possible. Unit tests can be written and run before the entire system is in place, even before the first implementation of a function is actually there. Basically, there’s no shifting further left than that, otherwise you would be in the planning stage.

Unit tests help make sure you deliver high-quality, well-functioning code, and that your implementation stays bug-free in the future. Any and all changes you make should be checked with unit tests. When in doubt, refer to the Beyoncé rule: “If you liked it, you should have put a CI test on it”!

But writing unit tests is a tedious process that eats up lots of development time and effort. Even with all that effort, however, manually creating unit tests means there’s still some chance that you’ll miss a bug or two. We can’t always think about all the corner cases, not to mention that unit tests themselves can have bugs, too.

To maximize productivity, you need a way to:

  1. … reduce the time and effort costs of writing good quality unit tests.
  2. … ensure that those unit tests thoroughly test your code, one behavior at a time.

Automatically generate JUnit unit test cases with Symflower

At Symflower, we found a solution to tackle both challenges at once: building a smart tool to generate the boiler plate for writing unit tests in a jiffy and the auto-generation of whole unit test suites. Both functionalities significantly reduce the effort that goes into ensuring the quality of your code. In addition, Symflower’s symbolic execution engine can discover edge cases that you may miss if you wrote unit tests yourself. Symflower is a great performance-boosting tool regardless of whether you are using TDD or a traditional development approach as it supports any workflow.

Whatever IDE you are using (Visual Studio Code, JetBrains' IntelliJ IDEA, GoLand or Android Studio), you can easily generate Java unit tests automatically with Symflower for code written in Java or Go. Symflower is like a virtual programming buddy that spots problems and unexpected behavior, takes care of routine tasks, and auto-generates Java unit tests with meaningful values in real time.

For a concrete example, let’s take a look at how the functionality of the Java unit test generator works!

How does Symflower work? A JUnit test generator for IntelliJ IDEs, VS Code, and CLI

Let’s use a simple example to give you an idea of how Symflower can make your life easier. In this example, we want to implement a class to store triangles. Specifically, we want to be able to store the length of each side of the triangle, and we also want the application to tell which kind of triangle we’re dealing with:

  • Equilateral: all sides are the same length
  • Isosceles: two sides have the same length
  • Scalene: none of the sides are equal in length

We’ll start by whipping up just the basic frame of the geometric triangle class with three member variables for the three triangle sides, a constructor, as well as the available triangle types:

public class Triangle {
    private int sideA;
    private int sideB;
    private int sideC;

    public Triangle(int sideA, int sideB, int sideC) {
        this.sideA = sideA;
        this.sideB = sideB;
        this.sideC = sideC;
    }

    public TriangleType getType() {
        return null;
    }
}

enum TriangleType {
    equilateral,
    isosceles,
    scalene,
    invalid
}

Let’s start to test getType. If you’re a TDD practitioner, you can use Symflower to generate the boilerplate code for your unit tests now. Then, you just need to fill in the right values for your tests. Simply open up your context menu and hit “Symflower: Add Unit Test for function”. See what you’ll get in section 1 of this article: Creating smart unit test templates with Symflower!

The video below shows how Symflower can greatly support a typical TDD workflow:

Not into TDD? No problem. Let’s move on to writing the logic for our triangle class first. A possible implementation of the getType function could look as follows:

public TriangleType getType() {
    if (sideA <= 0 || sideB <= 0 || sideC <= 0) {
        return TriangleType.invalid;
    }

    if (sideA == sideB && sideB == sideC) {
        return TriangleType.equilateral;
    }

    if (sideA == sideB || sideB == sideC || sideA == sideC) {
        return TriangleType.isosceles;
    }

    return TriangleType.scalene;
}

OK, on to unit testing! Let’s see how Symflower’s two options (generating full unit tests vs generating boilerplate code for your unit tests) play out:

1) Creating smart unit test templates with IntelliJ or VS Code

Writing boilerplate code to actually write your unit tests can be a major productivity drainer. If you want Symflower to create the boilerplate code for your unit tests, right-click and hit “Add Unit Test for Function”. Symflower will add the boilerplate code to your test file that you can review and fill in with values. Here’s what the generated unit test template in our example looks like:

package com.symflower.demo.triangle;

import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;

public class TriangleTest {
    @Test
    public void getType() {
        Triangle t = null; // TODO Replace default value.
        TriangleType expected = null; // TODO Replace default value.
        TriangleType actual = t.getType();

        assertEquals(expected, actual);
    }
}

2) Auto-generating unit tests with IntelliJ or VS Code

To get complete, ready-to-compile unit tests with high coverage for your code, you just have to right-click and hit “Generate Unit Test for Function”. Symflower’s symbolic execution engine will explore all paths in your code, find meaningful values to test those paths, and create ready-to-run unit tests for your test file:

@Test
public void getType4() {
    Triangle t = new Triangle(1, 1, 0);
    TriangleType expected = TriangleType.invalid;
    TriangleType actual = t.getType();

    assertEquals(expected, actual);
}

@Test
public void getType5() {
    Triangle t = new Triangle(1, 1, 1);
    TriangleType expected = TriangleType.equilateral;
    TriangleType actual = t.getType();

    assertEquals(expected, actual);
}

@Test
public void getType9() {
    Triangle t = new Triangle(2, 2, 1);
    TriangleType expected = TriangleType.isosceles;
    TriangleType actual = t.getType();

    assertEquals(expected, actual);
}

Note that the above is just an excerpt of the test suite for the shown implementation. For each path in your program, the required inputs for a test are detected by Symflower. Even choosing the right constructor for initialization, and the resulting outputs are provided.

Watch this video to see Symflower in action, or download the Symflower IDE extension right away!

Wondering how Symflower works? Symflower uses symbolic execution to search for all possible execution paths and bugs in your software. It provides optimized unit tests that are easy to read and ideal for debugging. Peek under the hood: Symflower’s inner workings: the technology behind the curtain

The benefits of auto-generating unit tests

That’s it! We just used Symflower to create unit tests in a fraction of the time it would normally take if we were to write those tests manually. In addition to saving time and accelerating development by automatically generating unit tests, Symflower offers a range of other benefits, including:

  • Instant, real-time problem detection while coding. By having bugs fixed early, this translates to significant savings in development costs and time.
  • Boost TDD. Test-driven development is way easier and faster if you only need to think about which test values to use, because all the boilerplate code is already provided for you.
  • Debug edge cases effortlessly. By exploring all application paths, Symflower can help your discover problems that you may otherwise miss.
  • Automatic mocking. Automatically generate mocks for your interfaces, along with all the necessary behavioral checks that let you handle all possibilities.
  • High code coverage with minimal effort. Unit tests are generated in real time and with practically no effort, making it easier for you to reach optimal test coverage of your code.

Don’t take our word for it – try Symflower yourself to see if the unit tests it generates helps you slash development time.

https://get.symflower.com

Found a bug or have an idea for improvement? Don’t hold back! We’re always glad to hear your feedback! Also, make sure you don’t miss further updates from us: sign up for our newsletter, and follow us on Twitter, LinkedIn, or Facebook.

| 2023-01-18