Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Definition

The RuleForInterpreter is used to express concrete and measurable business rules.
During the execution of the specification, GreenPepper compares the values returned by the system under development against the expected values defined by the Business Expert.

  • The first row of the table indicates the set of rules to be tested by GreenPepper.
  • The next row is called the header row and serves to distinguish the given values and the expected values. Given values serve as inputs to the system, whereas expected values serve as comparison values against values that are actually returned by the system. When a column header ends with special characters ? or (), it denotes an expected value.
  • Finally, the remaining rows capture the examples. They are the executable test rows.

Specific keywords for expected values

offers a list of useful keywords to support the Business Expert.

Empty cellsWhen a test cell is left blank, only shows the returned value
errorWhen you expect an error, specify it in the cell to test that particular behavior

Coloring

will visually show the test result by coloring each testing cell:

...

The return value of the quotient method is also a double, which means that the values provided in the quotient? expected column must be doubles as well. When compares the value returned by the fixture with the value provided as an expectation, it will first convert the expected value to the type of the actual returned value. In the fifth row, it will convert the value 6 to a double and then do the comparison.

A More Realistic Example

The Calculator example is very simple. In a real world example, the fixture code would not perform any real work but would instead delegate to the application under development. In other words, if this was a real application the fixture would not carry out the division operation but call on the system under development. The general rule is to keep the fixture as thin as possible to be merely a mediator between the example table and the application code.

...

  • given values, which are mapped to public instance variables in the fixture class
  • expected values, which are checked against values returned by the corresponding public instance methods

Headers

For a given column header cell, :

...

  • It figures out the public instance method to use using camel casing rules.
  • If there is no such method or if it's not publicly accessible, it marks the cell with an error annotation, causing the cell to appear yellow and to display a stack trace of the error. That column will be ignored entirely.

Columns

will then run all remaining rows one at a time, going through all cells in the row from left to right.

...

DEFINITION

The collection interpreters are used to express any kind of groups, lists or sets of values.

When a collection interpreter is executed, compares the list of values expected with the list of values returned by the system under development. The test result depends on the specific collection interpreter selected.

  • As for all other interpreters, the first row of the collection interpreters specifies the name of the interpreter and the name of the collection to be tested.
  • The next row is used to define the name of each attribute related to the members of the collection of data.
  • The following rows are used to specify the set of values to test.

Specific keywords

none

Coloring

will visually indicate the test result by coloring the rows:

...

Writing fixtures for List of Value

As we've seen in the Collection Interpreters definition, the collection interpreters are used to express a collection of data to be compared with the system under development.

When running the table, Image Removed Image Added uses a fixture to mediate between the example expressed in collection of values tables and the system under development. The fixture code defines how the specific lists of values are mapped to the application code.

This page shows the fixture code that supports the examples introduced in the

Workflow validation (Do With)

Definition

...

definition.

Using the CollectionInterpreter alone

Consider the example of collection of values table described in definition, shown again below.

list ofCanada Province Codes
NameCode
ALBERTAAB
BRITISH COLUMBIABO
NEW BRUNSWICKNB
MANITOBAMB
NEWFOUNDLAND and LABRADORNL
NOVA SCOTIANS
NUNAVUTNU
ONTARIOON
PRINCE EDWARD ISLANDPE
QUEBECQC
SASKATCHEWANSK
YUKONYT
OTHER PROVINCE

OP

The first cell of the first row indicates that a the ListOfInterpreter will be used to interpret the example table. The next cell says that the query() method to use is in the fixture named Canada Province Codes. In Java, the name of the fixture is the name of a Java class. The returned value of the query() method must be a Collection which is, in our example, a Set of Provinces.

The second row, also known as the header row, designates the attribute columns of the Collection's elements. In our example, Name and Code are the attribute of the Province.

The fixture code to support this example in Java is the class CanadaProvinceCodesFixture shown below.

The query method

The GreenPepper method called to get the list of data from the fixture is query() in Java and Query() in C#.

Code Block
languagejava
public Collection query() {...}

The return type of the query method does not have to be specifically a Collection.

It can be any of the derived Collection class or an Array.

Code Block
languagejava
public Employees[] query() {...}

You can choose another method then query by telling GreenPepper which method to use with the help of an annotation or attributes.

Code Block
languagejava
import com.greenpepper.reflect.CollectionProvider;
   ...
    @CollectionProvider
    public Collection query() {...}

but the method specifies still have to be parameter-less and return a Collection implementation or an array.

Show me the code

Code Block
languagejava
titleCode for the CanadaProvinceCodesFixture
public class CanadaProvinceCodesFixture
{
    public Set<Province> query()
    {
        return Country.canada().provinces();
    }
}
Code Block
languagejava
titleCode of the System Under Development
public class Country
{
    private String name;
    private Set<Province> provinces = new TreeSet<Province>();

