What is a test? - a test is atomic : a test is an individual unit. you cannot run part of a test. a test is responsible for knowing how to get from a blank starting state to an ending state and any cleanup necessary. +-----+ +---+ |start|-test->|end| +-----+ +---+ - a test may consist of any number of steps : each step is a transition from one state to the next state:: +-----+ +-------+ +-------+ +---+ |start|-step1->|state A|-step2->|state B|-step3->|end| +-----+ +-------+ +-------+ +---+ - since state B comes after state A, it is assumed to dependent on state A. therefore, if any step in a test fails, it may be assumed that that the test fails and no further steps should be run. whatever cleanup steps should be run upon failure or passing - since cleanup may be called at any time, it should not depend on any particular state being established. cleanup should check for state as necessary. - given the last step completed (and, conceivably, introspecting state), a test knows which test to run next. this is vital as the application under testing may be reset between tests. - steps may be other tests: since a test is an ordered set of transitions traversed through to a final state, it may be seen as a black box providing this final state given an initial state. this way, tests may be composed of other tests when applicable. in this case, the teardown (i.e. cleanup) is performed only after the top-level atom (i.e. test) is finished, either through success or failure, since the cleanup may reset (or partially reset) the state. - unrelated groupings of transitions should not be treated as tests : as stated, a test is a set of steps that when called transition from an initial state to a final state. while they may contain common setup and/or teardown code, it is meaningless to have them associated if there is no clear workflow. instead, an inheritence pattern should be used. - tests should be able to import and use modules and functions. not all logic has to go in the tests. utility functions can be tests, if applicable, which can be used to compose other tests, but they may also be free-standing functions. test steps/functions should not be confused with utility functions.