CSCE 315 Lecture 19

From Notes
Jump to navigation Jump to search

« previous | Monday, March 5, 2012 | next »


Testing

Helps find errors that exist.

A systematic attempt to break a working program, unlike other parts of software development, whose goal is to avoid errors.

FYI, we can never prove the absence of errors.

Unit Testing
Testing af a single class, routine, or program; usually done by a single programmer
Isolated from the rest of the system
Component Testing
Test small packages
Integration Testing
Test the whole application
Regression Testing
Re-test to make sure that new errors have not been implemented.
System testing
Testing the entire software in final configuration with the hardware
finds security, performance, resource, and timing problems

Testing First

  • Identify errors more quickly
  • Doesn't take more effort later
  • think about requirements and design before writing code

Testing during development

Boundary Testing
Make sure that code handles boundary conditions (sorting an empty array or an array with 1 element).
Check loop and conditional bounds
Preconditions and Postconditions
Verify that the procedure starts with the correct preconditions and produces correct postconditions.
Assertions
assert.h (C/C++); Assert, AssertionError (Java)
checking for pre-/postconditions
Helps identify where problem occurs
usually placed in calling routine
Defensive Programming
Protecting the program from bad data
Check for "not going to happen" cases
Error Returns
Good API and routine design include error codes that need to be checked
Exception handling (try-catch)

Systematic Testing

Incremental Testing
Test along the way; don't wait until everything is finished.
Simple parts first
Find the "easy" bugs
Know expected output
Design a test case that you will know the answer to.
Make hand-checks convenient
Not always easy to do
Verify conservation properties
StartCount + NumInserted − NumDeleted = FinalCount
Compare independent implementations
Multiple implementations to compute the same data should agree
Useful for testing tricky code to increase performance (compare to slow, brute-force method)
Measure Test Coverage
What portion of code is actually tested? Aim for 100%
Logic Coverage: test every execution path through the code.
Structured Basis: test every line (no need for every combination of paths)
Data flow Testing
Examine data rather than control
3 states: Defined (init, but not used), Entered (data input), Killed (information is deleted)
Compilers test Defined-Defined, Defined-Killed, etc. conditions
Write tests for Defined-Used cases.