What is white box testing?
White box testing traditionally refers to the use of program source code as a test basis, that is, as the basis for designing tests and test cases. (IEEE standards define a test as "a set of one or more test cases.") A looser definition says that "white box testing is based on internal structures of the software", but it is very unclear what kinds of "internal structure" are covered by this. Some authorities, for example, include user-facing menus and even business processes. The term "gray box testing" is now in widespread use for internal software structures that are not actually source code - for example, class hierarchies or module call trees. In the following discussion, "white box testing" is held to be synonymous with "code-based testing."
Those two terms are opposed to "requirements-based" or "specification-based" testing, also known as black box testing. The implication there is that you can't see the inner workings of a black-painted box; and in fact, you don't need to see the inner workings to test whether a given set of inputs results in the required or specified set of outputs. But if you do need to test the inner workings, painting the box white would leave them just as invisible as when the box was black, so the terms "clear box testing" and "glass box testing" are also used. (The word "analysis" is sometimes used in place of "testing.")
White-box testing usually involves tracing possible execution paths through the code and working out what input values would force the execution of those paths. Quite simple techniques exist by which the tester (usually the developer who wrote the code) can work out the smallest number of paths necessary to test, or "cover," all the code. Some types of static analysis tool will do the same job, more quickly and more reliably.
White box testing, on its own, cannot identify problems caused by mismatches between the actual requirements or specification and the code as implemented but it can help identify some types of design weaknesses in the code. Examples include control flow problems (e.g., closed or infinite loops or unreachable code), and data flow problems (e.g., trying to use a variable which has no defined value). Static code analysis (by a tool) may also find these sorts of problems, but doesn't help the tester/developer understand the code to the same degree that personally designing white-box test cases does.
White box testing is usually associated with component testing (i.e., unit testing), and with the concept that, at minimum, 100% of the component's code statements should be tested before the component is released for use ("100% code coverage"). But it may be dangerous to design white box test cases simply to achieve such a standard. This is not only because it will miss disconnects between code and specifications, but because the test cases are often artificial and unrepresentative of how the component will actually be used. The test cases may even be impossible to execute (corresponding to "unachievable" or "infeasible" paths. A tool will avoid generating these).
A better approach may be to design enough test cases to cover all requirements specified for the component (black box testing), then use a code coverage monitor to record how much of the code is actually covered (executed) when the test cases are run. Often, the code will fall into two parts: code statements that correspond directly to the requirements and get covered by the black box test cases; and code statements that deal with aspects of the target execution environment, which may not be explicitly specified but which the developer is expected to provide. This second type of code often provides error handling for exceptions thrown by hardware or software conditions (e.g., by a database management system), and often goes untested - which may cause severe problems when such an exception occurs in live use. The developer would use white box techniques to work out how to drive the testing of those statements not covered by the black box test cases.