CS 343 - Concurrent and Parallel Programming

Testing and Documentation Examples

Summary

A test document demonstrates aspects of a program’s correctness to the marker. When an assignment question requires test documentation, you must:

In the time allotted for an assignment, you cannot test your program completely. So the goal is to show you thought about a few important aspects of the program and then demonstrated their correctness.

Note, writing a script that tests your program on all possible inputs is not considered test documentation (and is impossible in most cases). Test documentation is supposed to make you think critically about your code and possibly even find mistakes that can be fixed.

Ground rules

Two expected layers of testing

Layer 1: User Interface test

In this course, the user interface is the program’s command-line interface (CLI) and input/output data. For example, the program tests the command-line arguments for correctness:

  $ ./pizzamachine asdf
  Usage: ./pizzamachine [ npies (>= 0) | d [ maxtops (> 0) | d [ seed (> 0) | d [infile] ] ]
  $ ./pizzamachine 100 5 d doesnt-exist.txt
  error: could not read from doesnt-exist.txt
  $ ./pizzamachine 100 5 d < one-pie.txt
  pep gp mshr olv chv: made in 3 minutes
  error: input ended before 100 pies read

A general CLI is provided that can be specialized for each assignment. User Interface testing does not change significantly from one assignment to the next, so much of your test design can be reused/improved.

Without good User Interface quality, you risk that when we test your program, we won't be able to drive the parts that matter.

Since you are given a general CLI outline, only 1 test case should be used involving a several small program runs, as above. For example:

Layer 2: Algorithm tests

These tests handle assignment-specific definitions of correctness and are the other 4-5 test cases.

Test Documentation Examples

Download a zip file with all of the sample documentation listed below.

  1. Hello World (SwapCase)
    • Good, starter example of writing output analysis.
    • Nothing to note about document structure or conventions because the case is so small.
    • Program (swapcase.cc)
    • Test documentation (test.txt)
  2. Full Sequential (FlexVec)
  3. Accessible Concurrent (Telephone)

Appendix: Tips for going deeper

You would spend too long on testing if you followed an exhaustive interpretation of this section. Consult this section if you are feeling stuck about how to find good cases.

Consider Data vs Control Flow

Incorrect data occurs when the program’s memory has wrong values.

Incorrect control flow occurs when the program transfers to the wrong location.

Try to apply these perspectives together. Identify cases where different call-stack paths interact with a common datum. Maybe “most” of a collection gets consumed one way, during the core of a run, and leftover items need to be dismissed during shutdown. Then the zero-one-more heuristic applies to both sides of the split.

Consider Black- vs. White-box cases

Black-box coverage is an argument that analyzes a specification; white-box analyzes an implementation. Black-box coverage does not reveal many problems introduced by implementation complexity and white-box coverage does not reveal many unimplemented requirements.

Find the concurrent cases that aren't user-driven

Here is a suggestion for handling the apparent nondeterminism of concurrent programs, without having to force behaviours by changing your code. It is not applicable in A1--A2.

We call a concurrent program nondeterministic, as a useful simplification of the fact that it takes inputs from the scheduler, whose consequences are impractical to predict. Some testing tools try to put the tester in control of those inputs; note that this starting point can still leave the "impractical to predict" part unsolved. You should not try to take control of those inputs here. Instead, take a guess-and-check approach, combined with output anlysis.