    private Country(String name)
    {
        this.name = name;
    }

    public static Country canada()
    {
        Country canada = new Country("CANADA");
        canada.provinces.add(new Province("ALBERTA","AB"));
        canada.provinces.add(new Province("BRITISH COLUMBIA","BC"));
        canada.provinces.add(new Province("MANITOBA","MB"));
        canada.provinces.add(new Province("NEW BRUNSWICK","NB"));
        canada.provinces.add(new Province("NEWFOUNDLAND and LABRADOR","NL"));
        canada.provinces.add(new Province("NOVA SCOTIA","NS"));
        canada.provinces.add(new Province("NUNAVUT","NU"));
        canada.provinces.add(new Province("ONTARIO","ON"));
        canada.provinces.add(new Province("PRINCE EDWARD ISLAND","PE"));
        canada.provinces.add(new Province("QUEBEC","QC"));
        canada.provinces.add(new Province("SASKATCHEWAN","SK"));
        canada.provinces.add(new Province("YUKON ","YT"));
        return canada;
    }

    public Set<Province> provinces()
    {
        return provinces;
    }
}

public class Province implements Comparable
{
    public String name;
    public String code;

    public Province(String name, String code)
    {
        this.name = name;
        this.code = code;
    }

    public int compareTo(Object o)
    {
        return name.compareTo(((Province)o).name);
    }
}

How is the table processed?

When it runs this table, Image Added reads the first row to select the interpreter and fixture. It then reads the second to know what are the attribute columns. Finally it starts testing from the third row down to the end of the table.

For the third row Image Added carries out the following sequence of steps:

  1. It calls the method query() of the fixture CanadaProvinceCodesFixture to retrieve the Collection to test.
  2. It reads the value ALBERTA from the column Name and compares it to the attribute Name of the first element of the List.
    Since the values are equal, it will annotate the cell as right, which results in the cell being colored green.
  3. It reads the value AB from the column Code and compares it to the attribute Code of the first element of the List.
    Since the values are equal, it will annotate the cell as right, which results in the cell being colored green.

Step 2 and 3 are repeated through the remaining rows of the table.


For the fourth row, the Codes are not the same so Image Added will mark the expected cell wrong. The cell will be colored red and will display a message including the expected value and the actual value.
The order of Provinces NEW BRUNSWICK and MANITOBA are inverted compared to the alphabetical sorting. Image Added will annotate both rows as wrong. Each cell will be colored red and will display a message including the expected value and the actual value.

The last row is not part the set of Province returned by the system under development. In that particular case, Image Added will insert the keyword missing and color the row in red.

Using a CollectionInterpreter joined with the DoWithInterpreter

In this particular case, there is only one fixture combining the methods of the CollectionInterpreter and the methods of the DoWithInterpreter. So, in the CollectionInterpreter table, the second cell of the first row says which method to call from the DoWithInterpreter fixture.

Consider the example of the Phone Book application as described in Collection Interpreters definition. The DoWithInterpreter will insert entries in the Phone Book. The ListOfInterpreter is then used to test that the Phone Book really contains the inserted entries.

1. We use the DoWithInterpreter to create our personal phone book.

do withphone book
insertFred Flintstonewith number(123) 456-7890
insertBarney Rubblewith number(123) 321-7666
insertGreat Gazoowith number(123) 989-4455

2. The test to be performed is: The requirement list should be the same as the SUD list.

list ofPhone book entries
FirstNameLastName
FredFlintstone
BettyRubble
GreatGazoo
WilmaFlintstone

Show me the code

Code Block
languagejava
titleCode for the PhoneBookFixture
public class PhoneBookFixture
{
    private PhoneBook phoneBook = new PhoneBook();
    public void insertWithNumber(String firstName, String lastName, String number)
    {
        phoneBook.insert(new PhoneBookEntry(firstName, lastName, number));
    }
    public List<PhoneBookEntry> query()
    {
        return phoneBook.entries();
    }
}
Code Block
languagejava
titleCode of the System Under Development
public class PhoneBook
{
    private List<PhoneBookEntry> entries = new ArrayList<PhoneBookEntry>();

    public void insert(PhoneBookEntry entry)
    {
        entries.add(entry);
    }

    public List<PhoneBookEntry> entries()
    {
        return entries;
    }
}
public class PhoneBookEntry
{
    public String firstName;
    public String lastName;
    public String number;

    public PhoneBookEntry(String firstName, String lastName, String number)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.number = number;
    }
}

Writing fixtures for derived List of Value (SetOf, SubsetOf, SupersetOf)

The fixture writing and results annotations are exactly similar in all points.
Of course the behavior of the test will vary see Collection Interpreters definition for detail.

