+ All Categories
Home > Documents > Testing During Implementation 1 *Testing During Implementation (Schach, Chap 15) Once Source Code...

Testing During Implementation 1 *Testing During Implementation (Schach, Chap 15) Once Source Code...

Date post: 15-Dec-2015
Category:
Upload: caitlin-richardson
View: 217 times
Download: 0 times
Share this document with a friend
31
Testing During Implementation 1 *Testing During Implementation *Testing During Implementation (Schach, Chap 15) (Schach, Chap 15) Once Source Code Available, can test code's Once Source Code Available, can test code's Execution Execution Worst way — Random Testing: Plug in Arbitrary Input and see what happens. Needed — a Systematic Way of Developing Test Cases Why make a big deal about testing? Why not just release software and fix it after delivery? F-16 autopilot inverted aircraft F-16 autopilot inverted aircraft when when crossing the equator (found crossing the equator (found in simulator) in simulator) (Neumann 86) (Neumann 86) ESA lost Ariane 5 rocket due to ESA lost Ariane 5 rocket due to numerical numerical precision in inertial reference system precision in inertial reference system (Gleick 96) (Gleick 96) 64 bit floating point num for horizontal velocity converted to a 16 bit signed int. Conversion over 32,767 failed 37 seconds after liftoff ($500 Million).
Transcript

T

est

ing

Du

rin

g Im

ple

men

tati

on

1

*Testing During Implementation*Testing During Implementation (Schach, Chap 15)(Schach, Chap 15)

Once Source Code Available, can test code's ExecutionOnce Source Code Available, can test code's Execution Worst way — Random Testing: Plug in Arbitrary Input and

see what happens. Needed — a Systematic Way of Developing Test Cases

Why make a big deal about testing? Why not just release software and fix it after delivery?

F-16 autopilot inverted aircraft when F-16 autopilot inverted aircraft when crossing the equator (found in crossing the equator (found in simulator) simulator) (Neumann 86)(Neumann 86)

ESA lost Ariane 5 rocket due to ESA lost Ariane 5 rocket due to numerical precision in inertial reference system numerical precision in inertial reference system (Gleick 96)(Gleick 96) 64 bit floating point num for horizontal velocity converted to a

16 bit signed int. Conversion over 32,767 failed 37 seconds after liftoff ($500 Million).

T

est

ing

Du

rin

g Im

ple

men

tati

on

2

Two Approaches to Test Case SelectionTwo Approaches to Test Case Selection

Testing To Testing To SpecificationsSpecifications (a.k.a (a.k.a Black-Box Testing Black-Box Testing aka aka functional testing) functional testing) Focus: what module is supposed to do, not how it does it.

Testing To Testing To CodeCode (aka (aka Glass-Box Testing, Glass-Box Testing, logic-driven, or path-oriented testing).logic-driven, or path-oriented testing). Focus: how code in module is structured,

not what its supposed to do

Only info used in design of test cases is the spec doc

The code itself is tested, w/o regard to specifications

Events: External Conditions that set the Context of the module

T

est

ing

Du

rin

g Im

ple

men

tati

on

3

Role of Black/Glass Box focus in Test Case DevRole of Black/Glass Box focus in Test Case Dev

Regardless as to whether black or glass box based, need Regardless as to whether black or glass box based, need the identify the following for each test case:the identify the following for each test case:

Once actual test Once actual test case data set case data set determined, determined, what next?what next?

What is being tested. Ex: myATM.deposit(); How test data id’d Ex: User Scenario: deposit $10 The actual input data. ???????? The expected output. ???????? The actual output. ????????

• Need to inspect what the software actually produces as output and compare with what was expected.

T

est

ing

Du

rin

g Im

ple

men

tati

on

4

*Feasibility of Testing to Specifications*Feasibility of Testing to Specifications

Combinatorial Explosion Makes Completely Testing to Combinatorial Explosion Makes Completely Testing to Specifications ImpossibleSpecifications Impossible Example: Specifications For Data Processing Product

Include 5 Types of Commission And 7 Types of Discount. How Many Total Test Cases are needed?

Doesn’t matter if Commission and Discount computed in two entirely separate modules—the structure is irrelevant

T

est

ing

Du

