Test patterns are design patterns for test software. Design patterns [GHJV94] capture and reuse design knowledge that has gained widespread application in the object-oriented software development community. Each pattern is a specific configuration of interactions among a set of objects that form some cluster in the overall design. The pattern description explains the context within which the pattern should be considered, provides a set of forces that guide a trade-off analysis, and explains how to construct the objects. We use the same format for the pattern description as the design community, but we can place more specific meaning on certain sections of the description. We have been successful with the concept of relating a test pattern to a particular design pattern. When a developer uses a specific design pattern to structure a portion of the system, a tester (who may be another developer) then knows which test pattern to use to structure the test code. The Grid component is based on the Listener design pattern, which is related to the more general Observer design pattern to incorporate event handling into its GUI. In the next section, we will explain the associated test pattern. Listener Test PatternIntentThere is a need to test the interactions among the Listener, ActionListener, and TargetObject objects that are participating in the Listener design pattern (Figure 6.21). The interactions need to be examined to ensure that:
Figure 6.21. Conceptual interactions in the Listener patternA Listener object is passed to an object that receives events. A Listener is only "interested" in a certain set of event objects. The ActionListener object forwards to a registered Listener only those events for which the Listener is registered. Each Listener is associated with some instance of TargetObject. When the Listener receives an event, it performs some action on its target object. That action was defined as a method in the class Listener. ContextThe Listener design pattern has been heavily used in Java, but equivalent event-handling patterns are used in all object-oriented languages. The pattern is particularly used in the context of the user interface. Most Java programs contain a large number of instances of the Listener pattern.Very little original code is written in a Listener class. Developers usually define the original code using the anonymous class mechanism. This makes it more difficult to test the mechanism in isolation. ForcesThere are several forces that constrain the design of the test classes:
SolutionA TestListener class creates an environment in which the interactions between objects in the Listener design pattern are exercised and observed. The TestListener object instantiates the pattern. A TestListener object can generate any of the events for which a Listener object can register. There is essentially one type of test case. An event is generated by the TestListener object and sent to the ActionListener object. If the ActionListener object is working correctly, the event is forwarded to all of the registered Listener objects. The Listeners invoke specific actions on their TargetObjects. The TestListener object registers with the ActionListener so that it receives the event at basically the same time as the Listener object being tested. The ListenerTest object then checks the TargetObject to determine whether the expected changes have occurred there. DesignAn instance of the TestListener class, after inheriting from the AbstractListener class, can register with the ActionListener object. It will then receive a notification of a specific event and will know to activate tests on the SpecializedListener object, Figure 6.22. Figure 6.22. Conceptual interactions in the Listener pattern extended for testing.Specific ExampleThe pattern can be applied to the Brickles TimerObserver class and those associated classes, Figure 6.23. Figure 6.23. An instantiation of the Listener pattern extended for testing timer observers in BricklesResulting ContextThe production classes participating in the Listener pattern have been tested relative to their interaction with each other. A series of test classes and test cases have been created that can be reused, with slight modifications, for a variety of types of events. By using the pattern approach, new events and new listeners can be tested cheaply. |