COMPLEXITY OF APPLYING FUNCTIONAL TESTING
9.2 COMPLEXITY OF APPLYING FUNCTIONAL TESTING
In order to have an idea of the difficulty in applying the concept of functional testing, let us summarize the main points in functional testing in the following:
• Identify the input and the output variables of the program and their data domains.
• Compute the expected outcomes as illustrated in Figure 9.5a for selected input values.
• Determine the input values that will cause the program to produce selected outputs as illustrated in Figure 9.5b.
233 Input domains
9.2 COMPLEXITY OF APPLYING FUNCTIONAL TESTING
Output domains
(a)
Input domains
Output domains
(b)
Figure 9.5 (a) Obtaining output values from an input vector and (b) obtaining an input vector from an output value in functional testing.
Generating test data by analyzing the input domains has the following two charac- teristics.
• The number of test cases obtained from an analysis of the input domains is likely to be too many because of the need to design test vectors representing different combinations of special values of the input variables.
• Generation of the expected output for a certain test vector is relatively simple. This is because a test designer computes an expected output from an understanding and analysis of the specification of the system.
On the other hand, generating test data by analyzing the output domains has the following characteristics:
• The number of test cases obtained from an analysis of the output domains is likely to be fewer compared to the same number of input variables because there is no need to consider different combinations of special values of the output variables.
• Generating an input vector required to produce a chosen output value will require us to analyze the specification in the reverse direction, as illustrated
in Figure 9.5b. Such reverse analysis will be a more challenging task than
234 CHAPTER 9 FUNCTIONAL TESTING
computing an expected value in the forward direction, as illustrated in Figure 9.5a.
So far in this section we have discussed the ways to apply the idea of functional testing to an entire program. However, the underlying concept, that is, analyzing the input and output domains of a program, can as well be applied to individual modules, functions, or even lines of code. This is because every comput- ing element can be described in terms of its input and output domains, and hence the idea of functional testing can be applied to such a computing element.
Referring to Figure 9.6, program P is decomposed into three modules M 1 , M 2 , and M 3 . In addition, M 1 is composed of functions f 1 and f 5 ,M 2 is composed of functions f 2 and f 3 , and M 3 is composed of functions f 4 and f 6 . We can apply the idea of functional testing to the entire program P , individual modules M 1 ,M 2 , and M 3 , and individual functions f 1 ,...,f 6 by considering their respective input and output domains as listed in Table 9.2.
M 2 Figure 9.6 Functional testing in general.
TABLE 9.2 Input and Output Domains of Functions of P in Figure 9.6
Entity Name Input Variables
Output Variables
{x 1 ,x 2 ,x 3 ,x 4 }
{z}
M 1 {x 1 ,x 2 }
{y 5 }
M 2 {x 3 ,x 4 }
{y 4 }
M 3 {y 4 ,y 5 }
{z}
f 1 {x 1 ,x 2 }
{y 1 }
f 2 {x 3 ,x 4 ,y 3 }
{y 2 ,y 4 }
f 3 {y 2 }
{y 3 }
f 4 {y 4 }
{y 6 }
f 5 {y 1 }
{y 5 }
f 6 {y 5 ,y 6 }
{z}
235 Conceptually, one can apply functional testing at any level of abstraction,
9.3 PAIRWISE TESTING
from a single line of code at the lowest level to the entire program at the highest level. As we consider individual modules, functions, and lines of code, the task of accurately identifying the input and output domains of the computing element under test becomes more difficult.
The methodology for developing functional test cases is an analytical process that decomposes specification of a program into different classes of behaviors. The functional test cases are designed for each class separately by identifying the input and output domains of the class. Identification of input and output domains help in classifying the specification into different classes. However, often, in practice, the total number of input and output combinations can be very large. Several well-known techniques are available to tackle this issue, which we discuss in the following sections.