rin

g Im

ple

men

tati

on

5

*ICE*ICE: : Feasibility of Completely Testing to SpecificationsFeasibility of Completely Testing to Specifications

Suppose Specification Includes 20 Factors, Each of Suppose Specification Includes 20 Factors, Each of Which can Take On any of 4 ValuesWhich can Take On any of 4 Values Determine how many test cases would be needed to

completely test to specification.

T

est

ing

Du

rin

g Im

ple

men

tati

on

6

*What about the Feasibility of Testing to Code?*What about the Feasibility of Testing to Code?

If it is desired that If it is desired that eacheach Path through Module be executed at Path through Module be executed at least once, Combinatorial Explosion May Resultleast once, Combinatorial Explosion May Result

// kmax in an int between 1..18// kmax in an int between 1..18

// myChar is A, or B, or C// myChar is A, or B, or C

T

est

ing

Du

rin

g Im

ple

men

tati

on

7

*What Does Exercising Every Path Promise?*What Does Exercising Every Path Promise?

Is it Possible to exercise Is it Possible to exercise EveryEvery Path w/o detecting Path w/o detecting EveryEvery Fault? Fault? if ((x + y + z) / 3 == x)

println ("x, y, z are equal in value");

else

println ("x, y, z are not equal");

T

est

ing

Du

rin

g Im

ple

men

tati

on

8

*More on the Feasibility of Testing to Code*More on the Feasibility of Testing to Code A Path can be tested only if it is presentA Path can be tested only if it is present

Weaker Criteria exist besides Path coverage:Weaker Criteria exist besides Path coverage: Branch Coverage: Exercise all branches of all

conditional statements Statement Coverage: Execute every statement

How many paths through this code?

T

est

ing

Du

rin

g Im

ple

men

tati

on

9

*Equivalence Testing and Boundary Value Analysis*Equivalence Testing and Boundary Value Analysis

Equivalence testing, combined with boundary value Equivalence testing, combined with boundary value analysis, is a black-box technique of selecting test casesanalysis, is a black-box technique of selecting test cases Goal: New test cases chosen to detect previously

undetected faults. An equivalence class is a set of test cases such that any one

member of the class is representative of any other member of the class.

• Assumes that any one member of the equivalence class is as good a test case as any other member of the class.

• Is this a good assumption? How are test cases selected?

T

est

ing

Du

rin

g Im

ple

men

tati

on

10

*Equivalence Classes Example*Equivalence Classes Example

Suppose Specifications For DBMS State that product must Suppose Specifications For DBMS State that product must handle any number of Records between 1 and 16,383. handle any number of Records between 1 and 16,383. Example: if System can handle 34 Records and 14,870

Records, then probably will work fine for 8,252 Records Basic ideaBasic idea: If system works for a test case in range : If system works for a test case in range

(1..16,383), then will probably work for any other test (1..16,383), then will probably work for any other test case in range; don’t bother with nearly redundant testing.case in range; don’t bother with nearly redundant testing.

T

est

ing

Du

rin

g Im

ple

men

tati

on

11

*Boundary-Value Analysis Probability of detecting a fault increases when test case on/next Probability of detecting a fault increases when test case on/next

to boundary of an equivalence class is selected.to boundary of an equivalence class is selected. Thus, when testing the database product, the following cases

could be selected for the Range 1..16,383

Combining Equivalence Classes With Boundary Value Analysis Yields Combining Equivalence Classes With Boundary Value Analysis Yields a (relatively) small set of Test Data with the a (relatively) small set of Test Data with the potentialpotential of uncovering a of uncovering a large # of Faults.large # of Faults.

Test CaseTest Case # records# records Equivalence class? Boundary value? Equivalence class? Boundary value?

11 0 records 0 records

22 1 record 1 record

33 2 records 2 records

44 723 records 723 records

55 16,382 records 16,382 records

66 16,383 records 16,383 records

77 16,384 records 16,384 records

Equivalence class 1 (& adjacent to boundary value)Equivalence class 1 (& adjacent to boundary value)

Eq Class 2; Adjacent to boundary valueEq Class 2; Adjacent to boundary value

Eq Class 2; Boundary valueEq Class 2; Boundary value

T

est

ing

