Skip to content

verhas/yamaledt

Repository files navigation

Patuyaja — JUnit 5 Parameterized Tests Using Yaml and Jamal

Introduction and usage

Note
This is the latest development documentation. This is a SNAPSHOT version. To see the documentation of a release you have to follow the link in the documentation RELEASES.adoc

You can create parameterized unit tests fetching the data from Yaml formatted resource file using Patuyaja. To use the possibility add the dependency to your build configuration. In case of Maven, for example, add the following lines to your dependencies configuration part:

<dependency>
    <groupId>com.javax0.yamaledt</groupId>
    <artifactId>yamaledt</artifactId>
    <version>1.1.3-SNAPSHOT</version>
    <scope>test</scope>
</dependency>

The next step is to create a parameterized test, and the Yaml file that holds the data set for the tests.

    @ParameterizedTest(name = "{0}")
    @YamlSource()
    void sampleTestWithSimpleParameters(@Name("DisplayName") String dn,
                                        int i,
                                        @Name("k") int k) {
        Assertions.assertEquals(5, i + k);
    }

The JUnit 5 annotation @ParameterizedTest signals that this test is a parameterized test. The annotation @YamlSource specifies the test data source. In this case all the settings are the default, there are no arguments. The data will be read from the resource file sampleTestWithSimpleParameters.yaml. The name is calculated from the name of the test method, and the extension .yaml is appended to it.

The Yaml data source file contains the data in the format:

"adding zero to five is five":
  int: 5
  k: 0
"adding one to four is five":
  int: 4
  k: 1
"adding three to two is five":
  k: 3
  int: 2
"using negative number is also okay":
  k: -1
  int: 6

The Yaml file describes a Map structure. The keys are the test names. These are the strings that will get into the place of the strings, which are defined using the @DisplayName annotation in non-parameterized tests. The value for each test is also a Map specifying the values for the test parameters.

The mapping of values can be based on

  • the type of the method arguments, or

  • the value of the annotation @Name.

In the example above we have three parameters.

  • One is named using @Name("DisplayName"),

  • one unnamed, and

  • one named using @Name("k").

In the Yaml file the main key, is used for the parameter named 'DisplayName'. For the unnamed parameter the type is used, which is, in this case is int. Finally, the last parameter gets the value from the map using the key k.

Running this test from an IDE will result a view something like this:

idea sample run

Annotation @YamlSource

The annotation @YamlSource is used to specify parameters for the test. You have to use it together with the annotation @ParameterizedTest.

You have to use this annotation on the test method. The use of the annotation instructs JUnit 5 to execute the test as a parameterized test, and to use the YamalArgumentsProvider, which implements the Yaml data source handling for parameterized tests. The annotation can define parameters for the parameters, like the name of the Yaml file.

The annotation can also be applied to the enclosing class. This is useful in case annotation parameters are shared by multiple test methods. The annotation on the class can define these parameters, and the methods inherit the value from there. For example, you can use the same single Yaml file for test parameter storage and provide an OGNL expression to point to the data of the individual tests. In this case the name of the file can be provided on the class, shared, and the different OGNL expressions can be defined in the annotations on the methods.

The parameters of the annotation are:

  • value may specify the file that holds the test data. If it is not specified then the name of the name of the test method will be used with the extension .yaml.jam or .yaml. The extension .yaml.jam is used by default. The extension .yaml is used when the @Jamal annotation enabled=false disables the Jamal processing. If there is a specified value, then the value is used as a resource name, and no extension is appended to the name. That way you have to specify @YamlSource("testData.yaml"). The name of the method is only considered a file name if the annotation does not define a value on the method and also not on any of the enclosing classes.

  • jamal may specify a @Jamal annotation. The use of this parameter is not recommended. The same result can be achieved adding the @Jamal annotation directly on the test method or on the class containing the test method.

  • ognl may specify an OGNL expression. If this value is defined then the test environment uses only the structure pointed by this expression as test data. Using this along with putting a @YamlSource annotation on the class you can use

Annotation @Jamal

The annotation @Jamal is used to specify parameters for the input Jamal processing.

Jamal is a general purpose text preprocessor that can go to extreme to eliminate input redundancy and copy-paste. This way the data structures that appear repeatedly in the test data structure can be described programmatically. Jamal supports Yaml data structure handling through an extension module, and the Jamal transformation process can be debugged via Web user interface. The core Jamal modules as well as the debugger module, yaml and snippet handling modules are included in the project dependencies. If you want to use any other module you need to add those to the project as a dependency.

For more information about Jamal read the documentation at https://github.com/verhas/jamal

The parameters of the annotation are

  • open can specify the macro opening string. This is {% by default.

  • close can specify the macro closing string This is %} by default.

  • enabled can be used to disable Jamal processing on the input. The default is to interpret the input as a macro text that results Yaml as output. Use @Jamal(enabled=false) annotation on the method to disample Jamal processing. When Jamal processing is disabled the default file name extension will be .yaml when the parameter resource name is calculated from the method name.

  • dump can be used to specify a file name where the output of the Jamal processing in written. This content does not need to be written into a file. It is processed in memory usually. This option is only provided in case you want to look at the generated, already pure Yaml formatted file.