Test generation
The test generator allows to generate testcases from a CommaSuite model by using the reachability graph.
Currently Java (JUnit) test generation is supported.
To enable test generation add the following to the .prj
file, e.g. using content assist (ctrl + space):
import "Camera.interface"
Project Camera {
// Generate the reachability graph, see the reachability graph documentation.
Generate ReachabilityGraph {
ReachabilityGraph_ICamera for interface ICamera
{
max-depth: 30
params: 'Camera.params'
debug
}
}
// Test generation
Generate Test {
// Test_IRetroCamera is the name of this task (can be anything).
// ReachabilityGraph_ICamera refers to the reachability graph task above.
Test_IRetroCamera for task ReachabilityGraph_ICamera {
// Enables the Java test generator.
java: {}
}
}
}
To generate the tests, run the .prj
(right click on the .prj
file → Run As → Run generators).
The output can be found in the src-gen
directory.
Java test generator
The Java test generator generates test cases based on JUnit.
An example is included in CommaSuite and can be imported by clicking File (left-top) → New → Example → Test Generation Example → Next → Finish.
Running the generator (right click on the .prj
file → Run As → Run generators) will generate the test cases under src-gen/test.interfaceCamera/TestCases.java
(which can be executed by right click on TestCases.java
→ Run As → JUnit Test):
package test.ICamera;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
@SuppressWarnings("unused")
public class TestCases {
private static final Adapter adapter = new Adapter();
@BeforeAll
public static void beforeAll() {
adapter.beforeAll();
}
@BeforeEach
public void beforeEach() {
adapter.beforeEach();
}
@AfterEach
public void afterEach() {
adapter.afterEach();
}
@AfterAll
public static void afterAll() {
adapter.afterAll();
}
@Test
public void testScenario1() throws InterruptedException {
/*
* Call command PowerOn()
*
* When calling command TakePicture() we should get:
* - Return value: Ok
*
* Call command PowerOff()
*
* Call command PowerOn()
*
* When calling command TakePicture() we should get:
* - Return value: Ok
*
* Call command PowerOff()
*
* Call command PowerOn()
*
* When calling command TakePicture() we should get:
* - Return value: OutOfSpace
*
* When calling command SetZoom(3) we should get:
* - Notification ZoomChanged with value 3
* - Return value: Ok
*/
var result0 = adapter.call("PowerOn", null);
var result2 = adapter.call("TakePicture", "Ok");
Assertions.assertEquals("Ok", result2.returnValue);
var result4 = adapter.call("PowerOff", null);
var result6 = adapter.call("PowerOn", null);
var result8 = adapter.call("TakePicture", "Ok");
Assertions.assertEquals("Ok", result8.returnValue);
var result10 = adapter.call("PowerOff", null);
var result12 = adapter.call("PowerOn", null);
var result14 = adapter.call("TakePicture", "OutOfSpace");
Assertions.assertEquals("OutOfSpace", result14.returnValue);
var result16 = adapter.call("SetZoom", "Ok", 3);
var result17 = adapter.waitForNotification("ZoomChanged", 3);
Assertions.assertTrue(result17);
Assertions.assertEquals("Ok", result16.returnValue);
}
...
}
The adapter
is responsible for doing the communication with the system under test (SUT). The (before|after)(All|Each)
methods allow the adapter to do any setup/teardown of the SUT.
The testScenario*
methods contain the test cases.
Each test case starts with a human readable description followed by the test code.
As can be seen above, methods are called and the return value (if any) is checked.
Also any expected notifications are checked.
The adapter code contains system specific logic and is therefore manually written.
The example can be found under src/test.interfaceCamera/Adapter.java
.
This adapter contains:
-
Classes to handle and check events generated by the SUT (
AutoResetEvent
,Event
,EventHandler
) -
The
call
method to execute a command/signal on the SUT with a given set of parameters. -
Before and after each call the
beforeEvent
andafterEvent
methods are called. These method can be used to trigger any non-standard behavior on the interface (e.g. an error situation which would normally not occur).
The Test Generation Example also contains an example for components.
The testcases can be found under src-gen/test.componentCamera/TestCases.java
.
In general, the Java test generator assumes a file Adapter.java is available in a package with the same name as the generated package that contains TestCases.java, i.e., “test.[name of component or interface]”.
Moreover, the execution of generated JUnit tests requires a few preparation steps (that have already been performed for the Test Generation Example):
-
Ensure JUnit 5 is available :
Right-click on project, select Build Path > Configure Build Path; select tab Libraries > Add Library > select JUnit5
-
Define src-gen as source folder:
Right-click on project, select Build Path > Configure Build Path; select tab Source > Add Folder > select src-gen