<build>
<plugins>
...
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<version>${munit.version}</version>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
MUnit Maven Plugin
MUnit provides a Maven plugin that enables you to run your MUnit tests as part of your continuous integration environment.
The following configurations to the pom.xml
or settings.xml
files of your Maven installation apply only when running MUnit through Maven.
Set Up MUnit Maven Plugin
You must have the <munit.version>
property in your pom.xml to set up MUnit Maven Plugin.
-
Enable MUnit Maven Plugin in your
pom.xml
file:MUnit Maven Plugin -
Add MUnit dependencies to your
pom.xml
file:Dependencies<dependencies> ... <dependency> <groupId>com.mulesoft.munit</groupId> <artifactId>munit-runner</artifactId> <version>${munit.version}</version> <classifier>mule-plugin</classifier> <scope>test</scope> </dependency> <dependency> <groupId>com.mulesoft.munit</groupId> <artifactId>munit-tools</artifactId> <version>${munit.version}</version> <classifier>mule-plugin</classifier> <scope>test</scope> </dependency> ... </dependencies>
-
Configure the repositories for the MUnit dependencies and plugin:
Repositories<repositories> <repository> <id>mulesoft-releases</id> <name>MuleSoft Releases Repository</name> <url>https://repository.mulesoft.org/releases/</url> <layout>default</layout> </repository> </repositories>
Plugin Repositories<pluginRepositories> <pluginRepository> <id>mulesoft-release</id> <name>mulesoft release repository</name> <layout>default</layout> <url>https://repository.mulesoft.org/releases/</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories>
MUnit has Surefire support built in. The reports output to target/surefire-reports .
|
Handle Parent POM Files
You can declare the MUnit plugin in a parent pom.xml
file and every child project under this file can reference this definition.
To configure MUnit Maven Plugin in a parent-child POM relationship, include the MUnit plugin declaration in the <pluginManagement>
section of your parent pom.xml
file.
In the following example, the pirate-pom
project declares MUnit Maven Plugin in its plugin management section. This section also defines a global configuration that each child under this parent can reference, override, or ignore.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.1.0</modelVersion>
<groupId>org.pirate</groupId>
<artifactId>pirate-pom</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<munit.version>2.3.0</munit.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<version>${munit.version}</version>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<coverage>
<runCoverage>true</runCoverage>
<failBuild>false</failBuild>
<requiredApplicationCoverage>0</requiredApplicationCoverage>
<requiredResourceCoverage>0</requiredResourceCoverage>
<requiredFlowCoverage>0</requiredFlowCoverage>
<formats>
<format>console</format>
<format>html</format>
</formats>
</coverage>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Inherit a Parent Plugin
To inherit the MUnit plugin in your child pom.xml
files, reference it in the <plugin>
section of each child POM file individually.
The following sample references the pirate-pom
file as its parent. It declares the MUnit plugin in a <plugin>
section without specifying its <version>
because the MUnit plugin configuration is inherited from the <pluginManagement>
section in the parent POM file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.pirate</groupId>
<artifactId>pirate-pom</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>ninja</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>mule</packaging>
<name>Mule ninja Application</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<app.runtime>4.1.4</app.runtime>
<munit.version>2.3.0</munit.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Ignore a Parent Plugin
Each child project under a parent pom.xml
file can ignore the plugin referenced in the parent plugin management section and not implement the plugin configuration declared there.
By not declaring the MUnit Plugin in your <plugin>
section, you avoid inheriting the plugin declared in pirate-pom:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.pirate</groupId>
<artifactId>pirate-pom</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>ninja</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>mule</packaging>
<name>Mule ninja Application</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mule.version>4.1.0</mule.version>
<munit.version>2.3.0</munit.version>
</properties>
<build>
<plugins>
<plugin>
</plugin>
</plugins>
</build>
</project>
Override a Parent Plugin
When inheriting the plugin from a parent POM file, you can also override the parent configuration. Overriding the plugin configuration from your parent POM file suppresses the original configuration requiring you to declare all necessary configurations again.
The following example overrides the console coverage report from its parent POM file, replacing it with the HTML report. Because the values from the other elements in the parent (<failBuild>
, <requiredApplicationCoverage>
, <requiredResourceCoverage>
, <requiredFlowCoverage>
) aren’t being referenced, this child file won’t inherit them and the default values are applied:
<coverage>
<runCoverage>true</runCoverage>
<failBuild>false</failBuild>
<requiredApplicationCoverage>0</requiredApplicationCoverage>
<requiredResourceCoverage>0</requiredResourceCoverage>
<requiredFlowCoverage>0</requiredFlowCoverage>
<formats>
<format>console</format>
<format>html</format>
</formats>
</coverage>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
<coverage>
<runCoverage>true</runCoverage>
<formats>
<format>html</format>
</formats>
</coverage>
</configuration>
</plugin>
Set Up Coverage
The following configurations only apply when you execute your MUnit tests using the Maven plugin. They don’t apply when running tests from Studio. See Using Coverage in Maven for additional information.
From MUnit 2.x and later, the coverage report goal is integrated with the Maven reporting section. MUnit generates coverage reports during the Maven site
lifecycle, during the coverage-report
goal.
The following configurations apply if you execute your MUnit tests using the Maven plugin. They don’t apply when running tests from Anypoint Code Builder or Anypoint Studio.
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<version>${munit.version}</version>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
<goal>coverage-report</goal>
</goals>
</execution>
</executions>
<configuration>
<coverage>
<runCoverage>true</runCoverage>
<failBuild>false</failBuild>
<requiredApplicationCoverage>75</requiredApplicationCoverage>
<requiredResourceCoverage>50</requiredResourceCoverage>
<requiredFlowCoverage>50</requiredFlowCoverage>
<formats>
<format>console</format>
<format>html</format>
</formats>
</coverage>
</configuration>
</plugin>
Set up a Minimum Coverage Level
One of the features of MUnit Coverage is to fail the build if a certain coverage level isn’t reached.
MUnit Coverage handles three different levels:
-
Application: The overall coverage of all your application.
-
Resource: The coverage level of each Mule configuration file.
-
Flow: The coverage of event processors in each flow.
To define the required coverage levels:
<coverage>
<runCoverage>true</runCoverage>
<failBuild>true</failBuild>
<requiredApplicationCoverage>75</requiredApplicationCoverage> (1)
<requiredResourceCoverage>50</requiredResourceCoverage>
<requiredFlowCoverage>50</requiredFlowCoverage>
</coverage>
1 | Each value represents a percentage. If a percentage isn’t defined, it defaults to -1, which sets no requirements for said level so the build doesn’t fail due to low coverage. |
If you define coverage levels but set the property failBuild
to false
, and then the levels aren’t reached, a warning shows up in the MUnit Coverage summary:
===============================================================================
MUnit Coverage Summary
===============================================================================
* Resources: 2 - Flows: 3 - Processors: 4
* Application Coverage: 75.00%
----------------------------- WARNING --------------------------------------
* Flow: file2.xml -> file2Flow1 coverage is below defined limit. Required: 50.0% - Current: 00.00% (1)
====================================================================================
1 | Warning detailing which coverage level isn’t met, and where it happens. |
Ignore a Flow or a File
You can also ignore a flow or a file. This way, the ignored resource:
-
Does not count as coverage data.
-
Does not affect the overall number of message processors.
-
Does not cause a build to fail if the flow isn’t tested or if the flow doesn’t reach coverage metrics.
To ignore flows and files:
<coverage>
<runCoverage>true</runCoverage>
<failBuild>true</failBuild>
<requiredApplicationCoverage>100</requiredApplicationCoverage>
<requiredResourceCoverage>100</requiredResourceCoverage>
<requiredFlowCoverage>100</requiredFlowCoverage>
<ignoreFlows>
<ignoreFlow>flow-1</ignoreFlow>
<ignoreFlow>flow-2</ignoreFlow>
...
<ignoreFlow>flow-n</ignoreFlow>
</ignoreFlows>
<ignoreFiles>
<ignoreFile>mule-config-1.xml</ignoreFile>
<ignoreFile>mule-config-2.xml</ignoreFile>
...
<ignoreFile>mule-config-n.xml</ignoreFile>
</ignoreFiles>
</coverage>
Dynamic Ports
MUnit 2.2 and later introduce the dynamic-port
global element, that allows you to define dynamic ports at the MUnit suite level. Using this element instead of the plugin configuration described as follows allows you to set the dynamic port both from Maven and Studio.
See Dynamic Ports to learn how to configure this element.
When testing a Mule application in a continuous integration (CI) environment, you might encounter the following scenario:
Your application tries to open a specific port. The port is already in use. The application fails with a port binding exception.
The MUnit Maven Plugin comes with a built-in feature to make your application use a free port.
MUnit Dynamic Ports instructs the MUnit Maven Plugin to look for unbound ports and reserve them before running the tests over the Mule application. Each port selected is placed in a system property under the name indicated in the configuration. The application can get the port number through the use of placeholders afterward.
The plugin selects the ports from the range: [40000,50000]
Dynamic Ports feature is only available as part of the MUnit Maven Plugin. This feature does not work when running tests in Anypoint Studio. |
Enable Dynamic Ports
To enable the feature, you must add the following code to the configuration
section of the MUnit Maven Plugin:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<dynamicPorts>
<dynamicPort>a.dynamic.port</dynamicPort>
</dynamicPorts>
...
</configuration>
</plugin>
</plugins>
If you have the ${http.port}
placeholder in your application, the configuration looks something like:
<dynamicPorts>
<dynamicPort>http.port</dynamicPort>
</dynamicPorts>
Prepare Your Application
A placeholder must parameterize the part of the application trying to make use of a port. For example, to have your Mule application listening for HTTP traffic, provide the following configuration:
<http:listener-config name="HTTP_Listener_config">
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<flow name="httpFlow">
<http:listener path="/" config-ref="HTTP_Listener_config"/>
</flow>
The previous application always listens in port 8081
. To make it dynamic, change it to:
<http:listener-config name="HTTP_Listener_config">
<http:listener-connection host="0.0.0.0" port="${http.port}"/> (1)
</http:listener-config>
<flow name="httpFlow">
<http:listener path="/" config-ref="HTTP_Listener_config"/>
</flow>
1 | Notice the placeholder ${http.port} . |
With the application coded in this way and the configuration of Dynamic Ports in place, your application starts each run listening on a different port.
Enable Surefire Reports
MUnit has built-in support for Surefire. You mustn’t do additional configurations, and you can disable it if not needed:
<enableSurefireReports>false</enableSurefireReports>
You can find the reports under ${project.build.directory}/surefire-reports
.
By default, it’s set to true
.
Enable Sonar Reports
MUnit has built-in support for SonarQube, with a default setting of true
for enableSonarReports
. No other configuration is required.
You can find the reports under ${project.build.directory}/sonar-reports
.
You can disable SONAR reports if not needed:
<enableSonarReports>false</enableSonarReports>
You can find the reports under ${project.build.directory}/sonar-reports
.
By default, it’s set to true
.
Run Tests Using the Plugin
Run MUnit Tests for a Mule Application
mvn clean test
Run a Specific MUnit Test Suite
By using the property munit.test
, you can instruct the MUnit Maven plugin to run certain tests that belong to a specific test suite:
mvn clean test -Dmunit.test=<regex-test-suite>
This path is relative to src/test/munit
.
The property munit.test
accepts regular expressions. The expression is applied to the name of the MUnit Test Suite file. The regular expression language is the Java implementation.
For example:
mvn clean test -Dmunit.test=.*my-test.*
You can leverage this feature by adding naming conventions to your MUnit Test suites.
Run Specific MUnit Tests
In the same way that you instruct MUnit to run one test suite, you can also configure it to run a specific test in that test suite. You must use the property munit.test
with the addition of the special character #
to append the test name:
mvn clean test -Dmunit.test=<regex-test-suite>#<regex-test-name>
It also accepts regular expressions. The expression is applied to the attribute name
of the MUnit Test. For example:
mvn clean test -Dmunit.test=.*my-test.*#.*test-scenario-1.*
MUnit flags the tests in the MUnit Test Suite that don’t match the regular expression as ignored.
You can also configure this from the pom.xml
configuration:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<munitTest>example-MunitTest-suite.xml</munitTest>
...
</configuration>
</plugin>
</plugins>
Run Tests Using a Specific Tag
You can run the tests that you grouped under one specific tag:
mvn clean test -Dmunit.tags=<munit-tag>
You can also configure this from the pom.xml
configuration:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<munitTags>exampleMunitTag</munitTags>
...
</configuration>
</plugin>
</plugins>
You can specify more than one tag by separating them with a comma.
Skip All Tests
MUnit leverages the same mechanism as Maven. To skip tests, you must use the skipTests
parameter:
mvn clean package -DskipTests
You can also configure this from the pom.xml
configuration:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<skipMunitTests>true</skipMunitTests>
...
</configuration>
</plugin>
</plugins>
Skip Tests After One Suite Fails
MUnit allows you to skip the rest of the tests if one test suite fails:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<skipAfterFailure>true</skipAfterFailure>
...
</configuration>
</plugin>
</plugins>
If not specified, it’s default value is false
.
Specify the Runtime Product
You can specify the type of runtime in which the applications you test run. Accepted values are:
-
MULE
for the Mule Kernel (formerly called Mule Community Edition) -
MULE_EE
for the Mule Enterprise Edition
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<runtimeProduct>MULE</runtimeProduct>
...
</configuration>
</plugin>
</plugins>
Specify the Runtime Product Version
You can specify the runtime version in which the applications you test run.
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<runtimeVersion>4.2.2</runtimeVersion>
...
</configuration>
</plugin>
</plugins>
Specify the JVM
You can specify the JVM (or the Java executable) in which the applications you test run. You must populate the munit.jvm
parameter with the path to the executable:
mvn clean package -Dmunit.jvm=/path/to/jdk/bin/java
You can also configure this from the pom.xml
configuration:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<jvm>/path/to/jdk/bin/java</jvm>
...
</configuration>
</plugin>
</plugins>
Additional Argument Lines
You can pass additional argument lines to the JVM. Specify each argument in a separate argLine
:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<argLines>
<argLine>-XX:MaxPermSize=512m</argLine>
<argLine>-Xmx1024m</argLine>
</argLines>
...
</configuration>
</plugin>
</plugins>
Environment Variables
To set additional environment variables during the test run, you can specify them with the respective key and value:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<environmentVariables>
<MY_ENV>exampleValue</MY_ENV>
<MY_OTHER_ENV>val2</MY_OTHER_ENV>
</environmentVariables>
...
</configuration>
</plugin>
</plugins>
As shown in the previous example, you can use environment variables to replace placeholders such as ${MY_ENV}
.
System Properties Variables
If you must define specific system variables to run your MUnit test successfully:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<systemPropertyVariables>
<my.property.key>my.property.value</my.property.key>
</systemPropertyVariables>
...
</configuration>
</plugin>
</plugins>
Depending on the execution context, the system property values can vary. When referencing these properties, you must override their value to enforce test reproducibility.
You can do so by using the -D
argument when running MUnit with Maven. Variables passed with the -D
argument take full priority over any other property. For example:
-Dmy.property.key=my.property.another.value
Redirect Test Output to File
When running several tests, the build output can get very complex to read. MUnit allows you to redirect the output of each test suite to a file. This way, the test results remain in the build output and you can check the respective file to check the standard output of each test suite.
You can find these files in the testOutputDirectory
folder following the naming convention: munit.${suiteName}-output.txt
, where suiteName
represents the name of the XML file relative to the MUnit test folder.
The test output that doesn’t belong to a particular suite isn’t printed to keep the build output clean. You can enable it by running Maven in debug mode.
To redirect the output of each test suite to a file:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<redirectTestOutputToFile>true</redirectTestOutputToFile>
...
</configuration>
</plugin>
</plugins>
By default, it’s set to false
.
Test Output Directory
If you want to choose the location where the test creates the output files, the path specified can be absolute or written as a Maven placeholder:
<plugins>
<plugin>
<groupId>com.mulesoft.munit.tools</groupId>
<artifactId>munit-maven-plugin</artifactId>
<configuration>
...
<testOutputDirectory>/my/absolute/path</testOutputDirectory>
...
</configuration>
</plugin>
</plugins>
<testOutputDirectory>${project.build.directory}/my/output/folder</testOutputDirectory>
By default, the files are created in ${project.build.directory}/munit-reports/output/
.
MUnit Maven Plugin Configuration Reference
The MUnit Maven Plugin offers a set of optional configurable parameters.
Name | Type | Description |
---|---|---|
|
List |
Additional JVM argument lines to set on the test run. |
|
Configuration |
Coverage configuration to set on the test run. |
|
List |
Dynamic ports to set on the test run. |
|
boolean |
Set value to |
|
String |
Name of the MUnit tests to run. |
|
String |
Name of the MUnit tags. Tests tagged with these names run. |
|
boolean |
Setting this parameter to |
|
boolean |
Skip all tests if one fails. |
|
File |
Directory where the MUnit tests reside. |
|
String |
Version of the Mule runtime |
runtimeProduct |
String |
Type of runtime. Expected values are:
By default, this value comes from the |
|
String |
Option to specify the JVM (or path to the Java executable) to use. By default, the JVM is the same VM as the one used to run Maven. |
|
Map |
Additional environment variables to set on the test run. |
|
boolean |
Setting this value to |
|
Map |
System properties set on the test run. |
|
File |
Directory where the test outputs are written. |