What is a Virtual Block
A virtual block is used to specify the interface (number of pins and their datatypes), but not its implementation as an action block. It can be placed into a network like any other block.
During the execution, steps for virtual actions will determine the real action to be performed dynamically, at execution time. This is done via one of two mechanisms:
Explicit, Direct Performer:
If the performer input pin is connected, that pin's value provides a reference to a concrete action. The concrete action must have the virtual action's ID specified as its interface. The reference can be provided by another step (dynamically computed), via the environment using an environment-freeze value or directly as a freeze value. Of course, any environment variables must have been initialized elsewhere before.
The reference's value can be defined either as the action's ID, or its name. For convenience, actions can be directly dragged from the tree and dropped onto a performer input pin. Obviously, using a constant freeze value as performer-pin input makes the whole virtual mechanism useless, as you could then just place the concrete action. So this is usually only done for testing and demonstration purpose. In real-world scenarios, the reference is almost always provided by an environment variable, as described below.
Implicit Performer via a mapping in the Environment:
If the performer input pin is not connected, the concrete action is resolved using the dynamic runtime environment, where a mapping from virtual to concrete is expected. The environment must contain either a mapping for the individual action or for a complete virtual library.
Individual Action Mapping:
For this, the environment should contain a mapping from virtual-action-id to concrete action-id. I.e. it must contain a slot where a reference to the virtual action is key, and a reference to the concrete action is the value. Such mappings cannot be created via the environment editor (as it only creates slots with a string-type namekey), instead, a special block is provided, which creates such a mapping in its surrounding environment.
Virtual Library Mapping:
The most convenient way to specify virtual actions is by providing a virtual- to concrete library mapping. For that, a special block is provided, which expects a reference to a virtual library and a reference to a concrete library as inputs. After that mapping has been created, any reference to any virtual block of that library will be resolved using a corresponding concrete block from the concrete library.
See the virtualAction sample project for how to define and use virtual libraries.
When to use Virtual Blocks
Use a virtual block, if:
- you have to model a function which is realized using different concrete mechanisms. For example: if multiple communication paths exist to some device, and the one to be used has to be determined dynamically during the test (e.g. connected via USB vs. connected via Serial Line vs. Internet connection).
- you have to create a test which has to deal with multiple devices, which use different setups, parameters or protocols. For example: if you have multiple measurement devices in your lab, which require different interface handling, and the test has to determine dynamically, which device is to be used during test execution. This situation is especially common, when expecco is used together with a test automation system, such as expecco ALM, where expecco ALM chooses dynamically which devices are to be used in a test run and passes that information as parameter set.
- alternatives are to be configurable by the tester at test-execution time. For example, to select between debug- and non-debug versions of a block, or to select between different test-levels (smoke-test / full-test etc.) and different test-actions are to be performed depending on that choice.
How to use Virtual Blocks
- define the virtual block and its pins
- define a concrete block with the same number of pins having the same data types.
- copy the virtual blocks ID (either from its documentation-editor tab) or via the copy-ID popup menu function in the element-tree. The paste this ID into the concrete blocks "Interface" field (in the scheme-editor-tab). Alternatively, drag & drop a virtual action into this field. This tells expecco, that the concrete action implements that virtual interface.
- place the virtual action as a step into some network. Notice the additional performer pin
- create an environment variable to hold the concrete ID
- freeze the performer-pin input from the above environment variable
- connect the concrete action to the virtual action:
- for a demo run: drag&drop the concrete action into the environment variable (or copy-paste its functional-ID)
- for a real test: create a setup compound action, which sets the environment variable's value to the appropriate ID of a concrete action
- execute the action, where the virtual block has been placed. Notice how you can control the execution.