Other books that focus on procedural design issues include those by Robert- pro-son Simple Program Design, Boyd and Fraser Publishing, 1994, Bentley Programming Pearls, Addison-Wesley, 1
Trang 11 5 7 S U M M A R Y
The user interface is arguably the most important element of a computer-based tem or product If the interface is poorly designed, the user’s ability to tap the com-putational power of an application may be severely hindered In fact, a weak interfacemay cause an otherwise well-designed and solidly implemented application to fail.Three important principles guide the design of effective user interfaces: (1) placethe user in control, (2) reduce the user’s memory load, and (3) make the interfaceconsistent To achieve an interface that abides by these principles, an organized designprocess must be conducted
sys-User interface design begins with the identification of user, task, and mental requirements Task analysis is a design activity that defines user tasks andactions using either an elaborative or object-oriented approach
environ-Once tasks have been identified, user scenarios are created and analyzed to define
a set of interface objects and actions This provides a basis for the creation of screenlayout that depicts graphical design and placement of icons, definition of descriptivescreen text, specification and titling for windows, and specification of major and minormenu items Design issues such as response time, command and action structure,error handling, and help facilities are considered as the design model is refined Avariety of implementation tools are used to build a prototype for evaluation by theuser
The user interface is the window into the software In many cases, the interfacemolds a user’s perception of the quality of the system If the “window” is smudged,wavy, or broken, the user may reject an otherwise powerful computer-based system
R E F E R E N C E S
[LEA88] Lea, M., "Evaluating User Interface Designs," User Interface Design for puter Systems, Halstead Press (Wiley), 1988
Com-[MAN97] Mandel, T., The Elements of User Interface Design, Wiley, 1997
[MON84] Monk, A (ed.), Fundamentals of Human-Computer Interaction, Academic
Press, 1984
[MOR81] Moran, T.P., "The Command Language Grammar: A Representation for the
User Interface of Interactive Computer Systems," Intl Journal of Man-Machine ies, vol 15, pp 3–50.
Stud-[MYE89] Myers, B.A., "User Interface Tools: Introduction and Survey, IEEE Software,
January 1989, pp 15–23
[NOR86] Norman, D.A., "Cognitive Engineering," in User Centered Systems Design,
Lawrence Earlbaum Associates, 1986
[RUB88] Rubin, T., User Interface Design for Computer Systems, Halstead Press (Wiley),
1988
[SHN90] Shneiderman, B., Designing the User Interface, 3rd ed., Addison-Wesley, 1990.
Trang 2P R O B L E M S A N D P O I N T S T O P O N D E R
15.1 Describe the worst interface that you have ever worked with and critique it
relative to the concepts introduced in this chapter Describe the best interface thatyou have ever worked with and critique it relative to the concepts introduced in thischapter
15.2 Develop two additional design principles that “place the user in control.”
15.3 Develop two additional design principles that “reduce the user’s memory load.”
15.4 Develop two additional design principles that “make the interface consistent.”
15.5 Consider one of the following interactive applications (or an application
assigned by your instructor):
a A desktop publishing system
b A computer-aided design system
c An interior design system (as described in Section 15.3.2)
d An automated course registration system for a university
e A library management system
f An Internet-based polling booth for public elections
g A home banking system
h An interactive application assigned by your instructor
Develop a design model, a user model, a system image, and a system perception forany one of these systems
15.6 Perform a detailed task analysis for any one of the systems listed in Problem
15.5 Use either an elaborative or object-oriented approach
15.7 Continuing Problem 15.6, define interface objects and actions for the
applica-tion you have chosen Identify each object type
15.8 Develop a set of screen layouts with a definition of major and minor menu
items for the system you chose in Problem 15.5
15.9 Develop a set of screen layouts with a definition of major and minor menu
items for the advanced SafeHome system described in Section 15.4.1 You may
elect to take a different approach than the one shown for the screen layout in Figure15.2
15.10 Describe your approach to user help facilities for the task analysis design
model and task analysis you have performed as part of Problems 15.5 through 15.8
15.11 Provide a few examples that illustrate why response time variability can be
an issue
15.12 Develop an approach that would automatically integrate error messages and
a user help facility That is, the system would automatically recognize the error type
Trang 3and provide a help window with suggestions for correcting it Perform a reasonablycomplete software design that considers appropriate data structures and algorithms.
15.13 Develop an interface evaluation questionnaire that contains 20 generic
tions that would apply to most interfaces Have ten classmates complete the tionnaire for an interactive system that you all use Summarize the results and reportthem to your class
ques-F U R T H E R R E A D I N G S A N D I N ques-F O R M AT I O N S O U R C E S
Although his book is not specifically about human/computer interfaces, much of what
Donald Norman (The Design of Everyday Things, reissue edition,
Currency/Double-day, 1990) has to say about the psychology of effective design applies to the user face It is recommended reading for anyone who is serious about doing high-qualityinterface design
inter-Dozens of books have been written about interface design over the past decade.However, books by Mandel [MAN97] and Shneiderman [SHN90] continue to provide
the most comprehensive (and readable) treatments of the subject Donnelly (In Your Face: The Best of Interactive Interface Design, Rockport Publications, 1998); Fowler, Stanwick, and Smith (GUI Design Handbook, McGraw-Hill, 1998); Weinschenk, Jamar, and Yeo (GUI Design Essentials, Wiley, 1997); Galitz (The Essential Guide to User Inter- face Design: An Introduction to GUI Design Principles and Techniques, Wiley, 1996); Mul- let and Sano (Designing Visual Interfaces: Communication Oriented Techniques, PrenticeHall, 1995); and Cooper (About Face: The Essentials of User Interface Design,
IDG Books, 1995) have written treatments that provide additional design guidelinesand principles as well as suggestions for interface requirements elicitation, designmodeling, implementation, and testing
Task analysis and modeling are pivotal interface design activities Hackos and
Redish (User and Task Analysis for Interface Design, Wiley, 1998) have written a book
dedicated to these subjects and provide a detailed method for approaching task
analy-sis Wood (User Interface Design: Bridging the Gap from User Requirements to Design,
CRC Press, 1997) considers the analysis activity for interfaces and the transition
to design tasks One of the first books to present the subject of scenarios in
user-interface design has been edited by Carroll (Scenario-Based Design: Envisioning Work and Technology in System Development, Wiley, 1995) A formal method for design of
user interfaces, based on state-based behavior modeling has been developed by
Hor-rocks (Constructing the User Interface with Statecharts, Addison-Wesley, 1998) The evaluation activity focuses on usability Books by Rubin (Handbook of Usabil- ity Testing: How to Plan, Design, and Conduct Effective Tests, Wiley, 1994) and Nielson (Usability Inspection Methods, Wiley, 1994) address the topic in considerable detail.
The Apple Macintosh popularized easy to use and solidly designed user interfaces
The Apple staff (MacIntosh Human Interface Guidelines, Addison-Wesley, 1993)
Trang 4dis-cusses the now famous (and much copied) Macintosh look and feel One of the liest among many books written about the Microsoft Windows interface was pro-
ear-duced by the Microsoft staff (The Windows Interface Guidelines for Software Design: An Application Design Guide, Microsoft Press, 1995)
In a unique book that may be of considerable interest to product designers,
Mur-phy (Front Panel: Designing Software for Embedded User Interfaces, R&D Books, 1998)
provides detailed guidance for the design of interfaces for embedded systems andaddresses safety hazards inherent in controls, handling heavy machinery, and inter-faces for medical or transport systems Interface design for embedded products is
also discussed by Garrett (Advanced Instrumentation and Computer I/O Design: Time System Computer Interface Engineering, IEEE, 1994).
Real-A wide variety of information sources on user interface design and related jects is available on the Internet An up-to-date list of World Wide Web referencesthat are relevant to interface design issues can be found at the SEPA Web site:
sub-http://www.mhhe.com/engcs/compsci/pressman/resources/
interface-design.mhtml
Trang 6Component-level design, also called procedural design, occurs after data,
architectural, and interface designs have been established The intent
is to translate the design model into operational software But the level
of abstraction of the existing design model is relatively high, and the tion level of the operational program is low The translation can be challeng-ing, opening the door to the introduction of subtle errors that are difficult to findand correct in later stages of the software process In a famous lecture, EdsgarDijkstra, a major contributor to our understanding of design, stated [DIJ72]: Software seems to be different from many other products, where as a rule higherquality implies a higher price Those who want really reliable software will discoverthat they must find a means of avoiding the majority of bugs to start with, and as aresult, the programming process will become cheaper effective programmers should not waste their time debugging—they should not introduce bugs to startwith
abstrac-Although these words were spoken many years ago, they remain true today.When the design model is translated into source code, we must follow a set ofdesign principles that not only perform the translation but also do not “intro-duce bugs to start with.”
What is it? Data, architectural,and interface design must betranslated into operational soft-ware To accomplish this, the design must be rep-
resented at a level of abstraction that is close to
code Component-level design establishes the
algorithmic detail required to manipulate data
structures, effect communication between
soft-ware components via their interfaces, and
imple-ment the processing algorithms allocated to each
component
Who does it? A software engineer performs
component-level design
Why is it important? You have to be able to
deter-mine whether the program will work before you
build it The component-level design representsthe software in a way that allows you to reviewthe details of the design for correctness and con-sistency with earlier design representations (i.e.,the data, architectural, and interface designs) Itprovides a means for assessing whether data struc-tures, interfaces, and algorithms will work
What are the steps? Design representations of data,architecture, and interfaces form the foundationfor component-level design The processing nar-rative for each component is translated into a pro-cedural design model using a set of structuredprogramming constructs Graphical, tabular, ortext-based notation is used to represent thedesign
Q U I C K
L O O K
Trang 7It is possible to represent the component-level design using a programming guage In essence, the program is created using the design model as a guide An alter-native approach is to represent the procedural design using some intermediate (e.g.,graphical, tabular, or text-based) representation that can be translated easily intosource code Regardless of the mechanism that is used to represent the component-level design, the data structures, interfaces, and algorithms defined should conform
lan-to a variety of well-established procedural design guidelines that help us lan-to avoiderrors as the procedural design evolves In this chapter, we examine these designguidelines
logi-The constructs are sequence, condition, and repetition Sequence implements cessing steps that are essential in the specification of any algorithm Condition pro-
pro-vides the facility for selected processing based on some logical occurrence, and
repetition allows for looping These three constructs are fundamental to structured programming—an important component-level design technique.
The structured constructs were proposed to limit the procedural design of ware to a small number of predictable operations Complexity metrics (Chapter 19)indicate that the use of the structured constructs reduces program complexity andthereby enhances readability, testability, and maintainability The use of a limitednumber of logical constructs also contributes to a human understanding process that
soft-psychologists call chunking To understand this process, consider the way in which
you are reading this page You do not read individual letters but rather recognize terns or chunks of letters that form words or phrases The structured constructs are
pat-What is the work product? Theprocedural design for each com-ponent, represented in graphical,tabular, or text-based notation, is the primary work
product produced during component-level design
How do I ensure that I’ve done it right? A design
walkthrough or inspection is conducted The
design is examined to determine whether datastructures, interfaces, processing sequences, andlogical conditions are correct and will produce theappropriate data or control transformation allo-cated to the component during earlier designsteps
Q U I C K
L O O K
“When I'm working
on a problem, I
never think about
beauty I think only
how to solve the
problem But when I
have finished, if the
Trang 8logical chunks that allow a reader to recognize procedural elements of a module,rather than reading the design or code line by line Understanding is enhanced whenreadily recognizable logical patterns are encountered.
Any program, regardless of application area or technical complexity, can bedesigned and implemented using only the three structured constructs It should benoted, however, that dogmatic use of only these constructs can sometimes causepractical difficulties Section 16.1.1 considers this issue in further detail
16.1.1 Graphical Design Notation
"A picture is worth a thousand words," but it's rather important to know which ture and which 1000 words There is no question that graphical tools, such as theflowchart or box diagram, provide useful pictorial patterns that readily depict proce-dural detail However, if graphical tools are misused, the wrong picture may lead tothe wrong software
pic-A flowchart is quite simple pictorially pic-A box is used to indicate a processing step
A diamond represents a logical condition, and arrows show the flow of control
Fig-ure 16.1 illustrates three structFig-ured constructs The sequence is represented as two processing boxes connected by an line (arrow) of control Condition, also called if- then-else, is depicted as a decision diamond that if true, causes then-part processing
to occur, and if false, invokes else-part processing Repetition is represented using two slightly different forms The do while tests a condition and executes a loop task repetitively as long as the condition holds true A repeat until executes the loop task
first, then tests a condition and repeats the task until the condition fails The tion (or select-case) construct shown in the figure is actually an extension of the
selec-First task Next task
Sequence
Selection
Condition T F
If-then-else
Repetition
Case condition
Case part T
Trang 9if-then-else A parameter is tested by successive decisions until a true condition occursand a case part processing path is executed.
The structured constructs may be nested within one another as shown in Figure16.2 Referring to the figure, repeat-until forms the then part of if-then-else (shownenclosed by the outer dashed boundary) Another if-then-else forms the else part ofthe larger condition Finally, the condition itself becomes a second block in a sequence
By nesting constructs in this manner, a complex logical schema may be developed Itshould be noted that any one of the blocks in Figure 16.2 could reference another mod-ule, thereby accomplishing procedural layering implied by program structure
In general, the dogmatic use of only the structured constructs can introduce ficiency when an escape from a set of nested loops or nested conditions is required.More important, additional complication of all logical tests along the path of escapecan cloud software control flow, increase the possibility of error, and have a nega-tive impact on readability and maintainability What can we do?
inef-The designer is left with two options: (1) inef-The procedural representation is redesigned
so that the "escape branch" is not required at a nested location in the flow of control
or (2) the structured constructs are violated in a controlled manner; that is, a strained branch out of the nested flow is designed Option 1 is obviously the idealapproach, but option 2 can be accommodated without violating of the spirit of struc-tured programming
con-Another graphical design tool, the box diagram, evolved from a desire to develop
a procedural design representation that would not allow violation of the structuredconstructs Developed by Nassi and Shneiderman [NAS73] and extended by Chapin
[CHA74], the diagrams (also called Nassi-Shneiderman charts, N-S charts, or Chapin charts) have the following characteristics: (1) functional domain (that is, the scope of
Next taskThen-partLoop task
Loopcondition
understand the design.
If using them without
longer are used as
widely as they once
were In general, use
Trang 10repetition or if-then-else) is well defined and clearly visible as a pictorial tion, (2) arbitrary transfer of control is impossible, (3) the scope of local and/or globaldata can be easily determined, (4) recursion is easy to represent.
representa-The graphical representation of structured constructs using the box diagram isillustrated in Figure 16.3 The fundamental element of the diagram is a box To rep-resent sequence, two boxes are connected bottom to top To represent if-then-else,
a condition box is followed by a then-part and else-part box Repetition is depictedwith a bounding pattern that encloses the process (do-while part or repeat-until part)
to be repeated Finally, selection is represented using the graphical form shown atthe bottom of the figure
Like flowcharts, a box diagram is layered on multiple pages as processing ments of a module are refined A "call" to a subordinate module can be representedwithin a box by specifying the module name enclosed by an oval
ele-16.1.2 Tabular Design Notation
In many software applications, a module may be required to evaluate a complex bination of conditions and select appropriate actions based on these conditions Deci-sion tables provide a notation that translates actions and conditions (described in aprocessing narrative) into a tabular form The table is difficult to misinterpret and may
Do-while-Loop condition
part
Repeat-until-Repetition Selection
Condition
part
Else-part
Then-Case conditionValue
Value
part
part
Case-If-then-else
Use a decision table
when a complex set of
conditions and actions
is encountered within
a component.
Trang 11even be used as a machine readable input to a table driven algorithm In a hensive treatment of this design tool, Ned Chapin states [HUR83]:
compre-Some old software tools and techniques mesh well with new tools and techniques of ware engineering Decision tables are an excellent example Decision tables preceded soft-ware engineering by nearly a decade, but fit so well with software engineering that theymight have been designed for that purpose
soft-Decision table organization is illustrated in Figure 16.4 Referring to the figure, thetable is divided into four sections The upper left-hand quadrant contains a list of allconditions The lower left-hand quadrant contains a list of all actions that are possi-ble based on combinations of conditions The right-hand quadrants form a matrixthat indicates condition combinations and the corresponding actions that will occurfor a specific combination Therefore, each column of the matrix may be interpreted
as a processing rule.
The following steps are applied to develop a decision table:
1 List all actions that can be associated with a specific procedure (or module).
2 List all conditions (or decisions made) during execution of the procedure.
3 Associate specific sets of conditions with specific actions, eliminating
impos-sible combinations of conditions; alternatively, develop every posimpos-sible mutation of conditions
per-4 Define rules by indicating what action(s) occurs for a set of conditions.
Conditions 1 2 3 4 n
Rules
Condition #1Condition #2Condition #3
Action #1Action #2Action #3Action #4Action #5
Trang 12To illustrate the use of a decision table, consider the following excerpt from a cessing narrative for a public utility billing system:
pro-If the customer account is billed using a fixed rate method, a minimum monthly charge isassessed for consumption of less than 100 KWH (kilowatt-hours) Otherwise, computerbilling applies a Schedule A rate structure However, if the account is billed using a vari-able rate method, a Schedule A rate structure will apply to consumption below 100 KWH,with additional consumption billed according to Schedule B
Figure 16.5 illustrates a decision table representation of the preceding narrative.Each of the five rules indicates one of five viable conditions (i.e., a T (true) in bothfixed rate and variable rate account makes no sense in the context of this procedure;therefore, this condition is omitted) As a general rule, the decision table can be effec-tively used to supplement other procedural design notation
16.1.3 Program Design Language
Program design language (PDL), also called structured English or pseudocode, is "a
pid-gin language in that it uses the vocabulary of one language (i.e., English) and theoverall syntax of another (i.e., a structured programming language)" [CAI75] In thischapter, PDL is used as a generic reference for a design language
At first glance PDL looks like a modern programming language The differencebetween PDL and a real programming language lies in the use of narrative text (e.g.,English) embedded directly within PDL statements Given the use of narrative textembedded directly into a syntactical structure, PDL cannot be compiled (at least notyet) However, PDL tools currently exist to translate PDL into a programming lan-
Fixed rate acct
Variable rate acct
Consumption <100 kwhConsumption ≥100 kwh
Min monthly chargeSchedule A billingSchedule B billingOther treatment
Actions
F I G U R E 16.5
Resultant
decision table
Trang 13guage “skeleton” and/or a graphical representation (e.g., a flowchart) of design Thesetools also produce nesting maps, a design operation index, cross-reference tables,and a variety of other information
A program design language may be a simple transposition of a language such asAda or C Alternatively, it may be a product purchased specifically for procedural design.Regardless of origin, a design language should have the following characteristics:
• A fixed syntax of keywords that provide for all structured constructs, datadeclaration, and modularity characteristics
• A free syntax of natural language that describes processing features
• Data declaration facilities that should include both simple (scalar, array) andcomplex (linked list or tree) data structures
• Subprogram definition and calling techniques that support various modes ofinterface description
A basic PDL syntax should include constructs for subprogram definition, interfacedescription, data declaration, techniques for block structuring, condition constructs,repetition constructs, and I/O constructs The format and semantics for some of thesePDL constructs are presented in the section that follows
It should be noted that PDL can be extended to include keywords for multitaskingand/or concurrent processing, interrupt handling, interprocess synchronization, andmany other features The application design for which PDL is to be used should dic-tate the final form for the design language
16.1.4 A PDL Example
To illustrate the use of PDL, we present an example of a procedural design for the
SafeHome security system software introduced in earlier chapters The system
mon-itors alarms for fire, smoke, burglar, water, and temperature (e.g., furnace breakswhile homeowner is away during winter) and produces an alarm bell and calls a mon-itoring service, generating a voice-synthesized message In the PDL that follows, weillustrate some of the important constructs noted in earlier sections
Recall that PDL is not a programming language The designer can adapt as requiredwithout worry of syntax errors However, the design for the monitoring softwarewould have to be reviewed (do you see any problems?) and further refined beforecode could be written The following PDL defines an elaboration of the procedural
design for the security monitor component.
PROCEDURE security.monitor;
INTERFACE RETURNS system.status;
TYPE signal IS STRUCTURE DEFINED name IS STRING LENGTH VAR;
address IS HEX device location;
It’s a good idea to use
your programming
language as the basis
for the PDL This will
Trang 14bound.value IS upper bound SCALAR;
message IS STRING LENGTH VAR;
END signal TYPE;
TYPE system.status IS BIT (4);
TYPE alarm.type DEFINED
smoke.alarm IS INSTANCE OF signal;
fire.alarm IS INSTANCE OF signal;
water.alarm IS INSTANCE OF signal;
temp.alarm IS INSTANCE OF signal;
burglar.alarm IS INSTANCE OF signal;
TYPE phone.number IS area code + 7-digit number;
WHEN cps = "test" SELECT
CALL alarm PROCEDURE WITH "on" for test.time in seconds;
WHEN cps = "alarm-off" SELECT
CALL alarm PROCEDURE WITH "off";
WHEN cps = "new.bound.temp" SELECT
CALL keypad.input PROCEDURE;
WHEN cps = "burglar.alarm.off" SELECT deactivate signal [burglar.alarm];
REPEAT UNTIL activate.switch is turned off
reset all signal.values and switches;
DO FOR alarm.type = smoke, fire, water, temp, burglar;
READ address [alarm.type] signal.value;
IF signal.value > bound [alarm.type]
THEN phone.message = message [alarm.type];
set alarm.bell to "on" for alarm.timeseconds;
PARBEGIN CALL alarm PROCEDURE WITH "on", alarm.time in seconds;
CALL phone PROCEDURE WITH message [alarm.type], phone.number;
ENDPARELSE skip
ENDIF
ENDFOR
ENDREP
END security.monitor
Note that the designer for the security.monitor component has used a new
con-struct PARBEGIN ENDPAR that specifies a parallel block All tasks specified withinthe PARBEGIN block are executed in parallel In this case, implementation details arenot considered
Trang 151 6 2 C O M PA R I S O N O F D E S I G N N O TAT I O N
In the preceding section, we presented a number of different techniques for senting a procedural design A comparison must be predicated on the premise thatany notation for component-level design, if used correctly, can be an invaluable aid
repre-in the design process; conversely, even the best notation, if poorly applied, adds tle to understanding With this thought in mind, we examine criteria that may beapplied to compare design notation
lit-Design notation should lead to a procedural representation that is easy to stand and review In addition, the notation should enhance "code to" ability so thatcode does, in fact, become a natural by-product of design Finally, the design repre-sentation must be easily maintainable so that design always represents the programcorrectly
under-The following attributes of design notation have been established in the context
of the general characteristics described previously:
Modularity Design notation should support the development of modular software
and provide a means for interface specification
Overall simplicity Design notation should be relatively simple to learn, relatively
easy to use, and generally easy to read
Ease of editing The procedural design may require modification as the software
process proceeds The ease with which a design representation can be edited canhelp facilitate each software engineering task
Machine readability Notation that can be input directly into a computer-based
development system offers significant benefits
Maintainability Software maintenance is the most costly phase of the software life
cycle Maintenance of the software configuration nearly always means maintenance
of the procedural design representation
Structure enforcement The benefits of a design approach that uses structured
pro-gramming concepts have already been discussed Design notation that enforces theuse of only the structured constructs promotes good design practice
Automatic processing A procedural design contains information that can be
processed to give the designer new or better insights into the correctness and ity of a design Such insight can be enhanced with reports provided via softwaredesign tools
qual-Data representation The ability to represent local and global data is an essential
element of component-level design Ideally, design notation should represent suchdata directly
Logic verification Automatic verification of design logic is a goal that is paramount
during software testing Notation that enhances the ability to verify logic greatlyimproves testing adequacy
Trang 16"Code-to" ability The software engineering task that follows component-level
design is code generation Notation that may be converted easily to source codereduces effort and error
A natural question that arises in any discussion of design notation is: "What tion is really the best, given the attributes noted above?" Any answer to this question
nota-is admittedly subjective and open to debate However, it appears that program designlanguage offers the best combination of characteristics PDL may be embedded directlyinto source listings, improving documentation and making design maintenance lessdifficult Editing can be accomplished with any text editor or word-processing sys-tem, automatic processors already exist, and the potential for "automatic code gen-eration" is good
However, it does not follow that other design notation is necessarily inferior toPDL or is "not good" in specific attributes The pictorial nature of flowcharts and boxdiagrams provide a perspective on control flow that many designers prefer The pre-cise tabular content of decision tables is an excellent tool for table-driven applica-tions And many other design representations (e.g., see [PET81], [SOM96]), notpresented in this book, offer their own unique benefits In the final analysis, the choice
of a design tool may be more closely related to human factors than to technicalattributes
The design process encompasses a sequence of activities that slowly reduces thelevel of abstraction with which software is represented Component-level designdepicts the software at a level of abstraction that is very close to code
At the component level, the software engineer must represent data structures,interfaces, and algorithms in sufficient detail to guide in the generation of program-ming language source code To accomplish this, the designer uses one of a number
of design notations that represent component-level detail in either graphical, lar, or text-based formats
tabu-Structured programming is a procedural design philosophy that constrains thenumber and type of logical constructs used to represent algorithmic detail The intent
of structured programming is to assist the designer in defining algorithms that areless complex and therefore easier to read, test, and maintain
R E F E R E N C E S
[BOH66] Bohm, C and G Jacopini, "Flow Diagrams, Turing Machines and Languages
with Only Two Formation Rules," CACM, vol 9, no 5, May 1966, pp 366–371 [CAI75] Caine, S and K Gordon, "PDL—A Tool for Software Design," in Proc National Computer Conference, AFIPS Press, 1975, pp 271–276
Trang 17[CHA74] Chapin, N., "A New Format for Flowcharts," Software—Practice and ence, vol 4, no 4 , 1974, pp 341–357
Experi-[DIJ65] Dijkstra, E., "Programming Considered as a Human Activity," in Proc 1965 IFIP Congress, North-Holland Publishing Co., 1965
[DIJ72] Dijkstra, E., “The Humble Programmer,” 1972 ACM Turing Award Lecture,
CACM, vol 15, no 10, October, 1972, pp 859–866.
[DIJ76] Dijkstra, E., "Structured Programming," in Software Engineering, Concepts and Techniques, (J Buxton et al., eds.), Van Nostrand-Reinhold, 1976
[HUR83] Hurley, R.B., Decision Tables in Software Engineering, Van
Nostrand-Reinhold, 1983
[LIN79] Linger, R.C., H.D Mills, and B.I Witt, Structured Programming,
Addison-Wesley, 1979
[NAS73] Nassi, I and B Shneiderman, "Flowchart Techniques for Structured
Pro-gramming," SIGPLAN Notices, ACM, August 1973
[PET81] Peters, L.J., Software Design: Methods and Techniques, Yourdon Press, 1981 [SOM96] Sommerville, I., Software Engineering, 5th ed., Addison-Wesley, 1996.
P R O B L E M S A N D P O I N T S T O P O N D E R
16.1 Select a small portion of an existing program (approximately 50–75 source
lines) Isolate the structured programming constructs by drawing boxes around them
in the source code Does the program excerpt have constructs that violate the tured programming philosophy? If so, redesign the code to make it conform to struc-tured programming constructs If not, what do you notice about the boxes that you’vedrawn?
struc-16.2 All modern programming languages implement the structured programming
constructs Provide examples from three programming languages
16.3 Why is “chunking” important during the component-level design review
process?
Problems 16.4–16.11 may be represented using any one (or more) of the proceduraldesign notations presented in this chapter Your instructor may assign specific designnotation to particular problems
16.4 Develop a procedural design for components that implement the following
sorts: Shell-Metzner sort; heapsort; BSST (tree) sort Refer to a book on data tures if you are unfamiliar with these sorts
struc-16.5 Develop a procedural design for an interactive user interface that queries for
basic income tax information Derive your own requirements and assume that all taxcomputations are performed by other modules
Trang 1816.6 Develop a procedural design for a program that accepts an arbitrarily long text
as input and produces a list of words and their frequency of occurrence as output
16.7 Develop a procedural design of a program that will numerically integrate a
function f in the bounds a to b
16.8 Develop a procedural design for a generalized Turing machine that will accept
a set of quadruples as program input and produce output as specified
16.9 Develop a procedural design for a program that will solve the Towers of Hanoi
problem Many books on artificial intelligence discuss this problem in some detail
16.10 Develop a procedural design for all or major portions of an LR parser for a
compiler Refer to one or more books on compiler design
16.11 Develop a procedural design for an encryption/decryption algorithm of your
choosing
16.12 Write a one- or two-page argument for the procedural design notation that
you feel is best Be certain that your argument addresses the criteria presented inSection 16.2
F U R T H E R R E A D I N G S A N D I N F O R M AT I O N S O U R C E S
The work of Linger, Mills, and Witt (Structured Programming—Theory and Practice,
Addison-Wesley, 1979) remains a definitive treatment of the subject The text contains
a good PDL as well as detailed discussions of the ramifications of structured gramming Other books that focus on procedural design issues include those by Robert-
pro-son (Simple Program Design, Boyd and Fraser Publishing, 1994), Bentley (Programming Pearls, Addison-Wesley, 1986 and More Programming Pearls, Addison-Wesley, 1988), and Dahl, Dijkstra, and Hoare (Structured Programming, Academic Press, 1972).
Relatively few recent books have been dedicated solely to component-level design
In general, programming language books address procedural design in some detailbut always in the context of the language that is introduced by the book The fol-lowing books are representative of hundreds of titles that consider procedural design
in a programming language context:
[ADA00] Adamson, T.A., K.C Mansfield, and J.L Antonakos, Structured Basic Applied to nology, Prentice-Hall, 2000.
Tech-[ANT96] Antonakos, J.L and K Mansfield, Application Programming in Structured C,
Trang 19[WEL95] Welburn, T and W Price, Structured COBOL: Fundamentals and Style, 4th ed., Mitchell
Publishers, 1995
A wide variety of information sources on software design and related subjects isavailable on the Internet An up-to-date list of World Wide Web references that arerelevant to design concepts and methods can be found at the SEPA Web site:
http://www.mhhe.com/engcs/compsci/pressman/resources/
comp-design.mhtml
Trang 20or imperfectly specified, as well as [in] later design and development stages Because of human inability to perform and communicate with perfection, softwaredevelopment is accompanied by a quality assurance activity
Software testing is a critical element of software quality assurance and resents the ultimate review of specification, design, and code generation.The increasing visibility of software as a system element and the attendant
rep-"costs" associated with a software failure are motivating forces for well-planned,thorough testing It is not unusual for a software development organization toexpend between 30 and 40 percent of total project effort on testing In theextreme, testing of human-rated software (e.g., flight control, nuclear reactormonitoring) can cost three to five times as much as all other software engi-neering steps combined!
What is it? Once source code hasbeen generated, software must
be tested to uncover (and correct)
as many errors as possible before delivery to your
customer Your goal is to design a series of test
cases that have a high likelihood of finding errors—
but how? That’s where software testing techniques
enter the picture These techniques provide
sys-tematic guidance for designing tests that (1)
exer-cise the internal logic of software components,
and (2) exercise the input and output domains of
the program to uncover errors in program
func-tion, behavior and performance
Who does it? During early stages of testing, a
soft-ware engineer performs all tests However, as the
testing process progresses, testing specialists maybecome involved
Why is it important? Reviews and other SQA ities can and do uncover errors, but they are notsufficient Every time the program is executed, thecustomer tests it! Therefore, you have to executethe program before it gets to the customer withthe specific intent of finding and removing allerrors In order to find the highest possible num-ber of errors, tests must be conducted systemati-cally and test cases must be designed usingdisciplined techniques
activ-What are the steps? Software is tested from two ferent perspectives: (1) internal program logic isexercised using “white box” test case design tech-
dif-Q U I C K
L O O K
Trang 21In this chapter, we discuss software testing fundamentals and techniques for ware test case design Software testing fundamentals define the overriding objec-tives for software testing Test case design focuses on a set of techniques for thecreation of test cases that meet overall testing objectives In Chapter 18, testing strate-gies and software debugging are presented.
Testing presents an interesting anomaly for the software engineer During earlier ware engineering activities, the engineer attempts to build software from an abstractconcept to a tangible product Now comes testing The engineer creates a series oftest cases that are intended to "demolish" the software that has been built In fact,testing is the one step in the software process that could be viewed (psychologically,
soft-at least) as destructive rsoft-ather than constructive
Software engineers are by their nature constructive people Testing requires thatthe developer discard preconceived notions of the "correctness" of software just devel-oped and overcome a conflict of interest that occurs when errors are uncovered.Beizer [BEI90] describes this situation effectively when he states:
There's a myth that if we were really good at programming, there would be no bugs to catch
If only we could really concentrate, if only everyone used structured programming, down design, decision tables, if programs were written in SQUISH, if we had the right sil-ver bullets, then there would be no bugs So goes the myth There are bugs, the myth says,because we are bad at what we do; and if we are bad at it, we should feel guilty about it.Therefore, testing and test case design is an admission of failure, which instills a goodlydose of guilt And the tedium of testing is just punishment for our errors Punishment forwhat? For being human? Guilt for what? For failing to achieve inhuman perfection? For notdistinguishing between what another programmer thinks and what he says? For failing to
top-be telepathic? For not solving human communications problems that have top-been kickedaround for forty centuries?
niques Software requirementsare exercised using “black box”
test case design techniques Inboth cases, the intent is to find the maximum num-
ber of errors with the minimum amount of effort
and time
What is the work product? A set of test cases
designed to exercise both internal logic and
exter-nal requirements is designed and documented,expected results are defined, and actual resultsare recorded
How do I ensure that I’ve done it right? When youbegin testing, change your point of view Try hard
to “break” the software! Design test cases in a ciplined fashion and review the test cases you docreate for thoroughness
Trang 22Should testing instill guilt? Is testing really destructive? The answer to these tions is "No!" However, the objectives of testing are somewhat different than we mightexpect.
3 A successful test is one that uncovers an as-yet-undiscovered error
These objectives imply a dramatic change in viewpoint They move counter to thecommonly held view that a successful test is one in which no errors are found Ourobjective is to design tests that systematically uncover different classes of errors and
to do so with a minimum amount of time and effort
If testing is conducted successfully (according to the objectives stated previously), itwill uncover errors in the software As a secondary benefit, testing demonstrates thatsoftware functions appear to be working according to specification, that behavioral andperformance requirements appear to have been met In addition, data collected as test-ing is conducted provide a good indication of software reliability and some indication
of software quality as a whole But testing cannot show the absence of errors anddefects, it can show only that software errors and defects are present It is important
to keep this (rather gloomy) statement in mind as testing is being conducted
17.1.2 Testing PrinciplesBefore applying methods to design effective test cases, a software engineer mustunderstand the basic principles that guide software testing Davis [DAV95] suggests
a set1of testing principles that have been adapted for use in this book:
• All tests should be traceable to customer requirements As we have
seen, the objective of software testing is to uncover errors It follows that themost severe defects (from the customer’s point of view) are those that causethe program to fail to meet its requirements
• Tests should be planned long before testing begins Test planning
(Chapter 18) can begin as soon as the requirements model is complete.Detailed definition of test cases can begin as soon as the design model has
1 Only a small subset of Davis’s testing principles are noted here For more information, see [DAV95].
“Errors are more
Trang 23been solidified Therefore, all tests can be planned and designed before anycode has been generated.
• The Pareto principle applies to software testing Stated simply, the
Pareto principle implies that 80 percent of all errors uncovered during testingwill likely be traceable to 20 percent of all program components The problem,
of course, is to isolate these suspect components and to thoroughly test them
• Testing should begin “in the small” and progress toward testing “in the large.” The first tests planned and executed generally focus on individual
components As testing progresses, focus shifts in an attempt to find errors inintegrated clusters of components and ultimately in the entire system (Chap-ter 18)
• Exhaustive testing is not possible The number of path permutations for
even a moderately sized program is exceptionally large (see Section 17.2 forfurther discussion) For this reason, it is impossible to execute every combi-nation of paths during testing It is possible, however, to adequately coverprogram logic and to ensure that all conditions in the component-leveldesign have been exercised
• To be most effective, testing should be conducted by an independent
third party By most effective, we mean testing that has the highest
probabil-ity of finding errors (the primary objective of testing) For reasons that havebeen introduced earlier in this chapter and are considered in more detail inChapter 18, the software engineer who created the system is not the bestperson to conduct all tests for the software
17.1.3 Testability
In ideal circumstances, a software engineer designs a computer program, a system,
or a product with “testability” in mind This enables the individuals charged with
test-ing to design effective test cases more easily But what is testability? James Bach2
describes testability in the following manner
Software testability is simply how easily [a computer program] can be tested Sincetesting is so profoundly difficult, it pays to know what can be done to streamline it Some-times programmers are willing to do things that will help the testing process and a check-list of possible design points, features, etc., can be useful in negotiating with them.There are certainly metrics that could be used to measure testability in most of itsaspects Sometimes, testability is used to mean how adequately a particular set of
2 The paragraphs that follow are copyright 1994 by James Bach and have been adapted from an Internet posting that first appeared in the newsgroup comp.software-eng This material is used with permission.
Trang 24tests will cover the product It's also used by the military to mean how easily a toolcan be checked and repaired in the field Those two meanings are not the same as
software testability The checklist that follows provides a set of characteristics that lead
to testable software
Operability "The better it works, the more efficiently it can be tested."
• The system has few bugs (bugs add analysis and reporting overhead to thetest process)
• No bugs block the execution of tests
• The product evolves in functional stages (allows simultaneous developmentand testing)
Observability "What you see is what you test."
• Distinct output is generated for each input
• System states and variables are visible or queriable during execution
• Past system states and variables are visible or queriable (e.g., transaction logs)
• All factors affecting the output are visible
• Incorrect output is easily identified
• Internal errors are automatically detected through self-testing mechanisms
• Internal errors are automatically reported
• Source code is accessible
Controllability "The better we can control the software, the more the testing can
be automated and optimized."
• All possible outputs can be generated through some combination of input
• All code is executable through some combination of input
• Software and hardware states and variables can be controlled directly by thetest engineer
• Input and output formats are consistent and structured
• Tests can be conveniently specified, automated, and reproduced
Decomposability "By controlling the scope of testing, we can more quickly
iso-late problems and perform smarter retesting."
• The software system is built from independent modules
• Software modules can be tested independently
Simplicity "The less there is to test, the more quickly we can test it."
• Functional simplicity (e.g., the feature set is the minimum necessary to meetrequirements)
Trang 25• Structural simplicity (e.g., architecture is modularized to limit the tion of faults).
propaga-• Code simplicity (e.g., a coding standard is adopted for ease of inspection andmaintenance)
Stability "The fewer the changes, the fewer the disruptions to testing."
• Changes to the software are infrequent
• Changes to the software are controlled
• Changes to the software do not invalidate existing tests
• The software recovers well from failures
Understandability "The more information we have, the smarter we will test."
• The design is well understood
• Dependencies between internal, external, and shared components are wellunderstood
• Changes to the design are communicated
• Technical documentation is instantly accessible
• Technical documentation is well organized
• Technical documentation is specific and detailed
• Technical documentation is accurate
The attributes suggested by Bach can be used by a software engineer to develop a ware configuration (i.e., programs, data, and documents) that is amenable to testing.And what about the tests themselves? Kaner, Falk, and Nguyen [KAN93] suggestthe following attributes of a “good” test:
soft-1 A good test has a high probability of finding an error To achieve this goal, the
tester must understand the software and attempt to develop a mental picture
of how the software might fail Ideally, the classes of failure are probed Forexample, one class of potential failure in a GUI (graphical user interface) is afailure to recognize proper mouse position A set of tests would be designed
to exercise the mouse in an attempt to demonstrate an error in mouse tion recognition
posi-2 A good test is not redundant Testing time and resources are limited There is
no point in conducting a test that has the same purpose as another test.Every test should have a different purpose (even if it is subtly different) For
example, a module of the SafeHome software (discussed in earlier chapters)
is designed to recognize a user password to activate and deactivate the tem In an effort to uncover an error in password input, the tester designs aseries of tests that input a sequence of passwords Valid and invalid pass-words (four numeral sequences) are input as separate tests However, each
sys-What are the
attributes of
a “good” test?
?
Trang 26valid/invalid password should probe a different mode of failure For example,the invalid password 1234 should not be accepted by a system programmed
to recognize 8080 as the valid password If it is accepted, an error is present.Another test input, say 1235, would have the same purpose as 1234 and istherefore redundant However, the invalid input 8081 or 8180 has a subtledifference, attempting to demonstrate that an error exists for passwords
“close to” but not identical with the valid password
3 A good test should be “best of breed” [KAN93] In a group of tests that have a
similar intent, time and resource limitations may mitigate toward the tion of only a subset of these tests In such cases, the test that has the highestlikelihood of uncovering a whole class of errors should be used
execu-4 A good test should be neither too simple nor too complex Although it is
sometimes possible to combine a series of tests into one test case, the ble side effects associated with this approach may mask errors In general,each test should be executed separately
The design of tests for software and other engineered products can be as ing as the initial design of the product itself Yet, for reasons that we have alreadydiscussed, software engineers often treat testing as an afterthought, developing testcases that may "feel right" but have little assurance of being complete Recalling theobjectives of testing, we must design tests that have the highest likelihood of findingthe most errors with a minimum amount of time and effort
challeng-A rich variety of test case design methods have evolved for software These ods provide the developer with a systematic approach to testing More important,methods provide a mechanism that can help to ensure the completeness of tests andprovide the highest likelihood for uncovering errors in software
meth-Any engineered product (and most other things) can be tested in one of two ways:(1) Knowing the specified function that a product has been designed to perform, testscan be conducted that demonstrate each function is fully operational while at thesame time searching for errors in each function; (2) knowing the internal workings
of a product, tests can be conducted to ensure that "all gears mesh," that is, internaloperations are performed according to specifications and all internal componentshave been adequately exercised The first test approach is called black-box testingand the second, white-box testing
When computer software is considered, black-box testing alludes to tests that are
conducted at the software interface Although they are designed to uncover errors,black-box tests are used to demonstrate that software functions are operational, thatinput is properly accepted and output is correctly produced, and that the integrity of
“There is only one
rule in designing test
cases: cover all
features, but do not
make too many test
Trang 27external information (e.g., a database) is maintained A black-box test examines somefundamental aspect of a system with little regard for the internal logical structure ofthe software.
White-box testing of software is predicated on close examination of procedural
detail Logical paths through the software are tested by providing test cases that cise specific sets of conditions and/or loops The "status of the program" may beexamined at various points to determine if the expected or asserted status corre-sponds to the actual status
exer-At first glance it would seem that very thorough white-box testing would lead to
"100 percent correct programs." All we need do is define all logical paths, developtest cases to exercise them, and evaluate results, that is, generate test cases to exer-cise program logic exhaustively Unfortunately, exhaustive testing presents certainlogistical problems For even small programs, the number of possible logical pathscan be very large For example, consider the 100 line program in the language C Aftersome basic data declaration, the program contains two nested loops that executefrom 1 to 20 times each, depending on conditions specified at input Inside the inte-rior loop, four if-then-else constructs are required There are approximately 1014pos-sible paths that may be executed in this program!
To put this number in perspective, we assume that a magic test processor ("magic"because no such processor exists) has been developed for exhaustive testing Theprocessor can develop a test case, execute it, and evaluate the results in one mil-lisecond Working 24 hours a day, 365 days a year, the processor would work for 3170years to test the program This would, undeniably, cause havoc in most developmentschedules Exhaustive testing is impossible for large software systems
White-box testing should not, however, be dismissed as impractical A limitednumber of important logical paths can be selected and exercised Important datastructures can be probed for validity The attributes of both black- and white-box test-ing can be combined to provide an approach that validates the software interfaceand selectively ensures that the internal workings of the software are correct
White-box testing, sometimes called glass-box testing, is a test case design method
that uses the control structure of the procedural design to derive test cases Usingwhite-box testing methods, the software engineer can derive test cases that (1) guar-antee that all independent paths within a module have been exercised at least once,(2) exercise all logical decisions on their true and false sides, (3) execute all loops attheir boundaries and within their operational bounds, and (4) exercise internal datastructures to ensure their validity
A reasonable question might be posed at this juncture: "Why spend time and energyworrying about (and testing) logical minutiae when we might better expend effort
It is not possible to
exhaustively test every
program path because
the number of paths is
simply too large
White-box tests can be
designed only after a
component-level design
(or source code)
exists The logical
details of the program
must be available
Trang 28ensuring that program requirements have been met?" Stated another way, why don't
we spend all of our energy on black-box tests? The answer lies in the nature of ware defects (e.g., [JON81]):
soft-• Logic errors and incorrect assumptions are inversely proportional to the bility that a program path will be executed Errors tend to creep into our work
proba-when we design and implement function, conditions, or control that are out
of the mainstream Everyday processing tends to be well understood (andwell scrutinized), while "special case" processing tends to fall into the cracks
• We often believe that a logical path is not likely to be executed when, in fact, it may be executed on a regular basis The logical flow of a program is some-
times counterintuitive, meaning that our unconscious assumptions aboutflow of control and data may lead us to make design errors that are uncov-ered only once path testing commences
• Typographical errors are random When a program is translated into
program-ming language source code, it is likely that some typing errors will occur.Many will be uncovered by syntax and type checking mechanisms, but othersmay go undetected until testing begins It is as likely that a typo will exist on
an obscure logical path as on a mainstream path
Each of these reasons provides an argument for conducting white-box tests box testing, no matter how thorough, may miss the kinds of errors noted here White-box testing is far more likely to uncover them
Basis path testing is a white-box testing technique first proposed by Tom McCabe
[MCC76] The basis path method enables the test case designer to derive a logical plexity measure of a procedural design and use this measure as a guide for defining abasis set of execution paths Test cases derived to exercise the basis set are guaran-teed to execute every statement in the program at least one time during testing
com-17.4.1 Flow Graph NotationBefore the basis path method can be introduced, a simple notation for the represen-
tation of control flow, called a flow graph (or program graph) must be introduced.3
The flow graph depicts logical control flow using the notation illustrated in Figure17.1 Each structured construct (Chapter 16) has a corresponding flow graph symbol
To illustrate the use of a flow graph, we consider the procedural design tation in Figure 17.2A Here, a flowchart is used to depict program control structure
represen-“Bugs lurk in corners
Trang 29Figure 17.2B maps the flowchart into a corresponding flow graph (assuming that nocompound conditions are contained in the decision diamonds of the flowchart) Refer-
ring to Figure 17.2B, each circle, called a flow graph node, represents one or more
procedural statements A sequence of process boxes and a decision diamond can
map into a single node The arrows on the flow graph, called edges or links,
repre-sent flow of control and are analogous to flowchart arrows An edge must terminate
at a node, even if the node does not represent any procedural statements (e.g., seethe symbol for the if-then-else construct) Areas bounded by edges and nodes are
called regions When counting regions, we include the area outside the graph as a
region.4
When compound conditions are encountered in a procedural design, the tion of a flow graph becomes slightly more complicated A compound condition occurswhen one or more Boolean operators (logical OR, AND, NAND, NOR) is present in aconditional statement Referring to Figure 17.3, the PDL segment translates into the
genera-flow graph shown Note that a separate node is created for each of the conditions a and b in the statement IF a OR b Each node that contains a condition is called a pred- icate node and is characterized by two or more edges emanating from it.
17.4.2 Cyclomatic Complexity
Cyclomatic complexity is a software metric that provides a quantitative measure of the
logical complexity of a program When used in the context of the basis path testingmethod, the value computed for cyclomatic complexity defines the number of inde-pendent paths in the basis set of a program and provides us with an upper bound forthe number of tests that must be conducted to ensure that all statements have beenexecuted at least once
An independent path is any path through the program that introduces at least one
new set of processing statements or a new condition When stated in terms of a flow
The structured constructs in flow graph form:
Where each circle represents one or morenonbranching PDL or source code statements
Until
CaseSequence
F I G U R E 17.1
Flow graph
notation
4 A more-detailed discussion of graphs and their use in testing is contained in Section 17.6.1.
Draw a flow graph
when the logical
control structure of a
module is complex.
The flow graph
enables you to trace
program paths more
readily.
Trang 3010
11
87
F I G U R E 17.2
Flowchart, (A)
and flow
graph (B)
Trang 31graph, an independent path must move along at least one edge that has not been versed before the path is defined For example, a set of independent paths for the flowgraph illustrated in Figure 17.2B is
tra-path 1: 1-11 path 2: 1-2-3-4-5-10-1-11 path 3: 1-2-3-6-8-9-10-1-11 path 4: 1-2-3-6-7-9-10-1-11 Note that each new path introduces a new edge The path 1-2-3-4-5-10-1-2-3-6-8-9-10-1-11
is not considered to be an independent path because it is simply a combination ofalready specified paths and does not traverse any new edges
Paths 1, 2, 3, and 4 constitute a basis set for the flow graph in Figure 17.2B That
is, if tests can be designed to force execution of these paths (a basis set), every ment in the program will have been guaranteed to be executed at least one time andevery condition will have been executed on its true and false sides It should be notedthat the basis set is not unique In fact, a number of different basis sets can be derivedfor a given procedural design
state-How do we know how many paths to look for? The computation of cyclomaticcomplexity provides the answer
Cyclomatic complexity has a foundation in graph theory and provides us with anextremely useful software metric Complexity is computed in one of three ways:
1 The number of regions of the flow graph correspond to the cyclomatic
com-plexity
2 Cyclomatic complexity, V(G), for a flow graph, G, is defined as
V(G) = E N + 2
Predicatenode
IF a OR bthen procedure xelse procedure yENDIF
Trang 32where E is the number of flow graph edges, N is the number of flow graph
nodes
3 Cyclomatic complexity, V(G), for a flow graph, G, is also defined as
V(G) = P + 1 where P is the number of predicate nodes contained in the flow graph G.
Referring once more to the flow graph in Figure 17.2B, the cyclomatic complexitycan be computed using each of the algorithms just noted:
1 The flow graph has four regions.
2 V(G) = 11 edges 9 nodes + 2 = 4
3 V(G) = 3 predicate nodes + 1 = 4.
Therefore, the cyclomatic complexity of the flow graph in Figure 17.2B is 4
More important, the value for V(G) provides us with an upper bound for the
num-ber of independent paths that form the basis set and, by implication, an upper bound
on the number of tests that must be designed and executed to guarantee coverage
of all program statements
17.4.3 Deriving Test CasesThe basis path testing method can be applied to a procedural design or to sourcecode In this section, we present basis path testing as a series of steps The proce-
dure average, depicted in PDL in Figure 17.4, will be used as an example to illustrate each step in the test case design method Note that average, although an extremely
simple algorithm, contains compound conditions and loops The following steps can
be applied to derive the basis set:
1 Using the design or code as a foundation, draw a corresponding flow graph A flow graph is created using the symbols and construction rules pre-
sented in Section 16.4.1 Referring to the PDL for average in Figure 17.4, aflow graph is created by numbering those PDL statements that will bemapped into corresponding flow graph nodes The corresponding flow graph
is in Figure 17.5
2 Determine the cyclomatic complexity of the resultant flow graph The
cyclomatic complexity, V(G), is determined by applying the algorithms described in Section 17.5.2 It should be noted that V(G) can be determined
without developing a flow graph by counting all conditional statements in the
PDL (for the procedure average, compound conditions count as two) and
adding 1 Referring to Figure 17.5,
V(G) = 6 regions V(G) = 17 edges 13 nodes + 2 = 6
V(G) = 5 predicate nodes + 1 = 6
Cyclomatic complexity
provides the upper
bound on the number
of test cases that must
be executed to
guarantee that every
statement in a
component has been
executed at least once
“To err is human, to
find a bug, devine.”
Robert Dunn
Trang 333 Determine a basis set of linearly independent paths The value of V(G)
provides the number of linearly independent paths through the program
con-trol structure In the case of procedure average, we expect to specify six
paths:
path 1: 1-2-10-11-13 path 2: 1-2-10-12-13 path 3: 1-2-3-10-11-13 path 4: 1-2-3-4-5-8-9-2- path 5: 1-2-3-4-5-6-8-9-2- path 6: 1-2-3-4-5-6-7-8-9-2- The ellipsis ( .) following paths 4, 5, and 6 indicates that any path through theremainder of the control structure is acceptable It is often worthwhile to iden-tify predicate nodes as an aid in the derivation of test cases In this case, nodes
2, 3, 5, 6, and 10 are predicate nodes
4 Prepare test cases that will force execution of each path in the basis set Data should be chosen so that conditions at the predicate nodes are
appropriately set as each path is tested Test cases that satisfy the basis setjust described are
PROCEDURE average;
INTERFACE RETURNS average, total.input, total.valid;
INTERFACE ACCEPTS value, minimum, maximum;
TYPE value[1:100] IS SCALAR ARRAY;
TYPE average, total.input, total.valid;
minimum, maximum, sum IS SCALAR;
TYPE i IS INTEGER;
* This procedure computes the average of 100 or fewer numbers that lie between bounding values; it also computes the sum and the total number valid.
increment total.input by 1;
IF value[i] > = minimum AND value[i] < = maximum
ENDIF increment i by 1;
THEN average = sum / total.valid;
ELSE average = –999;
THEN increment total.valid by 1;
sum = s sum + value[i]
ELSE skip
1
3 6 4
5 7 8 9
10 11
12 13
Trang 34Path 1 test case:
value(k) = valid input, where k < i for 2 ≤ i ≤ 100 value(i) = 999 where 2 ≤ i ≤ 100
Expected results: Correct average based on k values and proper totals.
Note: Path 1 cannot be tested stand-alone but must be tested as part of path 4, 5, and
6 tests
Path 2 test case:
value(1) = 999
Expected results: Average = 999; other totals at initial values.
Path 3 test case:
Attempt to process 101 or more values
First 100 values should be valid
Expected results: Same as test case 1.
Path 4 test case:
value(i) = valid input where i < 100 value(k) < minimum where k < i Expected results: Correct average based on k values and proper totals.
9
10
1112
Trang 35Path 5 test case:
value(i) = valid input where i < 100 value(k) > maximum where k <= i Expected results: Correct average based on n values and proper totals.
Path 6 test case:
value(i) = valid input where i < 100 Expected results: Correct average based on n values and proper totals.
Each test case is executed and compared to expected results Once all test cases havebeen completed, the tester can be sure that all statements in the program have beenexecuted at least once
It is important to note that some independent paths (e.g., path 1 in our example)cannot be tested in stand-alone fashion That is, the combination of data required totraverse the path cannot be achieved in the normal flow of the program In such cases,these paths are tested as part of another path test
17.4.4 Graph MatricesThe procedure for deriving the flow graph and even determining a set of basis paths
is amenable to mechanization To develop a software tool that assists in basis path
testing, a data structure, called a graph matrix, can be quite useful.
A graph matrix is a square matrix whose size (i.e., number of rows and columns)
is equal to the number of nodes on the flow graph Each row and column corresponds
to an identified node, and matrix entries correspond to connections (an edge) betweennodes A simple example of a flow graph and its corresponding graph matrix [BEI90]
To this point, the graph matrix is nothing more than a tabular representation of a
flow graph However, by adding a link weight to each matrix entry, the graph matrix
can become a powerful tool for evaluating program control structure during testing.The link weight provides additional information about control flow In its simplestform, the link weight is 1 (a connection exists) or 0 (a connection does not exist) Butlink weights can be assigned other, more interesting properties:
• The probability that a link (edge) will be executed
• The processing time expended during traversal of a link
• The memory required during traversal of a link
• The resources required during traversal of a link
Trang 36To illustrate, we use the simplest weighting to indicate connections (0 or 1) The graphmatrix in Figure 17.6 is redrawn as shown in Figure 17.7 Each letter has been replacedwith a 1, indicating that a connection exists (zeros have been excluded for clarity).
Represented in this form, the graph matrix is called a connection matrix.
Referring to Figure 17.7, each row with two or more entries represents a predicatenode Therefore, performing the arithmetic shown to the right of the connection matrixprovides us with still another method for determining cyclomatic complexity (Sec-tion 17.4.2)
Beizer [BEI90] provides a thorough treatment of additional mathematical rithms that can be applied to graph matrices Using these techniques, the analysisrequired to design test cases can be partially or fully automated
algo-1
3
4
25
a
b
c
de
fg
Flow graph
1
342
5
a
eg
Connected tonodeNode
5
1
11
Connected tonodeNode
F I G U R E 17.7
Connection
matrix
Trang 371 7 5 C O N T R O L S T R U C T U R E T E S T I N G
The basis path testing technique described in Section 17.4 is one of a number of niques for control structure testing Although basis path testing is simple and highlyeffective, it is not sufficient in itself In this section, other variations on control struc-ture testing are discussed These broaden testing coverage and improve quality ofwhite-box testing
tech-17.5.1 Condition Testing5
Condition testing is a test case design method that exercises the logical conditions
contained in a program module A simple condition is a Boolean variable or a tional expression, possibly preceded with one NOT (¬) operator A relational expres-sion takes the form
rela-E 1 <relational-operator> E 2 where E 1 and E 2are arithmetic expressions and <relational-operator> is one of thefollowing: <, ≤, =, ≠ (nonequality), >, or ≥ A compound condition is composed of two
or more simple conditions, Boolean operators, and parentheses We assume thatBoolean operators allowed in a compound condition include OR (|), AND (&) and NOT
(¬) A condition without relational expressions is referred to as a Boolean expression.
Therefore, the possible types of elements in a condition include a Boolean ator, a Boolean variable, a pair of Boolean parentheses (surrounding a simple or com-pound condition), a relational operator, or an arithmetic expression
oper-If a condition is incorrect, then at least one component of the condition is rect Therefore, types of errors in a condition include the following:
incor-• Boolean operator error (incorrect/missing/extra Boolean operators)
• Boolean variable error
• Boolean parenthesis error
• Relational operator error
• Arithmetic expression error
The condition testing method focuses on testing each condition in the program dition testing strategies (discussed later in this section) generally have two advan-tages First, measurement of test coverage of a condition is simple Second, the testcoverage of conditions in a program provides guidance for the generation of addi-tional tests for the program
Con-The purpose of condition testing is to detect not only errors in the conditions of a
program but also other errors in the program If a test set for a program P is effective
5 Section 17.5.1 and 17.5.2 have been adapted from [TAI89] with permission of Professor K C Tai.
Errors are much more
common in the
neighborhood of
logical conditions than
they are in the locus of
sequential processing
statements
Trang 38for detecting errors in the conditions contained in P, it is likely that this test set is also effective for detecting other errors in P In addition, if a testing strategy is effective for
detecting errors in a condition, then it is likely that this strategy will also be effectivefor detecting errors in a program
A number of condition testing strategies have been proposed Branch testing is probably the simplest condition testing strategy For a compound condition C, the true and false branches of C and every simple condition in C need to be executed at
least once [MYE79]
Domain testing [WHI80] requires three or four tests to be derived for a relational
expression For a relational expression of the form
E 1 <relational-operator> E 2 three tests are required to make the value of E 1greater than, equal to, or less
than that of E 2 [HOW82] If <relational-operator> is incorrect and E 1 and E 2arecorrect, then these three tests guarantee the detection of the relational operator
error To detect errors in E 1 and E 2 , a test that makes the value of E 1greater or
less than that of E 2should make the difference between these two values as small
as possible
For a Boolean expression with n variables, all of 2n possible tests are required (n > 0).
This strategy can detect Boolean operator, variable, and parenthesis errors, but it is
practical only if n is small.
Error-sensitive tests for Boolean expressions can also be derived [FOS84, TAI87].For a singular Boolean expression (a Boolean expression in which each Boolean
variable occurs only once) with n Boolean variables (n > 0), we can easily ate a test set with less than 2n tests such that this test set guarantees the detec-
gener-tion of multiple Boolean operator errors and is also effective for detecting othererrors
Tai [TAI89] suggests a condition testing strategy that builds on the techniques just
outlined Called BRO (branch and relational operator) testing, the technique
guaran-tees the detection of branch and relational operator errors in a condition providedthat all Boolean variables and relational operators in the condition occur only onceand have no common variables
The BRO strategy uses condition constraints for a condition C A condition straint for C with n simple conditions is defined as (D 1 , D 2 , , D n ), where D i (0 < i ≤ n)
is a symbol specifying a constraint on the outcome of the ith simple condition in dition C A condition constraint D for condition C is said to be covered by an execu- tion of C if, during this execution of C, the outcome of each simple condition in C satisfies the corresponding constraint in D.
con-For a Boolean variable, B, we specify a constraint on the outcome of B that states that B must be either true (t) or false (f) Similarly, for a relational expression, the sym-
bols >, =, < are used to specify constraints on the outcome of the expression
Even if you decide
against condition
testing, you should
spend time evaluating
Trang 39As an example, consider the condition
C 1 : B 1 & B 2 where B 1 and B 2 are Boolean variables The condition constraint for C 1is of the form
(D 1 , D 2 ), where each of D 1 and D 2is t or f The value (t, f) is a condition constraint
for C 1 and is covered by the test that makes the value of B 1to be true and the value
of B 2to be false The BRO testing strategy requires that the constraint set {(t, t), (f, t),
(t, f)} be covered by the executions of C 1 If C 1is incorrect due to one or more Boolean
operator errors, at least one of the constraint set will force C 1to fail
As a second example, a condition of the form
C 2 : B 1 & (E 3 = E 4)
where B 1 is a Boolean expression and E 3 and E 4are arithmetic expressions A
con-dition constraint for C 2 is of the form (D 1 , D 2 ), where each of D 1 is t or f and D 2is
>, =, < Since C 2 is the same as C 1 except that the second simple condition in C 2is a
relational expression, we can construct a constraint set for C 2by modifying the
con-straint set {(t, t), (f, t), (t, f)} defined for C 1 Note that t for (E 3 = E 4) implies = and that
f for (E 3 = E 4) implies either < or > By replacing (t, t) and (f, t) with (t, =) and (f, =),respectively, and by replacing (t, f) with (t, <) and (t, >), the resulting constraint set
for C 2is {(t, =), (f, =), (t, <), (t, >)} Coverage of the preceding constraint set will
guar-antee detection of Boolean and relational operator errors in C 2
As a third example, we consider a condition of the form
C 3 : (E 1 > E 2 ) & (E 3 = E 4)
where E 1 , E 2 , E 3, and E 4 are arithmetic expressions A condition constraint for C 3is
of the form (D 1 , D 2 ), where each of D 1 and D 2 is >, =, < Since C 3 is the same as C 2 except that the first simple condition in C 3is a relational expression, we can con-
struct a constraint set for C 3 by modifying the constraint set for C 2, obtaining{(>, =), (=, =), (<, =), (>, >), (>, <)}
Coverage of this constraint set will guarantee detection of relational operator errors
in C3.
17.5.2 Data Flow Testing
The data flow testing method selects test paths of a program according to the
loca-tions of definiloca-tions and uses of variables in the program A number of data flow ing strategies have been studied and compared (e.g., [FRA88], [NTA88], [FRA93])
test-To illustrate the data flow testing approach, assume that each statement in aprogram is assigned a unique statement number and that each function does not
modify its parameters or global variables For a statement with S as its statement
number,
Trang 40DEF(S) = {X | statement S contains a definition of X}
USE(S) = {X | statement S contains a use of X}
If statement S is an if or loop statement, its DEF set is empty and its USE set is based
on the condition of statement S The definition of variable X at statement S is said to
be live at statement S' if there exists a path from statement S to statement S' that tains no other definition of X.
con-A definition-use (DU) chain of variable X is of the form [X, S, S'], where S and S' are statement numbers, X is in DEF(S) and USE(S'), and the definition of X in statement
S is live at statement S'.
One simple data flow testing strategy is to require that every DU chain be covered
at least once We refer to this strategy as the DU testing strategy It has been shown
that DU testing does not guarantee the coverage of all branches of a program ever, a branch is not guaranteed to be covered by DU testing only in rare situations
How-such as if-then-else constructs in which the then part has no definition of any able and the else part does not exist In this situation, the else branch of the if state-
vari-ment is not necessarily covered by DU testing
Data flow testing strategies are useful for selecting test paths of a program
con-taining nested if and loop statements To illustrate this, consider the application of
DU testing to select test paths for the PDL that follows:
proc xB1;
do while C1
if C2then
if C4 then B4;
else B5;
endif;
else
if C3 then B2;
PDL Assume that variable X is defined in the last statement of blocks B1, B2, B3, B4,
and B5 and is used in the first statement of blocks B2, B3, B4, B5, and B6 The DU
testing strategy requires an execution of the shortest path from each of B i , 0 < i ≤ 5,
It is unrealistic to
assume that data flow
testing will be used
extensively when
testing a large system.
However, it can be
used in a targeted
fashion for areas of
the software that are
suspect.