Du

rin

g Im

ple

men

tati

on

12

*Boundary Value Analysis of Output Specs*Boundary Value Analysis of Output Specs

ICE:ICE: In 2001, Minimum Social Security (OASDI) Deduction From In 2001, Minimum Social Security (OASDI) Deduction From any one Paycheck was $0.00, and the Maximum was $4,984.80any one Paycheck was $0.00, and the Maximum was $4,984.80 Using Boundary Value Analysis, what Input Data should be

used to Test the Software that Implements the above deduction?

T

est

ing

Du

rin

g Im

ple

men

tati

on

13

*Functional*Functional TestingTesting

An alternative (lower-level) form of black-box testing is to base An alternative (lower-level) form of black-box testing is to base the test data on the the test data on the functionalityfunctionality of the module.  of the module.  In functional testing, each function in module is identified;

test data are devised to test each function separately.  Functional testing can be difficult: Functional testing can be difficult:

The functions within a module may consist of lower-level functions, each of which must be tested first.

Lower-level functions may be not be independent. What problems arise when applying functional testing to OO?

T

est

ing

Du

rin

g Im

ple

men

tati

on

14

Shifting to Glass-Box TestingShifting to Glass-Box Testing

After black box testing: After black box testing: The requirements are shown to be fulfilled

for test cases considered. The interfaces are available and working.

So ... Why bother with glass-box testing? After all, the source code was tested by the black-box test cases.

T

est

ing

Du

rin

g Im

ple

men

tati

on

15

Glass-Box TestingGlass-Box Testing

Can be oriented towards Can be oriented towards Statement Coverage (Execute every

Statement at least once) Branch Coverage (Execute every Branch at least once) Path Coverage (Execute every Path at least once)

The code at hand is used to determine a test suite. The code at hand is used to determine a test suite. Ideally, you want Test Data that Exercises all Possible

Paths through your Code: • However, as previously discussed, likely is not possible

• Can Approximate by ensuring that each Path is Visited at least once, and considering equivalence classes.

T

est

ing

Du

rin

g Im

ple

men

tati

on

16

*Infeasible Code*Infeasible Code

It may not be possible to test It may not be possible to test a specific statementa specific statement May have an infeasible

path (“dead code”) in the module

Frequently this is evidence Frequently this is evidence of a faultof a fault

Many compilers can detect Many compilers can detect unreachable code as part of unreachable code as part of the parsing processthe parsing process

T

est

ing

Du

rin

g Im

ple

men

tati

on

17

Complexity Metrics: Making Testing ManageableComplexity Metrics: Making Testing Manageable

Goal Goal of Using a Software Complexity Metric: of Using a Software Complexity Metric: Highlight Modules Mostly Likely To Have Faults

Quality Assurance approach to Glass-Box Testing Quality Assurance approach to Glass-Box Testing Would be beneficial to be able to say, “Module M1 is

More “Complex” than Module M2” Problem: what do you do when you discover an Problem: what do you do when you discover an

unreasonably high Complexity Value for a Module?unreasonably high Complexity Value for a Module?

T

est

ing

Du

rin

g Im

ple

men

tati

on

18

Lines of Code as a Complexity MetricLines of Code as a Complexity Metric

Simplest Complexity Measure; Underlying Assumption: Simplest Complexity Measure; Underlying Assumption: There exists a Constant Probability p that Line of Code

Contains Fault. Based on the idea that the past can be used to predict the future.

Example:• Tester Believes Line of Code Has 2% Chance of

Containing Fault.• Module Under Test is 100 Lines Long, Probably Contains

2 Faults

T

est

ing

Du

rin

g Im

ple

men

tati

on

19

McCabe's Cyclomatic Complexity MetricMcCabe's Cyclomatic Complexity Metric

Cyclomatic Complexity Metric Cyclomatic Complexity Metric MM (McCabe, 76) (McCabe, 76) Essentially the Number of Decisions (branches) in Module

• M = #edges - #nodes +2 Can be used as a Metric for predicting the #

of Test Cases needed for Branch Coverage

M Value for Aegis System (Walsh,79)M Value for Aegis System (Walsh,79) 276 modules in Aegis 23% of modules with M > 10 contained 53% of detected faults Modules with M > 10 had 21% more faults per line of code

