Testing¶
The COOM DSL has support for regression tests that simulate configuration sessions. At runtime, each test is executed by the reasoning engine.
A test case is a COOM block, similar to structure
or behavior
, with one key difference: statements in a test are evaluated strictly in sequence.
- Define a test with a
test { ... }
block.- To define a test for a specific structure, provide its name like
test Wheel { ... }
. - Without a name, the test is defined at the root level.
- To define a test for a specific structure, provide its name like
- The test body contains a sequence of statements (order matters, unlike in
behavior
). - Execution starts from an empty configuration:
- Instances required by the minimum cardinality of features are created automatically.
- All other instances must be created explicitly.
Minimal example¶
// test defined at root level
test {
// set feature "wheelSupport" to option "Yes"
set wheelSupport = Yes
// assert that option "W14" remains selectable for feature "wheels"
isAvailable wheels = W14
}
Test statements¶
The following statements are available inside a test
block.
1. define <name> = <expression>
¶
Creates a local alias <name>
for a path or value, usable within the same test { ... }
block only.
2. load <name>
¶
Loads an existing configuration into the test environment and verifies that it is satisfiable. In KnowWE, configurations can be loaded from stored attachments; outside KnowWE, for example from files.
3. set <path>
and set <path> = <value>
¶
Set statements have three functions:
- Creates instances if needed.
- Assigns feature values.
- Verifies that the resulting configuration is satisfiable.
Instances are created automatically when:
- Setting a value on a not-yet-existing instance:
set bags[1].size = small
- Setting a subrange where instances do not yet exist:
set bags[2..3].size = small
- Explicitly setting a structural feature:
set bags
(creates all requiredbags
) orset bags[3..4]
Note: set bags.size = small
updates only existing bags
instances.
test {
// assign concrete values
set wheelSupport = Yes
set wheels = W14
// ensure that 6 bags exist (indices 0..5)
set bags[0..5]
// set the size of those 6 existing bags to "small"
set bags.size = small
// create instances 7 and 8 and set their size to "big"
set bags[6..7].size = big
}
4. remove <path>
¶
Removes one or more feature values at <path>
.
Removal is assumed to be always valid; no satisfiability check is performed.
5. reset <path>
¶
Clears all values at <path>
.
If <path>
points to an instance, all of its descendant values are cleared recursively.
Instances are not removed. Reset is assumed to be always valid; no satisfiability check is performed.
6. isAvailable <path> = <value>
¶
For single-valued enumeration features only.
Checks the set of available options at <path>
and asserts that <value>
is still selectable.
7. isBlocked <path> = <value>
¶
For single-valued enumeration features only.
The negation of isAvailable
: asserts that <value>
is not selectable at <path>
.
8. isFixed <path>
and isFixed <path> = <value>
¶
Solves the configuration and asserts that each feature at <path>
has exactly one remaining value in the solution space.
Without = <value>
, it only checks uniqueness; with = <value>
, it also checks equality.
9. isShown <path>
and isShown <path> = <value>
¶
Solves the configuration and asserts that:
- the feature at
<path>
is visible (not hidden), and - its value is at least a default (i.e., not solely a random choice by the engine),
- and, if
= <value>
is provided, that the value matches.
10. isEmpty <path>
¶
Solves the configuration and asserts that the feature at <path>
either has no value or only a random choice (implying multiple values remain possible).
Annotations¶
Test cases have to well known annotations:
@label
on atest
block to provide a human-readable name.@explanation
on individual statements to document intent.
Example: