The SDK relies on JUnit, the most popular Java testing framework, to define and execute the tests.
It supports a subset of JUnit 4, namely the annotations: @After,
@AfterClass, @Before, @BeforeClass, @Ignore, @Test.
Each test case entry point must be declared using the org.junit.Test annotation (@Test before a method declaration).
Refer to JUnit documentation to get details on the usage of other annotations.
The JVMTestSuite plugin provides an enhanced model to declare multiple groups of automated testsuites,
and is therefore the recommended way to configure your tests.
The next sections use the JVMTestSuite plugin to explain how to configure and run tests, but the same results
can be achieved with the Test task.
Tests can be executed on the Simulator.
They are run on a target VEE Port and generate a JUnit XML report.
Executing tests on the Simulator allows to check the behavior of the code in an environment similar to the target device
but without requiring the board.
This solution is therefore less constraining and more portable than testing on the board.
This piece of configuration is the minimum configuration required to define a testsuite on the Simulator:
(1): configures all the testsuites of the project.
(2): configures the built-in test suite provided by Gradle. Use this testsuite to configure the tests on the Simulator.
(3): declares that this testsuite uses the MicroEJ Testsuite Engine. By default, the MicroEJ Testsuite Engine executes the tests on the
Simulator.
(4): adds the dependencies required by the tests. The first line declares a dependency to the code of the project.
The second line declares a dependency on the edc Library. The third line declares a dependency to the JUnit API used
to annotate Java Test classes. Finally the fourth line declares a dependency to a required JUnit library.
The VEE used to execute the tests must be declared in the project dependencies,
with the microejVee or the testMicroejVee configuration (refer to Select a VEE Port for more details on the selection capabilities).
A VEE declared with the microejVee configuration is used to run the Application, as well as to execute the testsuites.
The microejVee is generally used in Application projects, since the tests should run on the same Application target VEE:
A VEE declared with the testMicroejVee configuration is used only for the testsuites.
It is recommended in Library projects, since they don’t need a VEE to run, the VEE is scoped for the tests only:
If the VEE is declared with microejVee, it is used to run the Application (if it is an Application) and to execute the tests.
If the VEE is declared with testMicroejVee, it is only used to execute the tests.
Warning
Declaring a VEE in project dependencies only applies to the current project.
This configuration is not fetched transitively by consumer projects.
But it is highly recommended to scope the VEE to its usage since this behavior is aimed to change in a future version.
Especially when configuring the VEE to test a Library project, it is recommended to use testMicroejVee.
The SDK provides a JUnit library containing the subset of the supported JUnit API: ej.library.test:junit.
Before creating the Test class, make sure this library is declared in the testsuite dependencies:
The test class can now be created in the src/test/java folder.
This can be done manually or with IDE menu:
right-click on the src/test/java folder.
select New > Java Class, then press Alt + Insert and select TestMethod.
right-click on the src/test/java folder.
select New > Other… > Java > JUnit > New JUnit Test Case.
right-click on the src/test/java folder in JAVA PROJECTS view.
select the + icon (New…) > Class, then enter the test class name you want to create.
Note
Gradle allows to define alternative folders for test sources but it would require additional configuration,
so it is recommended to stick with the src/test/java folder.
Before running tests, at least one target VEE Port must be configured using one of the methods described in the Select a VEE Port page.
If several VEE Ports are defined, the testsuite is executed on each of them.
Once the testsuite is configured, it can be run thanks to the test Gradle task.
This task is bound to the check and the build Gradle lifecycle tasks,
which means that the tests are also executed when launching one of these tasks.
In order to execute the testsuite from IntelliJ IDEA or Android Studio, double-click on the task in the Gradle tasks view:
In order to execute the testsuite from Eclipse, double-click on the task in the Gradle tasks view:
In order to execute the testsuite from VS Code, double-click on the task in the Gradle tasks view:
In order to execute the testsuite from the Command Line Interface, execute this command:
Gradle automatically executes all the tests located in the test source folder.
If you want to execute only a subset of these tests, Gradle provides 2 solutions:
Filtering configuration in the build script file.
Filtering option in the command line.
The tests filtering configuration must be done in the filter block of the test task:
This example tells Gradle to run the tests located in the com.mycompany package only.
Other methods are available for test filtering, such as excludeTestsMatching to exclude tests.
Refer to the TestFilter
documentation for the complete list of available filtering methods.
As mentionned earlier, Gradle allows to filter the tests from the command line directly, thanks to the --tests option:
./gradlewtest--testsMyTestClass
This can be convenient to quickly execute one test for example, without requiring a change in the build script file.
Refer to the Gradle Test filtering
documentation for more details on how to filter the tests and on the available patterns.
Warning
At the moment, only class-level filtering is supported.
This means that, for instance, it is not possible to run a single test method within a test class.
Have a device connected to your workstation both for programming the Executable and getting the output traces.
Consult your VEE Port specific documentation for setup.
microej.testsuite.properties.deploy.bsp.microejscript: enables the build of the Executable. It is required.
microej.testsuite.properties.microejtool.deploy.name: name of the tool used to deploy the Executable to the board. It is required.
It is generally set to deployToolBSPRun.
microej.testsuite.properties.launch.test.trace.file: enables the redirection of the traces in file. If the VEE Port does not have this capability,
the Serial to Socket Transmitter tool must be used to redirect the traces to a socket.
microej.testsuite.properties.testsuite.trace.ip: TCP/IP address used by the Serial to Socket Transmitter tool to redirect traces from the board.
This property is only required if the VEE Port does not redirect execution traces.
microej.testsuite.properties.testsuite.trace.port: TCP/IP port used by the Serial to Socket Transmitter tool to redirect traces from the board.
This property is only required if the VEE Port does not redirect execution traces.
Any other property can be passed to the Test Engine by prefixing it by microej.testsuite.properties..
For example, to set the the Immortal heap size:
The SDK allows to run tests on a Java SE VM.
This can be useful, for example, when the usage of mock libraries like Mockito is
needed (this kind of library is not supported by the MicroEJ VM).
There is nothing specific related to MicroEJ to run tests on a Java SE VM.
Follow the Gradle documentation to setup such tests.
As an example, here is a typical configuration to execute the tests located in the src/test/java folder:
The SDK allows to define multiple testsuites on different targets.
For example, you can configure a testsuite to run tests on the Simulator and a testsuite to run tests on a device.
Configuring multiple testsuites is almost only a matter of aggregating the testsuite declarations documented in the previous sections,
as described in the Gradle documentation.
If you need to define a testsuite to run on the Simulator and a testsuite to run on a device,
the only point to take care is related to the tests source location, because:
Gradle automatically uses the testsuite name to know the tests source folder to use.
For example, for a testsuite named test (the built-in testsuite), the folder src/test/java is used,
and for a testsuite named testOnDevice, the folder src/testOnDevice/java is used.
Tests classes executed by the MicroEJ Test Engine on the Simulator and on device are not directly the tests source classes.
The SDK generates new tests classes, based on the original ones, but compliant with the MicroEJ Test Suite mechanism.
This process assumes by default that the tests classes are located in the src/test/java folder.
Therefore:
It is recommended to use the built-in test testsuite for either the tests on the Simulator or the tests on device.
This avoids extra configuration to change the location of the tests source folder.
The tests source folder of the other testsuite must be changed to use the src/test/java folder as well:
The important part is the sources block of the testOnDevice testsuite.
This allows to use the src/test/java and src/test/resources folders as the tests source folders.
With this configuration, all tests are executed on both the Simulator and the device.
If you want to have different tests for each testsuite, it is recommended to separate the tests in different packages.
For example the tests on the Simulator could be in src/test/java/com/mycompany/sim
and the tests on the device could be in src/test/java/com/mycompany/emb.
Then you use the test filtering capabilities to configure which package to run in which testsuite:
As explained in the previous section, it is recommended to use the built-in test testsuite for the tests on the Simulator
since it avoids adding confguration to change the tests sources folder.
With this configuration, tests on the Simulator are located in the src/test/java folder,
and tests on a Java SE VM are located in the src/testOnJavaSe/java folder.
The engine used to execute the testsuite provides a set of configuration parameters that can be defined with System Properties.
For example, to set the timeout of the tests:
The following configuration parameters are available:
Name
Description
Default
microej.testsuite.timeout
The time in seconds before a test is considered as failed. Set it to 0 to disable the timeout.
60
microej.testsuite.jvmArgs
The arguments to pass to the Java VM started for each test.
Not set
microej.testsuite.lockPort
The localhost port used by the framework to synchronize its execution with other frameworks on same computer.
Synchronization is not performed when this port is 0 or negative.
0
microej.testsuite.retry.count
A test execution may not be able to produce the success trace for an external reason,
for example an unreliable harness script that may lose some trace characters or crop the end of the trace.
For all these unlikely reasons, it is possible to configure the number of retries before a test is considered to have failed.
0
microej.testsuite.retry.if
Regular expression checked against the test output to retry the test.
If the regular expression is found in the test output, the test is retried (up to the value of microej.testsuite.retry.count).
Not set
microej.testsuite.retry.unless
Regular expression checked against the test output to retry the test.
If the regular expression is not found in the test output, the test is retried (up to the value of microej.testsuite.retry.count).
Not set
microej.testsuite.verbose.level
Verbose level of the testsuite output. Available values are error, warning, info, verbose and debug.
Standalone Application Options can be defined to configure the Application or Library being tested.
They can be defined globally, to be applied on all tests, or specifically to a test.
In order to define an Application Option globally,
it must be prefixed by microej.testsuite.properties. and passed as a System Property,
either in the command line or in the build script file.
For example, to inject the property core.memory.immortal.size:
In order to define an Application Option for a specific test,
it must be set in a file with the same name as the test case file,
but with the .properties extension instead of the .java extension.
The file must be put in the src/test/resources folder and within the same package than the test file.
For example, to inject an Application Option for the test class MyTest located in the com.mycompany package,
a MyTest.properties file must be created. Its path must be: src/test/resources/com/mycompany/MyTest.properties.
Application Options defined in this file do not require the microej.testsuite.properties. prefix.