next up previous
Next: About this document ... Up: More information on the Previous: Use case template

Testing

The following is an example on how to do the tests required in the exam project. The example will be discussed in detailed in the lecture in week 8 (April 12).

Consider you need to write the software for a vending machine.

Image of a vending machine

It is possible to insert coins and press buttons for bananas and apples. If enough money is input, a banana or an apple will be dispensed. There is a cancel button that cancels a transaction. All money that has been input so far will be returned.

There is only one use case Buy Fruit, but it has a lot of alternative scenarios because of all the possible ways to press the various buttons and to input coins.

Use Case: Buy Fruit

name: Buy fruit
description: Entering coins and buying a fruit
actor: user
main scenario:
(1.) Input coins until the price for the fruit to be selected is reached
(2.) Select a fruit
(3.) Vending machine dispenses fruit
alternative scenarios:
(a1) User inputs more coins than necessary
(a2) select a fruit
(a3) Vending machine dispenses fruit
(a4) Vending machine returns excessive coins
(b1) User inputs less coins than necessary
(b2) user selects a fruit
(b3) No fruit is dispensed
(b4) User adds the missing coins
(b5) Fruit is dispensed
(c1) User selects fruit
(c2) User adds sufficient or more coins
(c3) vending machine dispenses fruit and rest money
(d1) user enters coins
(d2) user selects cancel
(c3) money gets returned
(e1) user enters correct coins
(e2) user selects fruit but vending machine does not have the fruit anymore
(e3) nothing happens
(e4) user selects cancel
(e5) the money gets returned
(f1) user enters correct coins
(f2) user selects a fruit but vending machine does not have the fruit anymore
(f3) user selects another fruit
(f4) if money is correct fruit with rest money is dispensed; if money is not sufficient, the user can add more coins

The project description requires you to develop test cases for functional tests from use cases. First, you should develop the tables that define the input sets and then tables that define the test cases themselves, in the form described in the note on testing by Peter Sestoft, and then you should implement the test cases in JUnit.

Here is the first table for our vending machine use case defining the input sets with their input properties. Note that the table contains many different input sets corresponding closely to the various alternative scenarios of the use case.

Input data set Input property
A Exact coins; enough fruits; first coins, then fruit selection
B Exact coins; enough fruits; first fruit selection, then coins
C Exact coins; not enough fruits; first coins, then fruit selection, then cancel
D Exact coins; not enough fruits; first fruit selection, then coins, then cancel
E More coins; enough fruits; first coins, then fruit selection
F More coins; enough fruits; first fruit selection, then coins
G More coins; not enough fruits; first coins, then fruit selection, then cancel
H More coins; not enough fruits; first fruit selection, then coins, then cancel
I Less coins; enough fruits; first coins, then fruit selection
J Less coins; enough fruits; first fruit selection, then coins
K Less coins; not enough fruits; first coins, then fruit selection, then cancel
L Less coins; not enough fruits; first fruit selection, then coins, then cancel

Here is the second table describing the actual test cases based on the input set definition from the previous table, i.e. the current input that belongs to the input set and the expected output..

Input data set Contents Expected Output
A 1,2; apple apple dispensed
B Apple; 1,2 apple dispensed
C 1,2; apple; cancel no fruit dispensed; returned DKK 3
D Apple; 1,2; cancel no fruit dispensed; returned DKK 3
E 5, apple apple dispensed; returned DKK 2
F Apple; 5 apple dispensed; returned DKK 2
G 5, apple; cancel no fruit dispensed; returned DKK 5
H Apple; 5; cancel no fruit dispensed; returned DKK 5
I 5; banana no fruit dispensed; current money shows 5
J Banana; 5,1 no fruit dispensed; current money shows 6
K 5,1; banana; cancel no fruit dispensed; returned DKK 6
L Banana; 5,1;cancel no fruit dispensed; returned DKK 6

One way of running the tests is to run them manually, i.e. to start up the application and then, e.g. input coins 1 and 2 and then press apple. If the output of the machine is the same as the expected output, then the test was executed successfully, else unsuccessfully.

Manual tests are very costly and cannot be executed in their entirety very often. Therefore, one would like to execute these tests automatically, so that whenever one changes the code of the application one can run the tests again to see if one has broken some functionality or not. One way to do this (and the way you should be doing this in your project) is to use a layered architecture with a thin presentation layer and an application layer containing all the functionality. This can be called testing the system under the UI. In this case, each test case from the second table needs to have its own test method. Within a layered architecture, all the interactions with the system (e.g. button presses, mouse movements, etc.) are translated by the presentation layer to messages to the application layer (e.g. input(money), selectFruit(fruit), and cancel()). These messages can be used in JUnit test methods to simulate the user interaction. The following is an example of how the first 4 test cases of 12 test cases of second table can be implemented using JUnit.

    public void testInputDataSetA() {
        VendingMachine m = new VendingMachine(10, 10);
        m.input(1);
        m.input(2);
        assertEquals(3, m.getCurrentMoney());
        m.selectFruit(Fruit.APPLE);
        assertEquals(Fruit.APPLE, m.getDispensedItem());
    }

    public void testInputDataSetB() {
        VendingMachine m = new VendingMachine(10, 10);
        m.selectFruit(Fruit.APPLE);
        m.input(1);
        m.input(2);
        assertEquals(0, m.getCurrentMoney());
        assertEquals(Fruit.APPLE, m.getDispensedItem());
    }

    public void testInputDataSetC() {
        VendingMachine m = new VendingMachine(0, 0);
        m.input(1);
        m.input(2);
        assertEquals(3, m.getCurrentMoney());
        m.selectFruit(Fruit.APPLE);
        assertEquals(null, m.getDispensedItem());
        m.cancel();
        assertEquals(null, m.getDispensedItem());
        assertEquals(3, m.getRest());
    }

    public void testInputDataSetD() {
        VendingMachine m = new VendingMachine(0, 0);
        m.selectFruit(Fruit.APPLE);
        m.input(1);
        m.input(2);
        assertEquals(3, m.getCurrentMoney());
        m.cancel();
        assertEquals(null, m.getDispensedItem());
        assertEquals(3, m.getRest())
    }

   ...


next up previous
Next: About this document ... Up: More information on the Previous: Use case template
Hubert Baumeister 2010-04-12