Workflow validation (Do With)

Definition

DEFINITION

The DoWithInterpreter is used to express interactions with the system under development that must be performed in a particular order. This form of specification provides information about the business flow.

When a sequence of action is executed, Image Added confirms that each action has successfully been performed.

Image Added

  • As for all other interpreters, the first row of the DoWithInterpreter specifies the name of the interpreter and the name of the sequence of actions to be tested. What makes the DoWithInterpreter particular is that it only has to be defined once for all the sequences of actions expressed in a page. Obviously, the DoWithInterpreter must be define before any sequence of actions.
  • The following rows are used to express specific actions.
  • The form of each row of a DoWithInterpreter shall respect the following rules:
    • a row shall begin with a part of the action description,
    • each parameter shall be isolated in a cell,
    • each parameter shall be separated by parts of the action description.
  • An action description can be left blank in order to separate two parameters.
  • The DoWithInterpreter provides a minimum of keywords used to define a specific action.
  • The DoWithInterpreter may also be expressed in Bullet List form or Number List form.

Specific Keywords

Image Added offers a list of useful keywords to support the Business Expert. Those keywords are placed at the beginning of an action row.

AcceptConfirm that the action as been executed by the system under development.
CheckVerify the specified expected value with the value returned by the system under development
RejectThe action should not be performed by the system under development (expected errors).
DisplayPrint the value returned by the system under development.

Coloring

Image Added will visually show the test result by coloring each testing cell:

Panel
bgColorlightgreen
titleBGColorlightgreen
titleGreen
borderStyledashed

When the action has been executed successfully, Image Added color the cell(s) in green.

Panel
bgColor#f08080
titleBGColor#f08080
titleRed
borderStyledashed

If the action execution has failed, Image Added color the cell(s) in red.

Panel
bgColor#f0e68c
titleBGColor#f0e68c
titleYELLOW
borderStyledashed

If the system encounters an execution error, the cell is colored yellow and Image Added provides information about the error.

Panel
bgColorlightgrey
titleBGColorlightgrey
titleGrey
borderStyledashed

When the action has been executed successfully, Image Added will display the returned value in gray.

Standard form (without keyword)Only the Action description will be colored.
AcceptOnly the cell containing the keyword Accept will be colored.
CheckThe cell containing the expected value will be colored. In case of a failure, Image Added will show the expected and the returned values.
RejectOnly the cell containing the keyword Reject will be colored.
DisplayA new cell at the end of the row will be colored containing the returned value.

Writing fixtures for Do With tables

As we've seen in the Do With definition, a sequence of tables is used to express a business flow in the application under development.

When running the table, Image Added uses a fixture to mediate between the example expressed in the sequence of tables and the system under development. The fixture code defines how the specific actions are mapped to the application code.

This page shows the fixture code that supports the examples introduced in the Writing a Do With specification(link to-do).

Fixture for Bank

Consider the first example of business flow described in Writing a Do With specification(link to-do), shown again below.

do withbank
open checking account12345-67890under the name ofSpongebob Squarepants
checkthat balance of account12345-67890is$0.00
end

The first table indicates to use a DoWithInterpreter, which handles a business flow expressed as a sequence of tables. The fixture Bank will do the mediation with the application under development.

The interpreter will run all the tables until the end of the document. In this case, the second and third tables compose the business flow example.

The second table indicates to perform the action open checking account under the name of on the system under development, with the parameters 12345-67890, Spongebob and Squarepants. That action will result in a call to the method openCheckingAccountUnderTheNameOf() on the fixture with the parameters 12345-67890, Spongebob and Squarepants.

The third table indicates to check the result of the action that balance of account is on the system under development with the expected value $0.00. That action results in a call to the method thatBalanceOfAccountIs on the fixture with the parameter 12345-67890. That method is expected to return a value, which will be asserted for equality against the domain representation for the value $0.00.

The fixture code to support this example in Java is the class BankFixture shown below.

Show me the code

Code Block
languagejava
titleCode for the Bank fixture
public class BankFixture 
{
    private Bank bank;

    public BankFixture()
    {
        bank = new Bank();
    }

    public boolean openCheckingAccountUnderTheNameOf(String number, String firstName, String lastName)
    {
        return bank.openCheckingAccount(number, new Owner(firstName, lastName)) != null;
    }

    public Money thatBalanceOfAccountIs(String accountNumber) throws Exception
    {
        BankAccount account = bank.getAccount(accountNumber);
        return account.getBalance();
    }
}

That class follows the general rules of fixtures described in Fixture Conventions. It provides public instance methods openCheckingAccount and thatBalanceOfAccount to map respectively to the actions open checking account and that balance of account.

 

Workflow validation (Scenario)

...