TDL step constructs¶
Overview¶
TDL step constructs are used to capture a test case’s core testing logic. They are used in test cases and also in Scriptlets to define their sequence of test steps. The available test steps are described in the sections that follow, organised in four main categories:
- Messaging steps used to exchange information between actors.
- Processing steps to perform complex arbitrary processing.
- Flow steps to manage the execution flow of the test case.
- Support steps to introduce support features to test cases.
Messaging steps¶
Messaging steps allow the test case to handle the exchange of messages between actors. The actual implementation allowing content to be sent or received is implemented by a messaging handler (see Messaging handlers).
btxn¶
The btxn
step stands for “Begin transaction”. Its purpose is to define a scope around a set of messaging
steps that have a logical relation to each other. This scope remains active until a etxn
element is
encountered to end it. The structure of the btxn
element is as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | A string ID for the transaction. |
@from | yes | The ID of the actor that acts as the messaging source (see Actors). |
@to | yes | The ID of the actor that acts as the messaging target (see Actors). |
@handler | yes | A string value or variable reference identifying the messaging handler to use for the transaction (see Specifying the handler implementation). |
property | no | Zero or more elements to provide configuration regarding the setup of the messaging handler call that are not passed to the handler. Each property element has a name attribute and a text content or variable reference as value. |
config | no | Zero or more elements to provide configuration when creating the transaction. Each config element has a name attribute and a text content or variable reference as value. |
Executing the btxn
step results in a call to the messaging handler specified by the handler
attribute. This gives it an
opportunity to take any actions needed for the upcoming transaction and apply specific configurations for its related send
and receive
calls.
<btxn from="Actor1" to="Actor2" txnId="t1" handler="SoapMessaging"/>
<send id="dataSend" desc="Send data" from="Actor1" to="Actor2" txnId="t1">
<input name="soap_message">$soapMessage</input>
</send>
<receive id="dataReceive" desc="Receive data" from="Actor2" to="Actor1" txnId="t1"/>
<etxn txnId="t1"/>
Note that btxn
steps are not presented to the user.
etxn¶
The etxn
step stands for “End transaction” and acts as the counterpart to a btxn
element by referencing its transaction
ID. It is structured as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | The identifier of the transaction to end. |
Executing the etxn
results in a call to the transaction’s messaging handler to take necessary actions such as resource clean-up.
<btxn from="Actor1" to="Actor2" txnId="t1" handler="SoapMessaging"/>
<send id="dataSend" desc="Send data" from="Actor1" to="Actor2" txnId="t1">
<config name="soap.version">1.2</config>
<input name="soap_message">$soapMessage</input>
</send>
<receive id="dataReceive" desc="Receive data" from="Actor2" to="Actor1" txnId="t1"/>
<etxn txnId="t1"/>
Note that etxn
steps are not presented to the user.
send¶
The send
step allows the test bed to signal that content needs to be sent from one actor to another. This operation needs to be
part of a transaction created by btxn
, the identifier of which it references. The structure of the send
element is as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | The ID of the transaction this send belongs to. |
@from | yes | The ID of the actor that will be sending the message (see Actors). |
@to | yes | The ID of the actor that will be receiving the message (see Actors). |
@desc | yes | A description to display to the user for this test step. |
@id | no | The ID for the step. This is also the name of a map variable in the session context in which output will be stored. |
documentation | no | Rich text content that provides further information on the current step. |
config | no | Zero or more elements containing configuration values pertinent to sending. Each config element has a name attribute and a text content or variable reference as value. |
input | no | Zero or more elements for the input parameters. See Handler inputs and outputs for details. |
The send
step results in the transaction’s messaging handler to be notified that it needs to send content. Recall that the actual
sending always takes place through the message handler implementation. The send
step simply acts as the signal to do so.
<btxn from="Actor1" to="Actor2" txnId="t1" handler="SoapMessaging"/>
<send id="dataSend" desc="Send data" from="Actor1" to="Actor2" txnId="t1">
<config name="soap.version">1.2</config>
<input name="soap_message">$soapMessage</input>
</send>
<etxn txnId="t1"/>
receive¶
The receive
step is the counterpart of send
signalling that an actor is expected to receive a message from another. This
operation needs to be defined as part of a transaction created by btxn
, the identifier of which it references. The structure
of the receive
element is as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | The ID of the transaction this receive belongs to. |
@from | yes | The ID of the actor that will be sending the message (see Actors). |
@to | yes | The ID of the actor that will be receiving the message (see Actors). |
@desc | yes | A description to display to the user for this test step. |
@id | no | The ID for the step. This is also the name of a map variable in the session context in which output will be stored. |
@timeout | no | An optional timeout (in milliseconds) on the time to wait for a message to be received. This is provided as a number or a variable reference. |
@timeoutFlag | no | An optional name for a boolean flag to record whether or not the timeout was triggered that will be stored in the result map named using the id attribute. This is provided as a string or a variable reference. |
@timeoutIsError | no | Whether or not a timeout being triggered should be considered as an error or success (the default). This is provided as a boolean or a variable reference. |
documentation | no | Rich text content that provides further information on the current step. |
config | no | Zero or more elements containing configuration values pertinent to receiving. Each config element has a name attribute and a text content or variable reference as value. |
input | no | Zero or more elements for the signal’s input parameters. See Handler inputs and outputs for details. |
output | no | Zero or more elements for the resulting output values. See Handler inputs and outputs for details. |
When the test bed executes the receive
step it performs two actions:
- It signals the transaction’s messaging handler that content is expected to be received.
- It blocks waiting for a call-back from the messaging handler that will contain the received data, or until the configured timeout has elapsed.
Regarding the input
elements provided these act as information provided to the messaging handler that are relevant to the
message’s reception. They act as a counterpart to config
elements whose purpose is more to signal parameters for the communication
setup rather than the involved message. The output
elements provided are optional and serve only to restrict the messaging handler’s
output (returned via its call-back to the test bed) to the specified values. If not specified all available output values are returned.
<btxn from="Actor1" to="Actor2" txnId="t1" handler="SoapMessaging"/>
<receive id="dataReceive" desc="Receive data" from="Actor2" to="Actor1" txnId="t1">
<config name="soap.version">1.2</config>
</receive>
<!--
Example using timeouts (that are considered as an error).
-->
<receive
id="dataReceiveTimeout" desc="Receive data with timeout" from="Actor2" to="Actor1" txnId="t1"
timeout="$maxWaitTime" timeoutFlag="timeoutOccurred" timeoutIsError="true">
<config name="soap.version">1.2</config>
</receive>
<etxn txnId="t1"/>
<!--
Check to see if timeout took place or not and inform the user.
-->
<interact desc="Check timeout status">
<instruct desc="Timeout occurred:" with="Actor2">$dataReceiveTimeout{timeoutOccurred}</instruct>
</interact>
listen¶
The listen
step is used to instruct the test bed to act as a proxy between messages sent to and from two actors defined as SUTs.
Similar to the send
and receive
steps, this step is expected to take place within a transaction created by btxn
, the
identifier of which it references. The structure of the listen
element is as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | The ID of the transaction this listen belongs to. |
@from | yes | The ID of the actor that will be sending the message (see Actors). |
@to | yes | The ID of the actor that will be receiving the message (see Actors). |
@id | no | The ID for the step. This is also the name of a map variable in the session context in which output will be stored. |
documentation | no | Rich text content that provides further information on the current step. |
config | no | Zero or more elements containing configuration values pertinent to the message exchange. Each config element has a name attribute and a text content or variable reference as value. |
input | no | Zero or more elements for for the messaging handler to consider. See Handler inputs and outputs for details. |
output | no | Zero or more elements for the output values reported back to the test case. See Handler inputs and outputs for details. |
Note
GITB software support: The listen
step is currently not supported. As a general note,
interoperability tests involving multiple actors as SUTs are not currently possible.
Processing steps¶
Processing steps are used to handle complex manipulations on information in the test session context that are domain-specific or too elaborate to be implemented using simple constructs such as the assign step. The actual implementation that carries out operations is implemented by a processing handler (see Processing handlers).
Note that processing steps are not presented to the user.
bptxn¶
Similar to Messaging steps, processing occurs in the context of a transaction that acts as a grouping mechanism
over related operations. The bptxn
step (the name stands for “Begin processing transaction”) is the construct used to
signal that a processing transaction should be considered as started and is assigned an identifier. Subsequent relevant
operations will be accompanied by this transaction ID to allow their processing handler to carry them out accordingly.
Use of a processing transaction is not always required. For processing steps that are simple in nature and don’t require
state to be maintained across calls, you may skip the definition of a transaction and simply refer to the processing handler
from the process
step itself (see process for details). Whether or not skipping a transaction’s definition is
supported depends on the specific processing handler; typically however, even if a processing handler doesn’t require a transaction
and is signalled to create one this will simply be ignored. In terms of whether you need or not to define a processing transaction
you can consider this rule of thumb:
- Transaction needed: When the processing handler is expected to maintain state across individual
process
calls and eventually perform some clean up operations. - Transaction not needed: When the processing handler is stateless.
The structure of the bptxn
element (defined when a processing transaction is needed) is as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | A string identifier for the transaction. |
@handler | yes | A string value or variable reference identifying the the processing handler for the transaction (see Specifying the handler implementation). |
property | no | Zero or more elements to provide configuration regarding the setup of the processing handler call that are not passed to the handler. Each property element has a name attribute and a text content or variable reference as value. |
config | no | Zero or more elements to provide configuration when creating the transaction. Each config element has a name attribute and a text content or variable reference as value. |
The bptxn
step results in a call to the configured processing handler to signal that a new transaction is going to
start.
<bptxn txnId="t1" handler="https://PROCESSING_SERVICE?wsdl"/>
<process id="result" txnId="t1">
<operation>action</operation>
<input name="anInput">$aValue</input>
</process>
<eptxn txnId="t1"/>
eptxn¶
The eptxn
step (the name stands for “End processing transaction”) is the counterpath of the bptxn
step and is used to
close a transaction the ID of which it references. The structure of the eptxn
element is as follows:
Name | Required? | Description |
---|---|---|
@txnid | yes | A string identifier for the processing transaction to end. |
The eptxn
step results in a call to the transaction’s processing handler to signal that it should consider the transaction as
completed and proceed with any needed actions such as resource clean-up.
<bptxn txnId="t1" handler="https://PROCESSING_SERVICE?wsdl"/>
<process id="result" txnId="t1">
<operation>action</operation>
<input name="anInput">$aValue</input>
</process>
<eptxn txnId="t1"/>
process¶
The process
step is where the actual processing work takes place. This may be defined within the context of a
processing transaction started by a bptxn
step, the ID of which is referenced. Alternatively, if a transaction
is not required by the underlying processing handler, the transaction ID reference can be skipped and the handler
can be defined on the process
step itself (see also bptxn for additional details).
The structure of the process
element is as follows:
Name | Required? | Description |
---|---|---|
@txnId | no | The ID of the transaction to which this processing step belongs. Can be ommitted if a transaction is not needed but in this case the handler attribute must be defined. |
@id | no | The ID for the step. This is also the name of a map variable in the session context in which output will be stored. |
@handler | no | A string value or variable reference identifying the processing handler for this step (see Specifying the handler implementation). This is ommitted in favour of the txnId in case a transaction is referenced. |
operation | no | An optional string to identify an operation the handler is expected to perform. |
input | no | Zero or more elements for the input parameters to the processing step. See Handler inputs and outputs for details. |
The operation
attribute is relevant for processing handlers that can support more than one task. Use of multiple operations under
the same transaction renders processing services quite powerful in that they can perform any number of related operations
and be extended with additional ones if needed.
For a processing handler that retains state, carrying out operations in a transaction is important as it provides an opportunity to manage correctly its resources. Moreover, for processing handlers supporting more than one operation for the same data, a transaction provides much needed context to logically connect operations. As an example consider a processing service that is used to read the contents from a ZIP archive. If the test case needs to read multiple files at different points in its execution it would be possible but very inefficient to pass the ZIP archive in each call. Defining a transaction allows the test case to pass the archive once allowing the processing handler to cache it and ultimately remove it upon transaction end. In addition, the presence of a transaction provides context and makes operations such as “initialize” (to pass the archive to consider), “extract” (to get a file’s contents), “checkExistence” (to check if a file exists but not return it) possible. Use of such a transaction-aware processing service is illustrated in the following example:
<!--
Create a processing transaction named "t1".
-->
<bptxn txnId="t1" handler="https://ZIP_PROCESSING_SERVICE?wsdl"/>
<!--
Call the "initialize" operation to pass the archive to the service.
The service handler can read and cache the archive for the transaction.
-->
<process id="init" txnId="t1">
<operation>initialize</operation>
<input name="zip">$zipContent</input>
</process>
<!--
Call the "checkExistence" operation to see if a given entry exists.
-->
<process id="exists" txnId="t1">
<operation>checkExistence</operation>
<input name="path">'file1.xml'</input>
</process>
<!--
Call the "extract" operation to get an entry.
-->
<process id="output" txnId="t1">
<operation>extract</operation>
<input name="path">'file1.xml'</input>
</process>
<!--
End the transaction.
The service handler can remove the archive.
-->
<eptxn txnId="t1"/>
For cases where processing operations are simple, one-off actions, defining a transaction results in superfluous
and unnecessary test steps. A good example of such a case is the TokenGenerator embedded processing handler
that is used to generate text tokens such as a random UUID. In this case, although possible, defining a processing transaction
is not needed, and is skipped in favour of simplification. In this case however, the handler
attribute must be defined
on the process
step itself (replacing the txnId
reference) as illustrated in the following example:
<!--
Generate a UUID. The handler is defined without referencing a transaction ID.
-->
<process id="uuid" handler="TokenGenerator">
<operation>uuid</operation>
</process>
<!--
Display to the user the generated UUID.
-->
<interact desc="Generated UUID">
<instruct desc="Value:">$uuid{value}</instruct>
</interact>
Flow steps¶
Flow steps are used to control the processing flow of a test case. The constructs available are similar to the flow control structures available in programming languages.
if¶
The if
step is used to run one of more steps if a condition is met. Its structure is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | A description to display to the user on the purpose of the check. |
documentation | no | Rich text content that provides further information on the current step. |
cond | yes | The condition to verify in order to execute the then set of steps (if true) or else (if false). This is provided as an expression (see Expressions). |
then | yes | Contains as children any sequence of steps to execute if the condition results to true. |
else | no | Contains as children any sequence of steps to execute if the condition results to false. |
<if desc="Check process type">
<cond>$processType = 'process1'</cond>
<then>
<assign to="$formatType">'XML'</assign>
<verify handler="https://VALIDATOR?wsdl" desc="Validate as XML">
<input name="source" source="$document"/>
<input name="validationType">$formatType</input>
</verify>
</then>
<else>
<assign to="$formatType">'CSV'</assign>
</else>
</if>
while¶
The while
step is the most useful looping construct. It allows a sequence of steps to be continuously executed as long as a condition
continues to be true. The structure of the while
element is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | A description to display to the user on the purpose of the loop. |
documentation | no | Rich text content that provides further information on the current step. |
cond | yes | The condition to verify in order to execute the contained steps. This is provided as an expression (see Expressions). |
do | yes | Contains as children any sequence of steps to execute if the loop’s condition results to true. |
The following example validates the name of each attachment defined in an XML document using a while
loop:
<!--
Initialise maximum iteration count based on the number of "Attachment" nodes in the document.
-->
<assign to="$iterationCount" source="$document">count(//*[local-name() = "Attachment"]</assign>
<assign to="$iteration">1</assign>
<while desc="Validate attachment names">
<cond>$iteration <= $iterationCount</cond>
<do>
<verify handler="XPathValidator" desc="The attachment is named as expected">
<input name="xmldocument" source="$document"/>
<!--
Construct the XPath expression to apply using the iteration variable.
-->
<input name="xpathexpression">concat("//*[local-name() = 'Attachment'][", $iteration, "]/text() = 'file_", $iteration, ".xml'")</input>
</verify>
<!--
Increment iteration counter.
-->
<assign to="$iteration">$iteration + 1</assign>
</do>
</while>
repuntil¶
The repuntil step allows you to execute a sequence of steps at least once, checking at the end a condition to see if another iteration
should take place. The structure of the repuntil
element is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | A description to display to the user on the purpose of the loop. |
documentation | no | Rich text content that provides further information on the current step. |
do | yes | Contains as children any sequence of steps to execute at least once and then again if the condition in cond is true. |
cond | yes | The condition to verify in order to execute again the steps contained in do . This is provided as an expression (see Expressions). |
<assign to="$iteration">1</assign>
<assign to="$maxIteration">3</assign>
<repuntil desc="Do iteration">
<do>
<interact desc="Message to user" with="User">
<instruct desc="Iteration: " with="User" type="string">concat($iteration, " of ", $maxIteration)</instruct>
</interact>
<assign to="$iteration">$iteration + 1</assign>
</do>
<cond>$iteration <= $maxIteration</cond>
</repuntil>
Note
Do-while: Step repuntil
stands for “repeat until”. Considering this you could assume that the steps in do
will be executed until
the condition in cond
is true. This is actually not the case currently as steps are executed while the condition in cond
remains true
(i.e. the logic is actually inversed). The naming of this step is thus unfortunate; it would be more appropriate if this was named dowhile
reflecting accurately how the condition is considered.
foreach¶
The foreach
step allows you to execute a sequence of steps for a specific number of iterations. Its structure is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | A description to display to the user on the purpose of the loop. |
@start | yes | A number to initialise the iteration index to. This is provided as a constant or as a variable reference. |
@end | yes | A number that is considered as the maximum iteration count plus 1. This is provided as a constant or as a variable reference. |
@counter | no | A name for the variable through which to expose the iteration counter (default is “i”). |
documentation | no | Rich text content that provides further information on the current step. |
do | yes | Contains as children any sequence of steps to execute for a loop iteration. |
The start
and end
values define the number of iterations to perform. Specifically, the loop will continue as long as
start
is less than end
with start
getting incremented by one at the end of each iteration.
<!--
The loop will execute 2 times (start must be less than end). The currentIndex variable will be 5 in the first
iteration and then 6. Note that referring to this is done as a variable reference (if not specified the variable
would be named "i" and referred to as "$i").
-->
<foreach desc="Do iteration" counter="currentIndex" start="5" end="7">
<do>
<interact desc="Message to user" with="User">
<instruct desc="Iteration: " with="User" type="string">concat("Iteration ", $currentIndex)</instruct>
</interact>
</do>
</foreach>
<!-- In the following case the loop's boundaries are set dynamically. -->
<assign to="$start">5</assign>
<assign to="$end">$start + 2</assign>
<foreach desc="Do iteration" counter="currentIndex" start="$start" end="$end">
<do>
<interact desc="Message to user" with="User">
<instruct desc="Iteration: " with="User" type="string">concat("Iteration ", $currentIndex)</instruct>
</interact>
</do>
</foreach>
flow¶
The flow
step is used to perform sequences of steps in parallel rather that sequentially as is the default. This can be useful
in scenarios where you want to process data in parallel or trigger messaging to actors concurrently. The flow of execution will be
joined at the end of the flow
step to continue sequential execution. The structure of the flow
element is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | A description to display to the user on the purpose of the forking. |
documentation | no | Rich text content that provides further information on the current step. |
thread | yes | One or more elements containing as children any sequence of steps to execute in the thread (including other flow steps). |
The following example sends a SOAP request to two actors in parallel and proceeds to send a third one when both actors have replied.
<flow desc="Contact actor ReceiverA and ReceiverB in parallel">
<thread>
<!--
Send message to ReceiverA and wait for response.
-->
<btxn from="Sender" to="ReceiverA" txnId="t1" handler="SoapMessaging"/>
<send id="dataSend" desc="Send data to A" from="Sender" to="ReceiverA" txnId="t1">
<config name="soap.version">1.2</config>
<input name="soap_message">$soapMessageForA</input>
</send>
<receive id="dataReceive" desc="Receive data from A" from="ReceiverA" to="Sender" txnId="t1"/>
<etxn txnId="t1"/>
</thread>
<thread>
<!--
Send message to ReceiverB and wait for response.
-->
<btxn from="Sender" to="ReceiverB" txnId="t2" handler="SoapMessaging"/>
<send id="dataSend" desc="Send data to B" from="Sender" to="ReceiverB" txnId="t2">
<config name="soap.version">1.2</config>
<input name="soap_message">$soapMessageForB</input>
</send>
<receive id="dataReceive" desc="Receive data from B" from="ReceiverB" to="Sender" txnId="t2"/>
<etxn txnId="t2"/>
</thread>
</flow>
<!--
After ReceiverA and ReceiverB have responded send a message to ReceiverC.
-->
<btxn from="Sender" to="ReceiverC" txnId="t3" handler="SoapMessaging"/>
<send id="dataSend" desc="Send data to C" from="Sender" to="ReceiverC" txnId="t3">
<config name="soap.version">1.2</config>
<input name="soap_message">$soapMessageForC</input>
</send>
<etxn txnId="t3"/>
exit¶
The exit
step is used to immediately exit the test case from any execution branch. The structure of the exit
element is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | A description to display for the exit step. |
@success | no | Whether or not this step should be considered as a success or failure (the default). This is provided as a boolean or a variable reference. |
documentation | no | Rich text content that provides further information on the current step. |
The following example shows a test case that exits as a success based on the user’s input:
<assign to="$inputValue">'NO'</assign>
<interact desc="Provide your choice" with="User">
<request desc="Enter 'YES' to end the test" with="User">$inputValue</request>
</interact>
<if>
<cond>$inputValue = 'YES'</cond>
<then>
<exit desc="Terminate test" success="true"/>
</then>
<else>
<interact desc="You chose to continue" with="User">
<instruct desc="Test continues" with="User" type="string">""</instruct>
</interact>
<verify handler="XSDValidator" desc="Validate content">
<input name="xmldocument">$document</input>
<input name="xsddocument">$schemaFile"</input>
</verify>
</else>
</if>
The result type of the exit
step can also be determined via variable reference. The example that follows exits as a success or failure depending
on whether or not the user provides a “true” of “false” input:
<interact desc="Decide outcome">
<request desc="Succeed?">$choice</request>
</interact>
<exit desc="Finished" success="$choice"/>
Support steps¶
Support steps are those that perform specific actions not related to messaging, processing or flow control.
assign¶
The assign
step is a frequently used construct in GITB TDL. It is a step that is not visible to the user, used for the manipulation
of data in the test session’s context. It can be used to assign values to variables but also as a means of
performing simple processing or conversion between data types (see Type conversions).
The processing and assignment result is determined by an expression provided as the text content of the assign
element (see Expressions).
The element’s structure is as follows:
Name | Required? | Description |
---|---|---|
@to | yes | The target variable to assign the result of the expression to. |
@append | no | Used if the to variable is a list to append the result to. Can be “true” or “false”. |
@type | no | Used to specify the type of variable to create if the to is an entry in a map . |
@lang | no | The expression language prefix to use to evaluate the contained expression (see Namespaces and Expressions). |
@source | no | A variable reference to identify a source object variable upon which the expression should be evaluated. |
@asTemplate | no | Whether or not the result will be considered as a template for placeholder replacement (see Expressions and templates). By default this is “false”. |
The following example illustrates assigning a value to a number
variable and also counting the nodes in an XML document:
<assign to="$value">1</assign>
<assign to="$nodeCount" source="$document">count(//*[local-name() = "Attachment"]</assign>
The to
attribute of an assign
step determines the target variable to which the expression’s output will be assigned to. This can be:
- An existing variable, defined as part of the test case’s variables section or from previous steps.
- A new variable that will be created once this step completes.
When defining a new variable its type is determined based on the result of the expression. This can also be affected by additional context information
from the way the assign
step is used, specifically the append
attribute that would suggest a list
, as well as the to
expression that
could suggest a map
(e.g. if this defines $myMap{myKey}
).
Numerous examples of the assign
step can be found in the documentation on expressions. Examples are also provided
here on how variables are dynamically created if not already defined.
Note
Using ‘$’ to define the assignment target: In the provided examples the to
attribute of an assign
step is always
prefixed by a $
given that these are variable references. In the case of assign
steps this is optional given that the to
can only ever refer to a variable. As such, a to
value of myVariable
is valid
and considered the same as $myVariable
.
group¶
The group
step is a construct used to visually group together a sequence of steps. It has no effect on the test execution adding only
a visual grouping and label to the display. Its structure is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | The description for the group. |
documentation | no | Rich text content that provides further information on the current step. |
The children of the group
element can be any number of steps supported by GITB TDL. The following example creates a group around a set of
related validations.
<group desc="Validate document">
<verify handler="XSDValidator" desc="Against schema">
<input name="xmldocument">$document</input>
<input name="xsddocument">$schema"</input>
</verify>
<verify handler="SchematronValidator" desc="Against Schematron 1">
<input name="xmldocument">$document</input>
<input name="schematron">$schematron1"</input>
</verify>
<verify handler="SchematronValidator" desc="Against Schematron 2">
<input name="xmldocument">$document</input>
<input name="schematron">$schematron2"</input>
</verify>
</group>
Note
GITB software support: The group
step is currently not supported. Using it will execute the contained steps but these will not be
rendered on the user interface.
verify¶
The verify
step is used to trigger validation of content. Similar to Messaging steps and Processing steps, validation
takes place using a validation handler implementation that can either be an embedded test bed component or a remote service that implements the
GITB validation service API. The content to validate is provided by the test case to the handler in terms of configuration and input, for which
a test report is returned in the GITB TRL (Test Reporting Language) format. The structure of the verify
element is as follows:
Name | Required? | Description |
---|---|---|
@id | no | The ID for the step. This is also the name of a boolean variable in the session context in which the validation result will be recorded (true for success). |
@desc | yes | The description for the validation. |
@handler | yes | A string value or variable reference identifying the the validation handler (see Specifying the handler implementation). |
@level | no | The severity level to be considered when this step fails validation. Can be set to ERROR (the default) or WARNING . |
documentation | no | Rich text content that provides further information on the current step. |
property | no | Zero or more elements to provide configuration regarding the setup of the validation handler call that are not passed to the handler. Each property element has a name attribute and a text content or variable reference as value. |
config | no | Zero or more elements to provide configuration for the validation. Each config element has a name attribute and a text content or variable reference as value. |
input | yes | One more elements for the validation’s input parameters. See Handler inputs and outputs for details. |
A verify
step that is set at warning level (through attribute level
) will never result in an overall failure for the test session. If validation fails,
the result will be indicated as a warning but without further impact. Note that a validation service returning a detailed validation report for a verify
step
at warning level may have its resulting report adapted accordingly. The report will be set as WARNING
(if it was FAILURE
) and any error-level report
items will be listed as warnings.
The following example illustrates use of two verify
steps, one using an XSDValidator and the other set at warning level and calling a remote
validation service:
<!--
Validation using the embedded XSDValidator.
-->
<verify handler="XSDValidator" desc="Validate invoice against schema">
<input name="xmldocument">$document</input>
<input name="xsddocument">$schema"</input>
</verify>
<!--
Warning-level validation using a remote validation service.
-->
<verify handler="https://VALIDATION_SERVICE_ADDRESS?wsdl" level="WARNING" desc="Validate against remote service">
<input name="aDocument">$document</input>
</verify>
Note
Remote or local validators: Simple validations such as those evaluating an XPath expression against a document can be implemented using Embedded validation handlers. When validation logic however is complex it is always best to decouple this into an external validation service. This is the case even when validating XML content since this usually involves multiple validation steps using an XSD and one or more Schematron files. It is more concise to present this as a single validation step with one report. This also enhances maintainability of the test cases considering that use of the embedded XSDValidator and SchematronValidator means that you need to bundle (and maintain) the validation artefacts in each test suite. When decoupled as a service artefacts can be updated without needing new test suite versions aside from the benefit that your service can also be invoked outside the test bed using any SOAP client.
call¶
The call
step is used to invoke a set of steps defined as a scriptlet
(see Scriptlets). If we consider that a scriptlet resembles a function
with input, output and local variables, the call
step can be considered as the function’s invocation. Its purpose is to identify the scriptlet
to call, pass
its required input parameters and receive its output. The structure of the call
element is as follows:
Name | Required? | Description |
---|---|---|
@id | no | The ID for the step. This is also the name of a map variable in the session context in which output will be stored. |
@path | yes | The ID of the scriptlet to call. |
input | no | Zero or more elements for the scriptlet ’s input parameters. See Handler inputs and outputs for details. |
output | no | Zero or more elements for the scriptlet ’s input parameters. See Handler inputs and outputs for details. |
<call id="call1" path="script1">
<input name="docToValidate">$fileContent1</input>
<output name="outputMessage"/>
</call>
More information and examples on how to call a scriptlet
and how to manage its output are provided in Scriptlets.
interact¶
The interact
step is used to exchange information with the user executing the test case. Interactions can be of two types:
- Instructions: Informative messages to be presented to a user.
- Requests: Prompts to a user to provide input.
Both instructions and requests can be included in the same interact
step to display and/or request multiple sets of information in one go.
The structure of the interact
element is as follows:
Name | Required? | Description |
---|---|---|
@id | no | Used as the name of a map variable that will be used to store provided input (if no per-input assignment is provided). |
@desc | yes | A description for the user interaction. |
@with | no | The ID of the actor this interaction refers to. If not specified is is assumed to be the test case actor defined as the SUT. |
documentation | no | Rich text content that provides further information on the current step. |
instruct | no | Zero or more elements to appear as instructions to the user. |
request | no | Zero or more information requests for the user. |
The instruct
elements define what is going to presented to the user. They have the following structure:
Name | Required? | Description |
---|---|---|
@desc | yes | The label to display to the user. |
@with | no | The ID of the actor this interaction refers to. If not specified this is taken from the interact parent element (which itself defaults to the test case’s SUT actor). |
@name | no | In case of instruct elements that used to share binary content, this is used as the name of the file presented for download. |
@type | no | The type to consider for the displayed value. If this is not specified the type will be inferred from the referred variable (if defined) or default to string . |
@source | no | A pure variable reference identifying a source variable. Used as the target upon which to evaluate the contained expression. |
@asTemplate | no | Whether or not the result will be considered as a template for placeholder replacement (see Expressions and templates). By default this is “false”. |
The request
elements define how information shall be requested from the user. Their structure is as follows:
Name | Required? | Description |
---|---|---|
@desc | yes | The label to display to the user. |
@with | no | The ID of the actor this interaction refers to. If not specified this is taken from the interact parent element (which itself defaults to the test case’s SUT actor). |
@contentType | no | Defines how the specified variable’s value is to be set (“STRING”, “BASE64” or “URI”). The default is “STRING”. |
@encoding | no | Used in case of text binary input to specify the character encoding to consider. The default is “UTF-8”. |
@name | no | In case of request elements this name is the key to be used for the map entry to hold the provided data. |
@options | no | Used to render a dropdown list by providing the option values to consider (comma-separated values, a reference to a string variable of comma-separated values, or a reference to a list variable of strings). |
@optionLabels | no | Used as the labels for the option values (comma-separated values, a reference to a string variable of comma-separated values, or a reference to a list variable of strings). If provided the number of values needs to match the options. If not provided the option values are used. |
@multiple | no | A boolean value to determine whether the dropdown list (if the options attribute is defined) shall be a single or multiple selection list (default is false for single selection). |
@asTemplate | no | Whether or not the result will be considered as a template for placeholder replacement (see Expressions and templates). By default this is “false”. |
The content of the instruct
and request
elements is expected to be an expression (see Expressions) that takes different
meaning depending on the specific element type. In the case of providing information to the user through a instruct
element the contained
value is a complete expression that will be evaluated to produce the value to display. In this case the contentType
and encoding
attributes are not used and are ignored if specified. What is important is the type
attribute that defines how the element’s expression
result is to be interpreted (see Types):
- A
binary
,object
orschema
type results in the calculated expression being computed as BASE64 content. This will be rendered as a download button for the user to download the content as a file. - All other cases result in the value being displayed as text. This is also the default case if the
type
attribute is not specified.
Concerning request
elements, the content of the expression is expected to be a pure variable reference that identifies the variable that
will receive the input. In addition the type
is ignored but the contentType
becomes important. Specifically:
- Specifying “BASE64” results in a file upload presented to the user.
- Specifying “STRING” (the default) or “URI” results in a simple text input. Note that only “STRING” can be used in case the request is defined as a dropdown list (i.e. the
options
attribute is defined).
The contentType
can also be ommitted in which case both the type
and contentType
are determined by the variable being referenced. If this is a binary
, object
or
schema
a type of binary
with contentType
“BASE64” will be considered.
The following examples illustrate a user interactions presenting instructions and also requesting information:
<interact desc="Some information and inputs">
<!-- type="string" ommitted as default. Displays the text as a message to the user. -->
<instruct desc="This is a simple message"/>
<instruct desc="A text value:">concat("A text value ", $aTextValue)</instruct>
<!-- Present a download button for file "schema.xsd" (not specifying a name would produce a "downloadedFile" file). -->
<instruct name="schema.xsd" desc="A file to download:">$schemaFile</instruct>
<!-- Present a text input field storing the result in variable aStringInputValue. -->
<request desc="Enter a text value:">$aStringInputValue</request>
<!-- Present a single selection dropdown list storing the result in variable aSelectedInputValue. -->
<request desc="Enter a text value:" options="v1, v2" optionLabels="Value 1, Value 2">$aSelectedInputValue</request>
<!-- Present a file upload storing the result in variable aBinaryVariable. -->
<request desc="Upload a file:">$aBinaryVariable</request>
</interact>
<!-- Example storing all provided input in a map. This uses the "id" and "name" attributes. -->
<interact id="userInput" desc="Some information and inputs">
<!-- Present a text input field storing the result in variable userInput{text} (a type of "string" is assumed as the default). -->
<request name="text" desc="Enter a text value:"/>
<!-- Present a file upload storing the result in variable userInput{file}. -->
<request name="file" desc="Upload a file:" type="binary"/>
</interact>
To better illustrate how dropdown selections can be define, the following code sample presents the different ways to define them:
<variables>
<var name="input1" type="string"/>
<var name="input2" type="string"/>
<var name="input3" type="string"/>
<var name="input4" type="string"/>
<var name="input3_options" type="string"/>
<var name="input3_labels" type="string"/>
<var name="input4_options" type="list[string]"/>
<var name="input4_labels" type="list[string]"/>
</variables>
...
<steps>
<assign to="$input3_options">"v1, v2, v3"</assign>
<assign to="$input3_labels">"Value 1, Value 2, Value 3"</assign>
<assign to="$input4_options" append="true">"x1"</assign>
<assign to="$input4_options" append="true">"x2"</assign>
<assign to="$input4_options" append="true">"x3"</assign>
<assign to="$input4_labels" append="true">"VAL 1"</assign>
<assign to="$input4_labels" append="true">"VAL 2"</assign>
<assign to="$input4_labels" append="true">"VAL 3"</assign>
<interact desc="Enter data">
<!-- Single selection with options provided in the attribute values. -->
<request desc="Select one" options="o1, o2, o3" optionLabels="Option 1, Option 2, Option 3">$input1</request>
<!-- Multiple selection with options provided in the attribute values. -->
<request desc="Select multiple" options="o1, o2, o3" optionLabels="Option 1, Option 2, Option 3" multiple="true">$input2</request>
<!-- Single selection with options provided by referring to string variables. -->
<request desc="Select one (use string reference)" options="$input3_options" optionLabels="$input3_labels">$input3</request>
<!-- Single selection with options provided by referring to list variables. -->
<request desc="Select one (use list reference)" options="$input4_options" optionLabels="$input4_labels">$input4</request>
</interact>
</steps>
Note
The value received from a request
element defined as a multiple selection list will be a comma-separated string in which the individual
parts match the selected values. This value is recorded in the test session context as a variable of type string
that can be passed as
input to handlers or be processed with relevant XPath functions.
Common step concepts¶
The following section documents common concepts that apply to all test steps.
Rich documentation per step¶
Test steps that are meant to be presented to users can be defined with an additional documentation
element. This complements the limited label
attached to each step (via attribute desc
), allowing further instructions, context and references to be provided. The content supplied is treated
as rich text and supports several HTML features:
- Structure elements (e.g. headings, text blocks, lists).
- In-line styling.
- Tables.
- Links.
- Images.
The simplest way to provide such information is to enclose the HTML content in a CDATA
section to ensure the test case XML remains well-formed. The
example that follows illustrates two examples, one defining a simple additional text, and another with more comprehensive HTML content.
<!-- Additional documentation as simple text. -->
<verify handler="XSDValidator" desc="Validate invoice against UBL 2.1 Invoice Schema">
<documentation>This is an extra documentation item.</documentation>
<input name="xmldocument">$file_content</input>
<input name="xsddocument" source="$UBL_Invoice_Schema_File"/>
</verify>
<!-- Additional documentation as rich HTML content. -->
<verify handler="SchematronValidator" desc="Validate invoice against BII RULES" level="WARNING">
<documentation><![CDATA[
<p>This is <b>important information!</b> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>
<div style="width:100%; text-align:center"><img src="https://www.itb.ec.europa.eu/docs/services/latest/_images/ValidationService.png"/></div>
<b><u>Steps for testing:</u></b>
<p>
<ol>
<li>Prepare correctly</li>
<li>Submit the correct file</li>
<li>Validate results</li>
</ol>
</p>
<p>
<table style="border: 1px solid black; width:100%">
<tr style="border: 1px solid black; font-weight: bold;">
<td>COL1</td><td>COL2</td><td>COL3</td><td>COL4</td><td>COL5</td>
</tr>
<tr>
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>
</tr>
<tr>
<td>test1</td><td>test2</td><td>test3</td><td>test4</td><td>test5</td>
</tr>
</table>
</p>
<p>After this make sure to check the docs <a href="https://www.itb.ec.europa.eu/docs/tdl/latest">here</a>.</p>
]]></documentation>
<input name="xmldocument">$file_content</input>
<input name="schematron" source="$BII_RULES_Invoice_Schematron_File"/>
</verify>
- Note that documentation such as this is also supported for:
- The overall test suite.
- The test cases included in the test suite.