Do With Interpreter
| Import |
| com.greenpepper.interpreter.flow.dowith |
| GreenPepper.Interpreters.DoWith |
The DoWithInterpreter verifies business flows expressed as a sequence of actions. This interpreter executes a workflow on the system under test and asserts returned values against expected values. By contrast with other interpreters, the DoWithInterpreter can interpret more than one table in a specification document. In fact, unless specified otherwise, it will interpret all of the tables it encounters.
Specifying the fixture
The DoWithInterpreter follows the general rules for interpreter and fixture selection and fixture naming.
Once a DoWithInterpreter starts interpreting a specification document, it carries out the actions in all of the following tables with the selected fixture. Consequently, each subsequent table doesn't need to explicitly declare an interpreter and a fixture.
Although the same fixture can be used to interpret all tables in a document, an action may also return an interpreter. This interpreter will be used with the rest of the current table and will be abandoned at the next table.
Interpretation flow
As already stated, a business workflow may span several tables. The DoWithInterpreter goes through all tables one by one, down to the end of the specification document. For each table, it executes the workflow one row at a time, reading cells from left to right.
| rule for |
interpretation order |
| tables |
order of interpretation? |
[ do with ][ some fixture ] [ row ][ 1 ][ of table ][ 1 ] [ row ][ 2 ][ of table ][ 1 ] [ row ][ 3 ][ of table ][ 1 ]
**** [ row ][ 1 ][ of table ][ 2 ]
**** [ row ][ 1 ][ of table ][ 3 ] [ row ][ 2 ][ of table ][ 3 ] |
row 1 of table 1, row 2 of table 1, row 3 of table 1, row 1 of table 2, row 1 of table 3, row 2 of table 3 |
Actions
Each row in a workflow represents an action to perform on the system under test.
The DoWithInterpreter expects default actions to be composed of keywords and data. An action starts with a keyword cell, then alternates between data cells and more keyword cells. In other words, keywords appear in every other cell.
The keywords of an action are concatenated together with spaces between them and converted into an identifier. On the Java platform, this is done using lower camel casing. The identifier obtained names the action to execute on the system under test, with the data used as parameters to the action.
To execute the action on the system under test, the DoWithIntepreter follows the rules of action access resolution rules.
| rule for |
row form |
| row |
action name? |
parameters? |
| [ Buy a ][ MacBook Pro ][ to ][ Bob ][ for doing ][ Rails Development ] |
Buy a to for doing |
MacBook Pro, Bob, Rails Development |
A keyword cell can be empty:
| rule for |
row form |
| row |
action name? |
parameters? |
| [] [ Bob ][ needs a ][ MacBook Pro ] |
needs a |
Bob, MacBook Pro |
| [ Buy ][ 5 ][ ][ MacBook Pros ] |
Buy |
5, MacBook Pros |
The last keyword in the row is optional, so the row can end with keyword or data:
| rule for |
row form |
| row |
action name? |
parameters? |
| [ Story Test Driven Development with ][ GreenPepper ][ rocks ] |
Story Test Driven Development with rocks |
GreenPepper |
Special Actions
The DoWithInterpreter knows about the special actions. Special actions are identified by a special keyword at the beginning of the row and apply to the rest of their row:
- check checks whether the result of the action described in the rest of the row matches the value in the last cell of the row.
- reject checks - as expected - that the action described in the rest of the row fails.
- accept checks that the action described in the rest of the row succeeds.
- display prints the result in a new cell at the end of the row without affecting the results (statistics).
| rule for |
row form |
| row |
type of action? |
| [ Buy a ] [ MacBook Pro ][ to ][ Bob ][ for doing ][ Rails Development ] |
Default |
| [ Check ] [ that code is written ] [ test-first ] |
Check |
| [ Accept ] [ code written ] [ test-first ] |
Accept |
| [ Reject ] [ code written ] [ test-last ] |
Reject |
| [ Display ] [ code written ] |
Display |
Rules for annotations
When an action returns a boolean value, the keywords of that action are annotated right if the action returns true:
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
| [ keyword ][ data ][ keyword ][ data ] |
true |
1, 3 |
[] |
[] |
| [ keyword ][ data ][ keyword ][ data ][ keyword ] |
true |
1, 3, 5 |
[] |
[] |
If it returns false, keywords are annotated wrong:
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
| [ keyword ][ data ][ keyword ][ data ] |
false |
[] |
1, 3 |
[] |
| [ keyword ][ data ][ keyword ][ data ][ keyword ] |
false |
[] |
1, 3, 5 |
[] |
If it throws an exception, the first keyword only is annotated exception:
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
| [ first keyword ][ data ][ keyword ][ data ][ keyword ] |
error |
[] |
[] |
1 |
A check special action only annotates the last cell, containing the expected value:
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
| [ check ][ that ][ TDD ][ is ][ cool ] |
cool |
5 |
[] |
[] |
| [ check ][ that ][ test last ][ is ][ boring ] |
never done |
[] |
5 |
[] |
A accept special action annotates the action cell right if the action returns true. Otherwise it annotates it wrong.
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
| [ accept ][ using debugging ] |
true |
1 |
[] |
[] |
| [ accept ][ failing build ] |
false |
[] |
1 |
[] |
| [ accept ][ fail ][ maven ][ ][ build ] |
error |
[] |
[] |
1 |
A reject special action annotates the action cell right if the action returns false or throws an exception. Otherwise it annotates it wrong.
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
| [ reject ][ using debugging ] |
true |
[] |
1 |
[] |
| [ reject ][ failing build ] |
false |
1 |
[] |
[] |
| [ reject ][ fail ][ maven ][ ][ build ] |
error |
1 |
[] |
[] |
A display special action annotates a new cell at the end of the row as ignored.
| rule for |
cell annotation |
| row |
action returns |
cells marked right? |
cells marked wrong? |
cells marked exception? |
cells marked ignored? |
| [ display ][ using debugging ] |
false |
[] |
[] |
[] |
3 |
| [ display ][ failing build ] |
false |
[] |
[] |
[] |
3 |
| [ display ][ fail ][ maven ][ ][ build ] |
false |
[] |
[] |
[] |
6 |
Processing table remainder with another interpreter
The action can explicitly return an interpreter, which is will be used to interpret the rest of the table. After the current table, that interpreter will be abandoned.