• Keine Ergebnisse gefunden

4.5 Test Selection

4.5.3 All-Configurations

UML Statecharts may have orthogonal states, where each region inside the state runs in parallel. To ensure that a test suite covers the possible combinations of active states arising from orthogonal states, we need special test selection criteria. Before we go into the details of the criteria, we first introduce the definition of aconfiguration:

Definition4.4 (Configuration (Space)). Aconfigurationis a snapshot of the currently active states in an UML Statechart. A configurationCifor a Statechart is the set of states that are active at the same time. C0is the initial state and consecutive configurations can be found by supposing that the outgoing transitions of a configuration can be fired. Theconfiguration spaceis the set of possible configurations of an UML Statechart.

In our Online Storage Example (Fig. 4.4), the initial configuration of theServercomponent isC0 = {init}. To find the next configuration, we assume that the outgoing transition t0 fires. This results in a new configurationC1 ={main, main.init, disc, disc.init}, where main.initdenotes the state init inside the combined state main. At this point, we can choose between firing the transitiont1 ort8. While the former results in the con-figurationC2 = {main, main.idle, disc, disc.init}, the latter gives the configuration C2 ={main, main.init, disc, disc.spaceAvailable}. Following this algorithm, we get a configuration space of 16 possible configurations for theServercomponent.

A practical way to visualize these configurations and the transitions between them is a reachability tree(Masiero et al., 1994). The reachability tree is a 4-tupleRT =< SC, T, , C0 >, withSCbeing the set of possible configurations,T being the set of transitions, the

4.5. Test Selection 79

transition functionbeing a partial function fromSC×TtoSC, andC0∈SCbeing the initial configuration (Masiero et al., 1994). Figure 4.15 presents the reachability tree of the Servercomponent. It shows the 16 configurations (C0, C1, . . . , C15). In each configuration, the active state is denoted with1and an inactive state with0. In the tree, a node denoted with↑Ciis calledhistory nodeand represents a loop in the Statecharts configuration. The means that this node is not a terminal node and the path continues at the first occurrence ofCi. With the help of the reachability tree, we can introduce our test selection criteria for covering parallelism in UML Statecharts:

Definition4.5 (all-configurations). All-Configuration coverage is achieved if every configu-ration of the model is visited at least once.

Applying the definition for all-configurations (Def. 4.5) to our test models, full coverage is achieved when our test suite visits each configuration, or in terms of the reachability tree every node of the tree, at least once. In our Online Storage Example (Fig. 4.4) the following four test cases achieveall-configurationscoverage for theservercomponent:

1. t0;t1;t2;t6;t7;t8;t9 2. t0;t1;t2;t6;t8;t9 3. t0;t1;t2;t8;t9

4. t0;t1;t8;t9

5. t0;t8;t9

This corresponds to following actions in the SUT:

1. • server is ready and idle (t0;t1),

• server receives a file upload request (t2;t6),

• server authenticates the client and approves the transfer (t7),

• server initialized the disk space availability part and recognizes a full disc (t8;t9), 2. • server is ready and idle (t0;t1),

• server receives a file upload request (t2;t6),

• server initialized the disk space availability part and recognizes a full disc (t8;t9), 3. • server is ready and idle (t0;t1),

• server receives a file upload request (t2),

• server initialized the disk space availability part and recognizes a full disc (t8;t9), 4. • server is ready and idle (t0;t1),

C = {(init),(main.init, main.idle, main.receive, main.receive.init, (states) main.receive.receivedF ileReq, main.receive.receivingF ile),

(disc.init, disc.spaceAvailable, disc.discF ull)}

SC = C0={1,(0,0,0,0,0,0),(0,0,0)}C8={0,(0,0,1,1,0,0),(0,1,0)} (configurations)

Figure 4.15.:Reachability tree for the Server component of the Online Storage Example (Fig. 4.4).

1 ReachabilityTree rt =newReachabilityTree();

2 Queue<Configuration> agenda =newQueue<Configuration>();

3

4 ReachabilityTree buildReachabilityTree(uml::Statemachine sm) {

5 Configuration initConfiguration =newConfiguration(collectInitialStatesFor(sm));

6

7 enqueueNewConfiguration(initConfiguration);

8

9 while (!agenda.isEmpty()) {

10 Configuration c = agenda.dequeue();

11

12 for (Vertex vertex : c.getVertices()) {

13 for (Transition t : vertex.getOutgoings()) {

14 Configuration newConf = getNextConfiguration(configuration, vertex, t);

15 Configuration historyConf = rt.getConfiguration(newConf);

16

17 if(historyConf != null) {

18 newConf = historyConf;

19 } else {

20 enqueueNewConfiguration(newConf);

21 }

22

23 ConfigurationTransition ct = createConfigurationTransition(rt, c, t, newConf);

24 rt.getConfigurationTransitions().add(ct);

25 c.getOutgoings().add(ct);

26 }

27 }

28 }

29 returnrt;

30 }

31

32 void enqueueNewConfiguration(mbtrs::Configuration c) {

33 agenda.add(c);

34 rt.getConfigurations().add(c);

35 }

Listing 4.4:Pseudo code of the algorithm to build a reachability tree using a classical breadth-first search.

4.5. Test Selection 83

ability tree is built using a classical breadth-first algorithm. Listing 4.4 shows the pseudo code of our algorithm (the missing functions of the algorithm can be found in the Ap-pendix C). The shown functionbuildReachabilityTreetakes an UML Statechart and builds the reachability tree for it. It uses a queue data structure (variableagenda) to store interme-diate configurations and transitions between configurations as it traverses the configuration space, as follows:

1. collect the first configuration using the initial states of the Statechart, and enqueue this configuration (line 7)

2. dequeue a configuration (line 10) and examine it:

• determine the set of successors (the direct child configurations) by traversing every outgoing transition of every state in the dequeued configuration (line 14)

• If the child configuration is a new configuration (not a already known history node), then enqueue it

• If the child configuration is a new configuration (not a already known history node), then enqueue it

3. If the queue is empty, quit and return the resulting reachability tree (line 29) 4. If the queue is not empty, repeat from step 2

The model-to-model transformation for all-configurations is completed by converting the configurations of the resulting reachability tree intoConfigurationTestCaseSpecification el-ements (listing 4.3, line 7 to 9).