TOPL (Testing Objects Pattern Language)
TOPL (Testing Objects Pattern Language)
Author: Donald Firesmith
Although there is always a considerable risk associated with making
predictions, I am convinced that object-oriented patterns will be
viewed as the most important concept in the object community during
the 1990s. For example, within a single year of its publication, the
book Design Patterns [Gamma et al., 1994] has been recognized as the
number one book in the list of top ten all-time classics in the object
technology field [Bilow, 1995]
According to the Dictionary of Object Technology [Firesmith and
Eykholt, 1995], a pattern is "any reusable architecture that
experience has shown to solve a common problem in a specific context."
A pattern language is a consistent collection of related patterns
gathered together to deal with a specific problem domain.
Several important object-oriented testing techniques have been
captured in the form of test patterns. These patterns have been
collected together to form PLOOT, the Pattern Language for
Object-Oriented Testing, which has been developed specifically to deal
with the following general issues that differentiate object-oriented
testing from traditional software testing:
- Unit testing is the testing of classes, typically indirectly by
means of their objects. This is because (1) classes are the basic
units of design, (2) classes are usually source code entities whereas
objects are run-time entities that may be executed, and (3) individual
operations within the class can not be tested in isolation because
they depend on the environment of the class (e.g., other operations,
properties, exceptions, assertions, etc.).
- Objects are essentially software blackboxes that hide their
encapsulated properties (e.g., attributes, links, component parts) and
hidden operations behind an interface of visible operations.
- Objects may exhibit externally-visible state behavior (e.g., a pop
message sent to an empty stack raises a stack empty exception rather
than returning the top entry).
- Objects collaborate via messages and exceptions, whereby messages
may be dynamically bound to polymorphic operations. A unit test case
is therefore typically a test message (with or without arguments) sent
to an object under test that is in a specific state rather than test
data sent to a function.
- Objects are defined by means of classes which are related via
inheritance relationships.
- Integration testing must take into account collaboration,
inheritance, aggregation, and attribution as well as patterns and
mechanisms.
- An iterative, incremental, parallel development cycle is often used
in which testing is performed incrementally, must be repeated often,
and is begun earlier in the project schedule.
This chapter has presented the initial version of PLOOT, a pattern
language for the testing of object-oriented software. Future versions
of PLOOT will add additional patterns, especially in the area of
integration testing, to the following current patterns:
- Built-in Test Operations. This is a pattern for automating the
complete whitebox unit self-testing of classes while bypassing
encapsulation.
- Mixin and Join Test Hierarchies. This is a pattern for automating
the complete whitebox unit testing of class using mixin and join
classes to bypass encapsulation.
- Friends Test Hierarchy. This is a pattern for automating the
complete whitebox unit testing of class using friends to bypass
encapsulation.
- Separate Test Driver Hierarchy. This is a pattern for automating
the complete blackbox unit testing of class.
- Paired Message Sequences. This is a pattern for performing
state-based blackbox unit testing of classes specified via axioms in
terms of pairs of message sequences that should transition equal
objects into equal objects.
- Transition Trees. This is a pattern for performing state-based
blackbox unit testing of classes in terms of transition trees base on
state transition diagrams.
- Operations that Delegate. This is a pattern for testing operations
that delegate responsibilities to other classes
- Dependency-Based Testing. This is a pattern that determines the
optimal test order for classes based on dependency relationships among
the objects.
- Assertions and Exceptions. This is a pattern that supports class
level debugging by embedding assertions and exceptions in the classes
under test
- Use Case Testing. This is a pattern for the acceptance testing of
reactive applications with user interfaces in terms of use cases.