Adding Custom Steps
Some Skills require their own unique Steps to test functionality specific to that Skill.
Custom Steps can be added to your Skills repository within the test/behave/steps
directory.
The Mycroft Timer Skill for example provides test/behave/steps/timer.py. This has a range of custom Steps to ensure the system is in an appropriate state before the test is run, and that a timer is stopped correctly when requested.
Let's use an example from this Skill to see how we can define our own custom Steps.
Packages
First we import some packages.
From behave
we can get the behave decorators - given
, when
, or then
. For this Step we also need some helper functions from the Voight Kampff module.
Like any Python script, you can import other packages from Mycroft or externally as needed.
Voight Kampff Tools
The test.integrationtests.voight_kampff
module provides a number of common tools that may be useful when creating Step files.
then_wait(msg_type, criteria_func, context, timeout=10)
Wait for a specified time for criteria to be fulfilled.
Arguments:
msg_type
- Message type to watch
criteria_func
- Function to determine if a message fulfilling the test case has been found.
context
- Behave context object
timeout
- Time allowance for a message fulfilling the criteria, defaults to 10 sec
Returns:
tuple (bool, str)
- test status, debug output
mycroft_responses(context)
Collect and format mycroft responses from context.
Arguments:
context
- Behave context to extract messages from.
Returns:
(str)
- Mycroft responses including skill and dialog file
emit_utterance(bus, utt)
Emit an utterance on the bus.
Arguments:
bus (InterceptAllBusClient)
- Bus instance to listen on
dialogs (list)
- List of acceptable dialogs
Returns:
None
wait_for_dialog(bus, dialogs, timeout=10)
Wait for one of the dialogs given as argument.
Arguments:
bus (InterceptAllBusClient)
- Bus instance to listen on
dialogs (list)
- list of acceptable dialogs
timeout (int)
- Time allowance to wait, defaults to 10 sec
Returns:
None
Decorators
Now we can use the @given()
decorator on our function definition.
This decorator tells the system that we are creating a Given
Step. It takes a string as it's first argument which defines what phrase we can use in our tests. So using the first decorator above means that in our tests we can then write Given
Steps like:
A handy feature of decorators is that they can be stacked. In this example we have two stacked decorators applied to the same function. This allows us to use variations of natural language, and both versions will achieve the same result. So now we could write another Step phrased differently:
Either way, it will ensure a 10 minute timer exists before running the test Scenario.
Function arguments
When we define a Step function, the first argument will always be a Behave Context
Object. All remaining arguments will map to variables defined in the decorators.
In our current example, we have only one variable "timer_length
". This corresponds to the second argument of our function. Additional variables can be added to the argument list such as:
Context Object
The first argument of each Step function is always a Behave Context
Object, with some additional properties added by Voight Kampff. These are:
context.bus
- an instance of the Mycroft MessageBusClient
class. context.log
- an instance of the Python standard library logging.Logger
class. context.msm
- a reference to the Mycroft Skills Manager
Step logic
Now we have the structure of our Step function in place, it's time to look at what that Step does.
In this example we have four lines:
Emitting an utterance to the Mycroft MessageBus to create a timer for the given length of time.
Waiting for dialog to be returned from the MessageBus confirming that the timer has been started.
Logging an
info
level message to confirm we created a timer.Clearing any remaining messages from the MessageBus to prevent interference with the test.
Note: the log message in this Step isn't really necessary. Voight Kampff will confirm that each Step is completed successfully. It just serves as a useful example to show how messages can be logged.
Help
For further assistance with Skill testing, please post your question on the Community Forums or in the Skills channel on Mycroft Chat.
See our tips for how to ask the best questions. This helps you get a more complete response faster.
Last updated