This section highlights DevMate’s high level concepts. Each subsequent tutorial goes into more detail and covers more scenarios.

In this tutorial, we are going to write the functional code first and then generate the corresponding test.

The next tutorial shows the same example but implemented with the Test First approach of Test Driven Development.


VIDEO - coming soon


Github

You can find the code relating to this tutorial on Github in the /java/util/trivialissimo folder.

Requirements

We need a very simple function that should meet the following very basic requirements.

It receives a positive integer as a string type, not as an integer. It should return the value as an integer type.

Valid cases would be

- “10” (any other valid string representation of an integer)

Invalid cases, which should throw an exception, are

- decimal string values such as “10.1”

- zero “0”

- any non-integer text strings such as “ten” or “xxx”

Creating the DevMate test

Method implementation

You might notice that this method does not meet the exact requirements, but we’ll use DevMate to catch this later.

Here’s the code

public class Trivialissimo {
    public static int parsePositiveIntString(String value) {
        return Integer.parseInt(value);
    }
}
CODE

Right click on the method name and then select Test with DevMate.

This will then create a .tmdl file. This will be saved to the src/test folder or the same folder as your class, depending on your project.

DevMate suggests the name of the parent class as the filename. For many cases, it makes sense to include all class methods to be tested in the same .tmdl file. We explain how to add more methods in the Scenarios and Chaining methods in one scenario tutorials.

DevMate Dialog

Next, you will see the DevMate dialog, which we’ll explore now.

We’ve preconfigured this in order to explain the general approach. Subsequent tutorials explain the configuration in detail.

The DevMate dialog

1. Instances

We are testing a static method, so no instantiation of the method’s parent class is required. We will see in later tutorials where this comes into play.

2. Methods

DevMate automatically picked up on the method when we right-clicked the method name in the IDE.

3. Inputs

The input String parameter was also automatically picked up by DevMate. Within here, we’ve added some input values that we want to test that meet the specified requirements. Note that valid inputs are marked green and invalid ones red.

If DevMate has seen similar code elsewhere, it can even auto-populate these values for you. Please take a look at our recommendation engine for more information.

4. Outputs

Here we add all of the possible returned values that could result from the inputs. Again, green is valid and red is invalid. Note that we can also specify exceptions that might be thrown by our method under test, including subclassed exceptions. In the above case, we are just catching all exceptions.

5. Generate test cases

Once the inputs and outputs are defined, you tell DevMate to generate the test cases, which it does automatically based on the provided inputs and outputs.

6. Completing the test cases

DevMate needs to know which input matches which output. DevMate tries to figure this out itself but lets you know if it’s not certain.

7. Generate Test code

Now we’re all done with the definitions, we press the button and the unit test code is automatically generated.

Generated Test Code

Now we can look see the test code back in the IDE. DevMate generates “parameterized tests”. This means it creates a single test that is fed with each of the test cases and its associated parameters.

We’ll look at the generated code in more detail later. However, in principle, you can immediately run the tests as you would with a manually written unit test. If you’re an IntelliJ user, you notice the familiar green arrow to run the test.

If we run it, we’ll see that one of our tests has failed. That’s great. It means our method has an issue. We can see it's the invalid:zero test case.

In the detail pane, we see org.opentest4j.AssertionFailedError: Expected java.lang.Exception to be thrown, but nothing was thrown.

Fixing the bug

The test case invalid:zero expected an exception to be thrown, but it isn’t currently. It’s not validating the “0” case and returns 0.

So let’s correct it now as follows.

public static int parsePositiveIntString(String value) throws Exception {
    int convertedValue = Integer.parseInt(value);
    if(convertedValue == 0) throw new Exception("0 cannot be accepted");
    return convertedValue;
}
CODE

And just re-run the test.

Fantastic, everything’s working as we expect.

Conclusion

Once you’re familiar with DevMate, the above process would take only a couple of minutes - way quicker than writing the code by hand. Furthermore, it can be done by technically oriented QA Engineers or Product Owners and is fully readable by Domain Experts and Product Managers if you want to involve them in the process.

This actually approach free up the developer to concentrate more heavily on writing functional code, which most developers will love.

As DevMate is clever but avoids black magic, DevMate generated tests fit beautifully into any development and CI/CD pipeline without any disruption, producing efficient, human readable and maintainable tests.