Verification of software and firmware is extremely expensive and time consuming. Poor software verification techniques can delay the release of products and result in products that, once released, suffer from reliability and performance problems. Finding problems early is one of the benefits of a systematic verification process.
Systematic application of V\&V techniques throughout the design process are critical. Specifications must be checked for consistency and completeness, designs must be verified against specifications, implementations must be verified agains the designs and finally the implementation must be validated agains the specification. For software systems the implementations are code in a given language and verification and validation requires software testing. While all phases of verification are time consuming, software testing can be extremely time consuming and tedious for the test engineer. However, because software has a formal representation dictated by the syntax of the programming language used, many aspects of software verification can be automated with the use of software tools.
Testing can be classified into two broad categories: structural testing and functional testing. {\em Structural testing} takes into account the structure of the software in developing tests, while {\em functional testing} considers only the expected functionality of the software (the specification) and develops test cases accordingly. There are many distinctions between structural and functional testing. For example, functional testing is typically done by a testing team while structural testing is done by the software designers. Also, functional tests are created from the software specification while structural test are created directly form the code. As a result, functional tests are from the user's view of the software while structural tests are the designers view of the code. Therefore, functional testing is based on an independent view of the software while structural testing can suffer from the same misconceptions of the specification which resulted in the faults that are the target of the testing.
Functional testing is never ending because a piece of software has an infinite number of possible inputs. Structural testing, on the other hand, is based on the source code and the and paths through the software which (may be quite large but) are finite in number. Structural testing can also be extremely tedious and, therefore, prone to more ``human'' errors. In addition, functional tests will not change with modifications to the the software, for example if a section of code is re-written to improve performance. The structural tests, however would need to be completely rewritten. Hypothetically, if infinite testing were possible functional testing can find all bugs, but unit testing can not find all errors since errors in the control flow may imply paths are not covered or that the code does not meet the specification. Also, much of functional testing can be redundant since inputs to programs naturally fall into equivalence classes which are handled by given paths through the code. Therefore, a number of seemingly different inputs can result in testing of the same paths through the code. Structural testing, on the other hand, can eliminate useless test cases through explicit observation of the paths present. Finally, structural testing and functional testing can not be view in strict isolation. Most notably, layers of software blur the distinction between the testing techniques, functionality to one layer of the software is structure to higher layers. It is the goal of this research to use structural testing metrics as a measure of functional tests.