T

est

ing

Du

rin

g Im

ple

men

tati

on

20

ICE: Applying McCabe’s Metric ICE: Applying McCabe’s Metric

1.1. Use statement to graph conversionsUse statement to graph conversions2.2. Count num edges (#e), num nodes (#n)Count num edges (#e), num nodes (#n)3.3. Compute McCabe’s Metric M = #e-#n+2Compute McCabe’s Metric M = #e-#n+24.4. M > 10 is overly complex. Consider Re-M > 10 is overly complex. Consider Re-

designing Moduledesigning Module5.5. M value gives the recommended number of M value gives the recommended number of

test cases needed for branch coverage.test cases needed for branch coverage.

switch a {switch a { case 1: x =3;case 1: x =3;

break;break;case 2: if (b == 0) case 2: if (b == 0)

x=2;x=2; elseelse x=4;x=4; break;break;

case 3: while (c>0)case 3: while (c>0)

process(c);process(c); break;break;

}}

T

est

ing

Du

rin

g Im

ple

men

tati

on

21

Is Complete Black-Box/Glass-Box Testing Feasible?Is Complete Black-Box/Glass-Box Testing Feasible?

The The ArtArt of Testing (after reducing complexity of Testing (after reducing complexity via analysis of McCabe’s metric and others):via analysis of McCabe’s metric and others): Want: A Small, Manageable Set Of Test Cases:

• Maximize Chances of Detecting Fault, While

• Minimizing Chances of Wasting Test Case

What relative (Black/Glass Box) ordering of Test Cases What relative (Black/Glass Box) ordering of Test Cases will highlight as Many Faults As Possible?will highlight as Many Faults As Possible?

T

est

ing

Du

rin

g Im

ple

men

tati

on

22

Example: Testing a Tax Computation SystemExample: Testing a Tax Computation System

#include <iostream.h>  #include <iostream.h>  int main(void) { int main(void) {  int numDependents, exemption;  int numDependents, exemption;  float income, taxSubTotal, taxTotal;  float income, taxSubTotal, taxTotal;      coutcout<<"Enter yearly income: "; "Enter yearly income: ";  cin cin >> income; income;

// first if - check income ifif (income (income < 0) {    0) {   

cout cout << “Cannot have ” “Cannot have ” << “negative income.";  “negative income."; 

return 0; return 0;  }  }      coutcout<< “Give # dependents+self";  “Give # dependents+self";  cin cin >> numDependents; numDependents;

  // second if - check dependents     ifif (numDependents (numDependents <= 0) { 0) { coutcout<<“Need at least one “Need at least one

dependant";  dependant";      return 0;    return 0;

}}

  // third if (else-if) - compute tax subtotal

    ifif (income (income << 10000) 10000)    taxSubTotal = .02 * income;    taxSubTotal = .02 * income; //bracket 1//bracket 1

elseelse if if (income (income < < 50000) 50000) //bracket 2//bracket 2

taxSubTotal = 200taxSubTotal = 200+.03*(income-10000);.03*(income-10000);

else else //bracket 3//bracket 3      

taxSubTotal =1400taxSubTotal =1400+.04*(income-50000); .04*(income-50000);

    exemption exemption = numDependents * 50; numDependents * 50;

taxTotataxTotal = taxSubTotal - exemption; taxSubTotal - exemption;

  // last if - check negative tax

    ifif (taxTotal (taxTotal<0) 0) //In case of negative tax     taxTotal    taxTotal=0; 0;

cout cout << income income <<‘ ‘ ‘ ‘ <<taxSubTotal; taxSubTotal;

cout cout << numDependents numDependents << ‘ ‘; ‘ ‘;

cout cout << exemption exemption << ‘ ‘ ‘ ‘ <<taxTotal; taxTotal;

} }

T

est

ing

Du

rin

g Im

ple

men

tati

on

23

Test Case Development for Path CoverageTest Case Development for Path Coverage

1st if 2nd if If-else-if Last if Result

1 inc < 0 doesn't matter doesn't matter doesn't matternegative income error

2 inc >= 0 numDep <= 0 doesn't matter doesn't matterinvalid dependents error

