Automation Testing Framework
With the Automation Testing Framework, you can test the logic of scripts that use the published APIs. It supports writing tests with common frameworks like JUnit or Spock and running them with DaVinci Configurator 6’s features. It provides possibilities to write tests with a common testing framework (like JUnit or Spock) and execute them with the functionality of the DaVinci Configurator 6.
How to enable the testing framework
scriptProject {
//Path to the CFG
cfgPath = file("${cfgPath}")
classes = ["MyScript"]
bswmd {
bswPath = file("${bswPath}")
}
//Test Execution
testing{
bswPath = file("${bswPath}")
}
}
Additionally the testing dependencies have to be added.
See chapter Managing Dependencies for more information.
Source Set 'testCfg'
The testing framework is based on the
testCfg source set[1], which is automatically enabled when you activate the testing framework in your project.
See How to enable the testing framework for more information.
In addition to the testCfg source set, the standard test source set can be used without script support.
Gradle Task 'testCfg'
To run the tests, you can use the gradlew testCfg command.
This gradle task will execute all tests in the testCfg source set.
The testCfg task will automatically get executed when you run the build task.
Writing basic tests
You can write tests using a common testing framework of your choice. While Spock is the preferred method, JUnit works as well.
These tests must be located in the src/testCfg directory of your script project.
In the example GetDpaProjectNameTest you see a Spock test that uses a DaVinci Configurator 6 project to test the functionality of a script. Using DaVinci Configurator 6 projects in your tests can be simplified by an annotation, which is described in chapter sec:TestProjectLoadAnnotation.
class GetDpaProjectNameTest extends Specification {
@Shared
IProjectRef projectRef = ScriptApi.scriptCode.projects.parameterizeProjectLoad {
it.projectFile = Paths.get("%CFG_PROJECT_PATH%")
}
@Shared
@TestProjectLoad
ITestProjectRef projectRefExtShared = ITestProjectRef.forProject(projectRef)
def "Test read project name"() {
when:
String origin = GetProjectName.getDpaProjectName()
then:
origin == "WorkshopProject"
}
static String getDpaProjectName() {
def name = ""
ScriptApi.scriptCode {
projects.activeProject {
name = project.getProjectName()
scriptLogger.info("Work with the project: " + name + ".dvjson")
}
}
return name
}
}
The %CFG_PROJECT_PATH% placeholder must be replaced with the path of the DaVinci Configurator 6 project you want to test.
Plugin configuration
Following properties can be set in the testCfg configuration:
cfgPath property specifies the path to the DaVinci Configurator 6
which should be used to run the tests.
The bswPath property specifies the path to the BSW package
which is used to run the tests.
The additionalVmArgs property allows you to specify
additional JVM arguments for the test execution.
Managing Dependencies
For adding test dependencies to your project, you should use the testCfg configuration.
testCfgImplementation libs.spock
testCfgImplementation platform(libs.junitBom)
testCfgImplementation libs.junitApi
testCfgImplementation libs.junitEngine
The template contain some of them with a compatible version in the libs.version.toml file, so you can use them directly in your build.gradle file.
Model TestInfrastructure
The ITransactionUndoAllExtension class provides a JUnit Extension, which will undo all transaction after the
JUnit test was executed. This can be used as static or instance field to undo for the whole test class or for each test case.
Note: This extension does not work with Spock.
public class ProjectLoadTest {
@RegisterExtension
static ITransactionUndoAllExtension extension = ITransactionUndoAllExtension.forActiveProject(); // Undo changes after ALL test cases.
public class ProjectLoadTest {
@RegisterExtension
ITransactionUndoAllExtension extension = ITransactionUndoAllExtension.forActiveProject(); // Undo changes after EACH test case.
class TransactionUndoAllExtensionTest {
@RegisterExtension
ITransactionUndoAllExtension rule = ITransactionUndoAllExtension.forActiveProject();
@Test
void testcase() {
//After this test case all transactions are reverted by the TransactionUndoAllExtension
}
class TransactionUndoAllExtensionWithLimitTest {
@RegisterExtension
ITransactionUndoAllExtension rule = ITransactionUndoAllExtension.forActiveProject(50);
@Test
void testcase() {
//After this test case all transactions are reverted by the TransactionUndoAllExtension
}
Load a Project in a JUnit Test
The IProjectLoadExtension class provides a JUnit 5 Extension, which will load the passed IProjectRef
before test execution and close it afterward. This can be used as an JUnit 5 Extension.
public class ProjectLoadExtensionTest {
@RegisterExtension
static IProjectLoadExtension extension = IProjectLoadExtension.forProject(ScriptApi.scriptCode.projects.parameterizeProjectLoad{
dpaFile "YourProject.dpa"
})
@Test
public void testcase() {
//In this test the project was loaded and will be closed after all tests.
}
For details about the how to load a project, or if you want to load only
an .arxml file, please refer to the AutomationInterfaceDocumentation.
Load a Project in a Spock Test
Use the TestProjectLoad spock annotation to load a test project.
The internals will take care of opening/closing the project.
If you are using the spock.lang.Shared annotation, the given test project will be opened/closed once for the whole specification, meaning it will be shared over all feature methods.
If you don't use the spock.lang.Shared annotation, the given test project will be opened/closed after each feature method.
Note: This annotation needs as input an IProjectRef, which has to be provided by the ITestProjectRef.forProject, see example below.
@Shared
@TestProjectLoad
ITestProjectRef testProjectRefShared = ITestProjectRef.forProject(ScriptApi.scriptCode.projects.parameterizeProjectLoad { dpaFile = "./MyProject.dpa" })
testProjectRefShared.project
IProject can be accessed.Test and Debug productive Tasks with the Testing Framework
To test and debug a script task in a fast and convenient way, you can use the testing framework.
For this, a test will be set up that executes the task you want to test or debug. You can set breakpoints in your script and debug the test.
With the testing framework, you have control over the task execution environment. This means you can provide a bsw package, a DaVinci Configurator 6 project and user defined arguments.
Attention: Tests which executes a whole script task can take some time, especially if a project will be loaded. You can classify or disable these test with the common Spock/Junit mechanisms.
Test a DV_APPLICATION task
To call a DV_APPLICATION task:
scriptTask("SimpleTask", DV_APPLICATION) {
taskDescription 'Task description - Prints "HelloWorld" to console.'
code {
scriptLogger.info "!!!Hello World!!!"
return "SimpleTask executed"
}
}
You can write a spock test and test/debug the task:
def "Debug simple task"() {
when:
def result = ScriptApi.scriptCode().scripts.callScriptTask("SimpleTask")
then:
result == "SimpleTask executed"
}
Test a task with userdefined arguments
To call a task with userdefined arguments:
scriptTask("SimpleTaskWithParams", DV_APPLICATION) {
def nameArg = newUserDefinedArgument("name", String, "My String Param")
def value = newUserDefinedArgument("value", Integer, "My Integer Param")
code {
return "name: $nameArg.value, value: $value.value"
}
}
You can write a spock test and test/debug the task:
def "Debug task with params"() {
when:
def result = ScriptApi.scriptCode().scripts.callScriptTaskWithUserArgs("SimpleTaskWithParams", "--name=Hello --value=42")
then:
result == "name: Hello, value: 42"
}
Test a DV_PROJECT task
To call a DV_PROJECT task:
scriptTask("ProjectTask", DV_PROJECT) {
code {
activeProject().getProjectName()
}
}
You can write a spock test and test/debug the task:
def "Debug task with project"() {
when:
def result = ScriptApi.scriptCode().projects.openProject("%CFG_PROJECT_PATH%") { scripts.callScriptTask("ProjectTask") }
then:
result == "WorkshopProject"
}
Attention:
The project will not be saved by default. But if the script contains asaveProjectcall, the project will be saved and persisted. See