Access Keys:
Skip to content (Access Key - 0)
 

3. List Validation (List of, Set of, Superset of, Subset of)

Definition

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

Colouring

will visually indicate the test result by colouring the rows:

GREEN

As expected, the row is returned by the system under development.

RED

A row is missing or in surplus in the list returned by the system under development.

* YELLOW*

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

Particular behaviour for the list of interpreters:
Since the ListOfInterpreter expects to match exactly the expected list and the list returned by the SUD, compares each cell of the table separately. If the expected value is different from the returned value, colours the cell in red and provide the two values.

Particular behaviour for the superset of interpreters:
Since the SupersetOfInterpreter accepts that the specification may contain rows that are not contained in the SUD, will not colour the rows contained in the specification but not returned by the SUD.

Writing fixtures for List tables

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, 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

Import
com.greenpepper.samples.application.phonebook

Using the CollectionInterpreter alone

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

list of Canada Province Codes
Name Code
ALBERTA AB
BRITISH COLUMBIA BC
MANITOBA MB
NEW BRUNSWICK NB
NEWFOUNDLAND and LABRADOR NL
NOVA SCOTIA NS
NUNAVUT NU
ONTARIO ON
PRINCE EDWARD ISLAND PE
QUEBEC QC
SASKATCHEWAN SK
YUKON YT
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#.

public Collection query() {...}
or
    public ICollection Query() {...}

The return type of the query method does not have to be specifically a Collection/ICollection.
It can be any of the derived Collection class or an Array.

public Employees[] query() {...}
or
    public Set<Something> Query() {...}

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

import com.greenpepper.reflect.CollectionProvider;
   ...
    @CollectionProvider
    public Collection query() {...}
or
    using GreenPepper.Reflect;
   ...
    [CollectionProvider]
    public ICollection Query() {...}

but the method specifies still have to be parameterless and return a Collection/ICollection implementation or an array.

Show me the code

Code for the CanadaProvinceCodesFixture
public class CanadaProvinceCodesFixture
{
    public Set<Province> query()
    {
        return Country.canada().provinces();
    }
}
Code 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, 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.
Begin Info

For the third row 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.
End Info

Step 2 and 3 are repeated through the remaining rows of the table.
For the fourth row, the Codes are not the same so 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. 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, 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 with phone book
insert Fred   Flintstone with number (123) 456-7890
insert Barney   Rubble with number (123) 321-7666
insert Great   Gazoo with number (123) 989-4455

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

list of Phone book entries
FirstName LastName
Fred Flintstone
Betty Rubble
Great Gazoo
Wilma Flintstone

Show me the code

Code 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 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 writting and results annotations are exactly similar in all points.
Of course the behavior of the test will varry see Collection Interpreters definition for detail.

Adaptavist Theme Builder (3.1.4) Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.4.3 Build:#705 Mar 21, 2007)
Free theme builder license