3 inc >= 0 numDep > 0 income < 10000 taxTotal < 0.02 bracket 0 tax due tax

4 inc>= 0 numDep > 010000 <= income < 50000

taxTotal < 0.03 bracket 0 tax due tax

There are four if statements in the code (and no loops), resulting in how many paths through the code?   First Few Test Cases:

Group Exercise: Determine the Remaining 4 Test Cases

T

est

ing

Du

rin

g Im

ple

men

tati

on

24

Test Data SetsTest Data Sets

IncomeNum

DependentsExpected Result

1 -5 Don’t care negative income error

2 0 0 invalid dependents error

3 100 1 0 (bracket .02, negative tax)

4 20000 11 0 (bracket .03, negative tax)

To test the above, we need eight sets of data (values for income To test the above, we need eight sets of data (values for income and number of dependents), one to test each possible path. and number of dependents), one to test each possible path. Ranges for income are fairly evident for each case; we need only

select an appropriate number of dependents for each case. Below shows 4 test data sets corresponding to the first four test

cases described above, and the expected results (TaxTotal):

T

est

ing

Du

rin

g Im

ple

men

tati

on

25

*ICE: The remaining Equivalence Classes*ICE: The remaining Equivalence Classes

ifif (income (income < 0) {    0) {    cout cout << “Cannot have ” “Cannot have ”

<< “negative income.";  “negative income.";  return 0; return 0; 

}  }      coutcout<< “Give # dependents+self";  “Give # dependents+self";  cin cin >> numDependents; numDependents;

  // third if (else-if) - compute tax subtotal

    ifif (income (income << 10000) 10000)   taxSubTotal = .02 * income;   taxSubTotal = .02 * income;

elseelse if if (income (income < < 50000) 50000)   taxSubTotal = 200  taxSubTotal = 200+.03*(income-10000); .03*(income-10000); else else   taxSubTotal =1400  taxSubTotal =1400+.04*(income-50000); .04*(income-50000);

    exemption exemption = numDependents * 50; numDependents * 50;

taxTotataxTotal = taxSubTotal - exemption; taxSubTotal - exemption;

  // last if - check negative tax

    ifif (taxTotal (taxTotal<0) 0) //In case of negative tax     taxTotal    taxTotal=0; 0;

cout cout << income income <<‘ ‘ ‘ ‘ <<taxSubTotal; taxSubTotal;

cout cout << numDependents numDependents << ‘ ‘; ‘ ‘;

cout cout << exemption exemption << ‘ ‘ ‘ ‘ <<taxTotal; taxTotal;

} }

#include <iostream.h>  #include <iostream.h>  int main(void) { int main(void) {  int numDependents, exemption;  int numDependents, exemption;  float income, taxSubTotal, taxTotal;  float income, taxSubTotal, taxTotal;      coutcout<<"Enter yearly income: "; "Enter yearly income: ";  cin cin >> income; income;

// first if - check income

  // second if - check dependents     ifif (numDependents (numDependents <= 0) { 0) { coutcout<<“Need at least one “Need at least one

dependant";  dependant";      return 0;    return 0;

}}

T

est

ing

Du

rin

g Im

ple

men

tati

on

26

*ICE: Compute M value for Tax Software System*ICE: Compute M value for Tax Software System

#include <iostream.h>  #include <iostream.h>  int main(void) { int main(void) {  int numDependents, exemption;  int numDependents, exemption;  float income, taxSubTotal, taxTotal;  float income, taxSubTotal, taxTotal;      coutcout<<"Enter yearly income: "; "Enter yearly income: ";  cin cin >> income; income;

// first if - check income ifif (income (income < 0) {    0) {   

cout cout << “Cannot have ” “Cannot have ” << “negative income.";  “negative income."; 

return 0; return 0;  }  }      coutcout<< “Give # dependents+self";  “Give # dependents+self";  cin cin >> numDependents; numDependents;

  // second if - check dependents     ifif (numDependents (numDependents <= 0) { 0) { coutcout<<“Need at least one “Need at least one

dependant";  dependant";      return 0;    return 0;

}}

  // third if (else-if) - compute tax subtotal

    ifif (income (income << 10000) 10000)   taxSubTotal = .02 * income;   taxSubTotal = .02 * income;

