This section and the next one describe combinatorial test models based on UML state machine diagrams. UML state machines are an extension of tra- ditional finite state machines: They can have hierarchically nested states and actions associated with the entry and exit of the states. A UML state machine also can describe multiple regions operating concurrently. Each region of a UML state machine has its own states, and the overall operation reflects all the regions interacting with each other and external stimuli. The test mod- els described here depend not only on the diagrammed state, but also on associated program variables, which may include inputs from set-up states, database values, and so on. Together the state and program variables define the extended state, which must be set correctly for repeatable test results.
Behaviors of a state machine region are defined by its state transitions, so testing the SUT models involves testing transitions. This consists of setting up the source (from) state, triggering the transition, and observing what happens. The expected result is the action of the transition to the tar- get (to) state indicated by the state machine diagram. Test factors include the source state, associated program variables, and the event expected to trigger the transition. Execution of each test case involves applying a sequence of set-up inputs to the SUT so that it is in the specified source
www.Ebook777.com
state with program variables set to the test case values. With the extended state set, the trigger is applied and results observed.
The online shopping cart state diagram is shown in Figure 6.3. Tables 6.8 through 6.10 describe actions in the diagram using pseudocode. The shopping cart has two lowest-level leaf states—emptyCart and nonempty- Cart; transitions to/from these states, as well as the shopping and checkout states, are to be tested. There are eight possible transitions among the four states, as shown in the left column of Table 6.11. The transition model tests each transition in its own partition. In this model, the partition is associ- ated only with the source and target states of its transition. (The source state is a single-value factor; the expected target state is determined by the event factor.) Consequently, all the t-tuples in the partition also are associ- ated with the source and target states.
A second model—the target state model—follows when the eight tran- sitions are grouped into four partitions according to their target states (right column of Table 6.11). In the target state model, all t-tuples in each partition are associated with the corresponding target state. Each source state is covered with strength t, but it might not be associated with all the
entry/addItem();
cart
[n>0] [else]
emptyCart entry/displayCartStart();
displayButton(SHOP);
displayCartEnd();
CHECK(i)[0<=i&&i<n]/delChk(i)=1-delChk(i);
QTY(i,q)[0<=i&&i<n]/newQ[i]=q;
SHOP CHECKOUT UPDATE/updateItems();
exit/for(i=0;i<n;i++){
delChk[i] = 0;
newQ[i]=qty[i];
}
nonemptyCart entry/displayNonemptyCart();
FIGURE 6.3 Shopping cart state diagram. Transitions among the leaf states (nonemptyCart and emptyCart) and the shopping and checkout states are to be tested. Pseudocode for the actions addItem(), displayNonemptyCart(), and updateItems() is given in Tables 6.8 through 6.10.
128 ◾ Introduction to Combinatorial Testing
t-tuples in the partition. The transition model can be more thorough than the target state model because all allowed t-tuples are exercised with the source state, as well as the target state. The transition model designs gener- ally yield more test cases also: In the shopping cart example, the transition model design has 187 pairwise test cases; the target state design has 172.
Test factors and values for the shopping cart example, are shown in Table 6.12. The same factors and values are used in both models. As before, the test design allows up to three different items to be placed in the cart.
Most of the test factors are program variables from the state diagram.
(These may or may not correspond to variables in the implementation.) The state and event factors are respectively the source state and the trigger for the transition to the target state.
There are 16 blocks for transitions to the nonemptyCart state. In the tar- get state model, they are grouped into one partition as follows. The first four
TABLE 6.8 Pseudocode for addItem() Action on Entry to the cart State in Figure 6.3 addItem() { /* cart entry */
if(!isset(n)) n=0;
if(isset(newItem)) { for(i=0; i<n; i++) {
if(newItem==item[i]) {
/* increment quantity of item in cart */
qty[i]++;
newQ[i]=qty[i];
itemTotal[i]=qty[i]*price[i];
break;
}
if(i==n-1) {
/* item not in cart – look in catalog */
select ctlgItem, ctlgDesc, ctlgPrice from ctlg where ctlgItem=newItem;
if(isset(ctlgItem)) { delChk[n]=0;
item[n]=ctlgItem;
desc[n]=ctlgDesc;
qty[n]=1;
newQ[n]=1;
price[n]=ctlgPrice;
itemTotal[n]=ctlgPrice;
n++;
unset(ctlgItem);
} } }
unset(newItem);
} }
Note: When a new item is already in the shopping cart, its quantity is incremented.
Otherwise, the new item is looked up in the catalog database.
TABLE 6.10 Pseudocode for updateItems() Action on the UPDATE Transition from the nonemptyCart State to Its Containing State cart in Figure 6.3
updateItems() { /* nonemptyCart UPDATE */
newI=0;
for(i=0; i<n; i++) {
if(delChk[i]==1||newQ[i]==0) continue;
/* skip removed items */
delChk[newI]=0;
item[newI]=item[i];
desc[newI]=desc[i];
if(newQ[i]>0) {
/* update valid quantities */
qty[newI]=newQ[i];
newQ[newI}=newQ[i];
}
else {
/* ignore invalid quantities */
qty[newI]=qty[i];
newQ[newI]=qty[i];
}
price[newI]=price[i];
itemTotal[newI]=qty[newI]*price[newI];
newI++;
} n=newI;
}
Note: Removed items are skipped; items with valid new quantities are updated; item totals are recomputed.
TABLE 6.9 Pseudocode for displayNonemptyCart() Action on Entry to the nonemptyCart State in Figure 6.3
displayNonemptyCart() {/* nonemptyCart entry */
displayCartStart();
subtotal=0;
for(i=0; i<n; i++) {
displayItem(delChk[i], item[i], desc[i], newQ[i], price[i], itemTotal[i]);
subtotal+=itemTotal[i];
}
displaySubtotal(subtotal);
displayButton(SHOP);
displayButton(UPDATE);
displayButton(CHECKOUT);
displayCartEnd();
}
Note: Each item in the cart is displayed; the subtotal and the SHOP, UPDATE, and CHECKOUT buttons are displayed, as shown in Figure 6.2.
130 ◾ Introduction to Combinatorial Testing
blocks are from the shopping state when there are 0−3 different items already in the cart. (These blocks comprise one partition in the transition model.) The next nine blocks are from and to the nonemptyCart state. The CHECK, QTY, and UPDATE events each use three blocks for when there are 1−3 items already in the cart. The last three blocks are from the checkout state to the nonemptyCart. Table 6.13 shows the first 10 of 74 test cases for the nonemptyCart partition in the target state model. These test cases can be set up and executed using automation scripts like those of the sequence units in Table 6.5. The design details for both models, including the DPB notation for their partitions, are available in the Testcover.com tutorial [197].
The transitions to the nonemptyCart state provide a few examples of constraint simplification with functionally dependent values. First, the exit action of the cart state (Figure 6.3) resets newQ[i], the new quantity shown in cart position i (which may have been be changed), back to qty[i], the cur- rent quantity of that item. Thus, in normal operation, the value of newQ[0]
is constrained to be the same as qty[0] in transitions back to the nonemp- tyCart state from the shopping state. Similar constraints occur for newQ[1]
and newQ[2], as well as for transitions back from the checkout state. Here blocks are not split to make the values of newQ[0] match those of qty[0]
for these transitions: Test cases are generated with qty[0] as the value for newQ[0], and the corresponding value is substituted afterwards. Similar substitutions are made for newQ[1] and newQ[2]. Different examples of functionally dependent values occur in the transition from and to the non- emptyCart state. Here, there are three events, CHECK(i), QTY(i,q), and
TABLE 6.11 Partitions for the Shopping Cart State Diagram of Figure 6.3
Transition Model Target State Model
# shopping to emptyCart # all states to emptyCart
# nonemptyCart to emptyCart
# shopping to nonemptyCart # all states to nonemptyCart
# nonemptyCart to nonemptyCart
# checkout to nonemptyCart
# emptyCart to shopping # all states to shopping
# nonemptyCart to shopping
# nonemptyCart to checkout # all states to checkout Note: In the transition model, each allowed transition has its own partition. In the target
state model, all the transitions to each target state are included in one partition. The same factors, values, and blocks are used in both models. For example, the blocks comprising the three transitions to the nonemptyCart state in the transition model are grouped into one partition for the target state model.
UPDATE. (q is the candidate new quantity for cart position i.) The action of CHECK(i) is determined by i; the action of QTY(i,q) is determined by both i and q; but UPDATE does not depend on either.
Both the transition model and the target state model follow the state machine diagram systematically. Their use ensures coverage of all state transitions defined by the state machine. In this example, the sequence
TABLE 6.12 Test Factors and Values for the Shopping Cart State Diagram of Figure 6.3
Test Factor Test Factor Values Indication
newItem unset itemA itemB itemC Item to place in cart n unset 0 1 2 3 Number of items in cart delChk[0] n/a 0 1 Delete box checked in
cart position 0
item[0] n/a itemA itemB itemC Item in cart position 0 qty[0] n/a 1 2 10 Quantity of item in
cart position 0
newQ[0] n/a 0 1 2 10 qty[0] New quantity shown in cart position 0
delChk[1] n/a 0 1 Delete box checked in cart position 1
item[1] n/a itemB itemC Item in cart position 1 qty[1] n/a 1 2 10 Quantity of item in
cart position 1
newQ[1] n/a 0 1 2 10 qty[1] New quantity shown in cart position 1
delChk[2] n/a 0 1 Delete box checked in cart position 2
item[2] n/a itemC Item in cart position 2 qty[2] n/a 1 2 10 Quantity of item in
cart position 2
newQ[2] n/a 0 1 2 10 qty[2] New quantity shown in cart position 2
i n/a 0 1 2 Cart position for event
q n/a 0 1 2 10 Quantity for event
state shopping emptyCart nonemptyCart checkout
Source state event SHOP CART
CHECK(i)[0<=i&&i<n]
QTY(i,q)[0<=i&&i<n]
UPDATE CHECKOUT
Trigger to target state
Note: The first 16 factors are program variables controlling the set-up and test of the cart transition. The last two factors are the source state and the transition event. The expected result is the transition to the target state. In this example up to three differ- ent items are placed into the cart. A factor with the value n/a indicates that the factor is not applicable to the transition test case.
132 ◾ Introduction to Combinatorial Testing
TABLE 6.13 Test Cases for Shopping Cart Target State Model newItemndelChk[0]item[0]qty[0]newQ[0]delChk[1]item[1]qty[1]newQ[1]delChk[2]item[2]qty[2]newQ[2]iqstateevent itemAunsetn/an/an/aqty[0]n/an/an/aqty[1]n/an/an/aqty[2]n/an/ashoppingCART unset30itemA100itemB100itemC100n/anonemptyCartCHECK(i)[0<=i&&i<n] unset21itemB201itemC21n/an/an/an/a11nonemptyCartQTY(i,q)[0<=i&&i<n] unset31itemA1021itemB1021itemC10222nonemptyCartQTY(i,q)[0<=i&&i<n] unset10itemC1010n/an/an/an/an/an/an/an/an/an/anonemptyCartUPDATE unset30itemA2qty[0]0itemB2qty[1]0itemC2qty[2]n/an/acheckoutCART itemC20itemB1qty[0]0itemC10qty[1]n/an/an/aqty[2]n/an/ashoppingCART unset31itemA2101itemB2101itemC210110nonemptyCartQTY(i,q)[0<=i&&i<n] unset31itemA111itemB111itemC1101nonemptyCartQTY(i,q)[0<=i&&i<n] unset10itemB12n/an/an/an/an/an/an/an/a00nonemptyCartQTY(i,q)[0<=i&&i<n] Note: There are 74 test cases in the nonemptyCart partition; the first 10 are shown here. In the first test case, itemA is placed in the cart, from the shop- ping state. The second test case is set up with three items in the cart with their new quantities set to 0; the delete box is checked in cart position 0 in this transition from and to the nonemptyCart state. In the transitions from shopping or checkout, newQ[0] is determined by qty[0] because newQ[0] = qty[0]. Similarly, newQ[1] and newQ[2] are determined by qty[1] and qty[2], respectively. In the transitions from nonemptyCart, CHECK(i) is determined by i, and QTY(i,q) is determined by i and q.
unit replay design tests much of the shopping cart behavior, but it has no transition to an empty cart, no return from checkout, and so on. The transition model and the target state model do cover these transitions, and require more test cases to do so.