Scenario
Objects
To a very large extent, Provengo is a tool for creating, analyzing, and reasoning about scenarios that a specification allows. Because scenarios are so central, Provengo provides built-in objects and methods to easily work with them. This section describes these objects and how to work with them.
The main class is Scenario
. Object of this class contains a sequence of events (basically, the run through the Provengo model), and some metadata, such as title and a set of tags. Setting the metadata of a scenario is done by the function specified by the scenario.generator.metadata
configuration key. This function accepts a Scenario
object, accesses its event sequence, and then assigns it a title and assigns tags accordingly.
By default, adding metadata to scenarios is done the by the addMetadata() function, in the meta-spec/scenario-metadata.js file. This function calls default implementations for adding tags and titles. If the default methods work for you, there’s no need to change anything.
|
Objects and Methods
addMetadata(aScenario)
Receives a Scenario
object, sets its title sand assigns tags to it. This function is called by the Provengo tool for each executed scenario. To change the name metadata function, use the scenario.generator.metadata
configuration key.
aScenario
-
Scenario
object to be tagged and titled.
Returns: nothing.
Scenario
Object
A Scenario
object represents a single run of the model. In most cases, a single scenario describes a single test case. A scenario contains a series of events, starting at the model’s start
node and ending in a node with no outbound arrows. A Scenario
object also contains metadata — a title and a set of tags.
scn.addTag(key, value)
Adds a tag to the scenario. Tags are composed of a key and value. The key is an array of strings (which may be empty), and the value is a string. This allows users to create structured tag hierarchies, which can be later used for more structured reporting and machine learning.
key
-
Optional
string
orstring
array. The tag’s "name". If omitted, an empty array is used and the tag in interpreted as a "label" - a "boolean" value that is either present or absent. value
-
string
. The value of the tag.
Returns: nothing.
Example
Consider a test model that involves costly API calls, for example to an external service that bills for every call. We’d like to know which tests are going to be costly to run, and which will be cheaper. For this, we count the number of API calls, and tag scenarios accordingly. The snippet below shows three examples for creating such a tag.
For this function to be called as a metadata generator, its name should be added to the project config under the scenario.generator.metadata config key. |
function customAddMetadata( aScenario ) {
let apiCalls = countApiCalls(aScenario.events); (1)
if ( apiCalls > 10 ) { (2)
aScenario.addTag("api-heavy");
} else {
aScenario.addTag("api-light");
}
aScenario.addTag("apiCalls", String(apiCalls)); (3)
aScenario.addTag(["api", "callCount"], String(apiCalls)); (4)
}
-
Counting costly API calls. Implementation not shown, but it basically iterates over the scenario’s
events
field, looks for API call events, and counts them. -
Option 1: Labeling scenarios as
api-heavy
orapi-light
. -
Option 2: Labeling each scenario with the exact call count, under the key
apiCalls
. -
Option 3: Labeling each scenario with the exact call count, under the hierarchical key
["api","callCount"]
.
scn.events
An array of Event
objects forming the scenario.
Example
Printing the scenario’s events to the log.
for ( let idx=0; idx<scenario.events.length; idx++ ) {
bp.log.info( scenario.events[idx] );
}
scn.length
number
. The number of events in the scenario.
Example
Printing the scenario’s length to the log.
function logScenarioLength( aScenario ) {
bp.log.info( `This scenario has ${aScenario.length} events`);
}
scn.title
string
. The title of the scenario.
Example
Printing the scenario title to the log, in a crocodile’s speech bubble. This is useful in many cases (we’re just not sure which cases. But it’s useful).
function crocTitle( aScenario ) {
let bubbleEdge = " ".padEnd(aScenario.title.length+3,"-");
bp.log.info(bubbleEdge);
bp.log.info(`( ${aScenario.title} )`);
bp.log.info(bubbleEdge);
bp.log.info("\\ ");
bp.log.info(" \\ ");
bp.log.info(" _____--\\__A_A_A_A_A_A_A_A_A_A_A ");
bp.log.info(" (____ oo \\A_A_A_A_A_A_A_A_ ");
bp.log.info(" (____ / / \\ ");
bp.log.info(" \\__ / /_______/ /________________________\\ ");
bp.log.info(" /,,,/ \\__\\ /,,,/ \\__\\ ");
}
Sample result:
[RUN>random] INFO B-program started
[RUN>random] INFO Selected: [Greeting: Howdy {JS_Obj type:"selection", name:"Greeting", value:"Howdy", lib:"bp-base"}]
[RUN>random] INFO Selected: [Choice: Venus {JS_Obj type:"choice", value:"Venus", lib:"bp-base"}]
[RUN>random] INFO Selected: [Howdy, Venus]
[RUN>random] INFO Super-step done
[RUN>random] INFO [BP][Info] -----------------------
[RUN>random] INFO [BP][Info] ( Greeting Howdy, Venus )
[RUN>random] INFO [BP][Info] -----------------------
[RUN>random] INFO [BP][Info] \
[RUN>random] INFO [BP][Info] \
[RUN>random] INFO [BP][Info] _____--\__A_A_A_A_A_A_A_A_A_A_A
[RUN>random] INFO [BP][Info] (____ oo \A_A_A_A_A_A_A_A_
[RUN>random] INFO [BP][Info] (____ / / \
[RUN>random] INFO [BP][Info] \__ / /_______/ /________________________\
[RUN>random] INFO [BP][Info] /,,,/ \__\ /,,,/ \__\
[RUN ] INFO Test Result: SUCCESS
ScenarioUtils
Object
A utility object storing methods for working with scenarios.
ScenarioUtils.addMetadata(aScenario)
A default implementation for adding metadata to scenarios. Assigns both tags and title, based on standard Provengo events such as choose()
and select().from()
, and on standard libraries such as State Machines and Combi.
aScenario
-
Scenario
object. The scenario to be tagged and titled.
Returns: true
if either tags or title was added, false
otherwise.
Example
Using the ScenarioUtils.addMetadata
function as a fallback when custom logic does not yield metadata.
For this function to be called as a metadata generator, its name should be added to the project config under the scenario.generator.metadata config key. |
function customAddMetadata( aScenario ) {
if ( ! generateSpecificMetadata(aScenario) ) { (1)
ScenarioUtils.addMetadata(aScenario);
}
}
-
generateSpecificMetadata
is defined somewhere else in the project.
ScenarioUtils.autoTag(aScenario)
Adds tags to a scenario, based on events from standard libraries and bp-base
.
aScenario
-
Scenario
object. The scenario to be tagged.
Returns: true
if one or more tags were added, false
otherwise.
Example
Using the ScenarioUtils.autoTag
function to add an initial set of tags.
For this function to be called as a metadata generator, its name should be added to the project config under the scenario.generator.metadata config key. |
function customAddMetadata( aScenario ) {
ScenarioUtils.autoTag(aScenario);
if ( aScenario.length > 20 ) {
aScenario.addTag("Lengthy");
}
}
ScenarioUtils.autoTitle(aScenario)
Adds a title to the passed scenario, based on events from standard libraries and bp-base
.
aScenario
-
Scenario
object. The scenario to be tagged.
Returns: true
if the title was set, false
otherwise.
Example
Using the ScenarioUtils.autoTitle
function to add a title to a scenario, then adding the event count to the scenario’s title.
For this function to be called as a metadata generator, its name should be added to the project config under the scenario.generator.metadata config key. |
function customAddMetadata( aScenario ) {
if ( ! ScenarioUtils.autoTitle(aScenario) ) {
aScenario.title="Test scenario"; // fallback
}
aScenario.title = aScenario.title + ` (${aScenario.length})`';
}