elseelse if if (income (income < < 50000) 50000)   taxSubTotal = 200  taxSubTotal = 200+.03*(income-10000); .03*(income-10000); else else   taxSubTotal =1400  taxSubTotal =1400+.04*(income-50000); .04*(income-50000);

    exemption exemption = numDependents * 50; numDependents * 50;

taxTotataxTotal = taxSubTotal - exemption; taxSubTotal - exemption;

  // last if - check negative tax

    ifif (taxTotal (taxTotal<0) 0) //In case of negative tax     taxTotal    taxTotal=0; 0;

cout cout << income income <<‘ ‘ ‘ ‘ <<taxSubTotal; taxSubTotal;

cout cout << numDependents numDependents << ‘ ‘; ‘ ‘;

cout cout << exemption exemption << ‘ ‘ ‘ ‘ <<taxTotal; taxTotal;

} }

T

est

ing

Du

rin

g Im

ple

men

tati

on

27

*Fault Distribution In Modules Is Not Uniform*Fault Distribution In Modules Is Not Uniform

[Myers]: 47% of faults in OS/370 were in only 4% of the [Myers]: 47% of faults in OS/370 were in only 4% of the modulesmodules

[Endres]: DOS/VS (Release 28):[Endres]: DOS/VS (Release 28): 512 faults in a total of 202 modules

• 112 of the modules had only one fault• There were modules with 14, 15, 19 and 28 faults,

respectively – The latter three were the largest modules in the

product, with over 3000 lines of DOS macro assembler language

– The module with 14 faults was relatively small, and very unstable. What should be done with this module?

T

est

ing

Du

rin

g Im

ple

men

tati

on

28

* What does the detection of a fault tell us?* What does the detection of a fault tell us?

What does the detection of a fault within a module tell us What does the detection of a fault within a module tell us about the probability of the existence of additional faults in about the probability of the existence of additional faults in the same module?the same module?

[Myers]: When a module [Myers]: When a module has too many faults =>has too many faults => It is cheaper to redesign,

recode module than to try to fix its faults

Does finding a fault have any bearing on whether other faults are present?

T

est

ing

Du

rin

g Im

ple

men

tati

on

29

Comparison: Black-Box, Glass-Box, Code ReviewComparison: Black-Box, Glass-Box, Code Review

(Hwang, 1981): All three methods equally effective(Hwang, 1981): All three methods equally effective (Basili and Selby, 1987)(Basili and Selby, 1987) 32 professional programmers, 32 professional programmers,

42 advanced students 42 advanced students Professional programmers

• code reading detected more faults

• code reading had faster fault detection rate Advanced students

• code reading and black-box testing equally good

• both outperformed glass-box testing What Conclusions can be drawn from the above?What Conclusions can be drawn from the above?

T

est

ing

Du

rin

g Im

ple

men

tati

on

30

Information to Maintain on Formal Test Cases:Information to Maintain on Formal Test Cases:

What program unit was testedWhat program unit was tested How test set data was arrived at: equivalence classes, How test set data was arrived at: equivalence classes,

boundary values; boundary values; Type of coverage : branch coverage, etc. Type of coverage : branch coverage, etc.

Actual inputs (Include global variables, files, other state information when relevant)

Expected outputs Actual outputs

Value in running test set is in comparingValue in running test set is in comparing expected expected outputs outputs withwith actual outputs! actual outputs!

T

est

ing

Du

rin

g Im

ple

men

tati

on

31

*ICE: Test Case Development*ICE: Test Case Development

switch a {switch a {

case 1: x =3;case 1: x =3;

break;break;

case 2: if (b == 0) case 2: if (b == 0)

x=2;x=2;

elseelse

x=4;x=4;

break;break;

case 3: while (c>0)case 3: while (c>0)

process(c);process(c);

break;break;

}}

Give branch coverage test cases Give branch coverage test cases for the switch code (note: recall for the switch code (note: recall the previously computed M the previously computed M value) value)

Provide the following for each Provide the following for each test case:test case:

What is being testedWhat is being tested How test data was arrived atHow test data was arrived at Give the Give the

Actual input data set The expected output The actual output (simulate by

executing by hand here)


Recommended