Glass Box Testing

By Crista Risley

What is black box/glass box testing?[2] [4]

Black-box and glass-box are test design methods. Black-box test design treats the system as a "black-box", so it doesn't explicitly use knowledge of the internal structure. Black-box test design is usually described as focusing on testing functional requirements. Glass-box test design allows one to peek inside the "box", and it focuses specifically on using internal knowledge of the software to guide the selection of test data.

Glass box testing requires the intimate knowledge of program internals, while black box testing is based solely on the knowledge of the system requirements. Being primarily concerned with program internals, it is obvious in SE literature that the primary effort to develop a testing methodology has been devoted to glass box tests. However, since the importance of black box testing has gained general acknowledgement, also a certain number of useful black box testing techniques were developed.

It is important to understand that these methods are used during the test design phase, and their influence is hard to see in the tests once they're implemented.

Glass box testing definition [5]

Software testing approaches that examine the program structure and derive test data from the program logic. Structural testing is sometimes referred to as clear-box testing since white boxes are considered opaque and do not really permit visibility into the code.

Synonyms for Glass box testing

Types of Glass Box testing [6]

Tradeoffs of Glass box testing [3]

Advantages

Disadvantages


Combining glass-box and black-box[3]

Most common approach in practice

int abs(int x)

{

// effects: return -x if x, x otherwise if (x < -1) return -x;

else

return x;

}

black-box subdomains: x < 0, x >= 0

glass-box subdomains: x < -1, x >= -1

intersect the subdomains, giving: x < -1, x = -1, x >= 0

testing these subdomains reveals the error

intuition: good probability of error if either of the following occurs:

 

Glass-Box Testing [1]

In this testing technique, you use the code at hand to determine a test suite. Ideally, you want test data that exercises all possible paths through your code; however, this isn't always possible, and we can approximate by ensuring that each path is visited at least once.

As an example, consider the following program:

#include <iostream.h>

int main(void) {
int nDependents, Exemption;
float Income, TaxSubTotal, TaxTotal;

cout << "Welcome to the Elbonian tax calculator. Enter your yearly income: ";
cin >> Income;

// first if - check income

if (Income < 0) {
cout << "You cannot have a negative income.\n";
return 0;
}

cout << "Enter the number of dependents you have, including yourself: ";
cin >> nDependents;

// second if - check dependents

if (nDependents <= 0) {
cout <<"You must have at least one dependent.\n";
return 0;
}

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

if (Income < 10000)
TaxSubTotal = .02 * Income;
else if (Income < 50000)
TaxSubTotal = 200 + .03 * (Income - 10000);
else
TaxSubTotal = 1400 + .04 * (Income - 50000);

Exemption= nDependents * 50;
TaxTotal=TaxSubTotal - Exemption;

// last if - check negative tax

if (TaxTotal<0) //In case of negative tax
TaxTotal=0;

cout << "$S$S$S$S$S$S$S$S$S$S$S$S$S$S$S$S$S$ \n";
cout << "Elbonian Tax Collection Agency \n";
cout << "Tax Bill \n";
cout << " Citizen's Income: " << Income <<'\n';
cout << " Tax Subtotal: " << TaxSubTotal << '\n';
cout << "Number of Dependents: " << nDependents << '\n';
cout << " Tax Exepmtion: " << Exemption << '\n';
cout << " Final Tax Bill: " << TaxTotal << '\n';
cout << "$S$S$S$S$S$S$S$S$S$S$S$S$S$S$S$S$S$ \n";

}

There are four if statements in this code and no loops (these are the source of multiple paths in your code). They form a total of eight paths through the program (verify this!):

First if

Second if

If-else-if

Last if

Result

Income < 0

doesn't matter

doesn't matter

doesn't matter

negative income error

Income >= 0

NDependents <= 0

doesn't matter

doesn't matter

invalid dependents error

Income >= 0

NDependents > 0

Income < 10000

TaxTotal < 0

bracket 1 negative tax

Income >= 0

NDependents > 0

10000 <= Income < 50000

TaxTotal < 0

bracket 2 negative tax

Income >= 0

NDependents > 0

Income >= 50000

TaxTotal < 0

bracket 3 negative tax

Income >= 0

NDependents > 0

Income < 10000

TaxTotal >= 0

bracket 1

Income >= 0

NDependents > 0

10000 <= Income < 50000

TaxTotal >= 0

bracket 2

Income >= 0

NDependents > 0

Income >= 50000

TaxTotal >= 0

bracket 3

To test this, we must come up with eight sets of data (income 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. The following table shows one test suite, and the expected results (TaxTotal):

Income

NDependents

Expected Result

-5

Doesn't matter

negative income error

0

0

invalid dependents error

100

1

0 (bracket 1, negative tax)

20000

11

0 (bracket 2, negative tax)

50000

100

0 (bracket 3, negative tax)

9000

1

130 (bracket 1)

15000

1

300 (bracket 2)

100000

1

3350 (bracket 3)

To complete the glass-box testing process, you would test your program with all eight input sets, and verify that the output matches the expected result. If all outputs match, then the code passes the test.

References

[1] http://www.cis.ysu.edu/~kramer/DataStructures/Intro/GlassBox.html

[2] http://issco-www.unige.ch/ewg95/node80.html

[3] http://sdg.lcs.mit.edu/~dnj/6170/1999/lectures/lecture11/tsld018.htm

[4] http://www.cis.ohio-state.edu/text/faq/usenet/software-eng/testing- faq/faq-doc-13.html

[5] http://burks.bton.ac.uk/burks/foldoc/55/112.htm

[6] http://issco-www.unige.ch/ewg95/node81.html