Say you have defined some abstract interface and you specify a general contract for that interface to which all implementations must adhere. Are there common techniques that can facilitate testing the conformance of arbitrary implementations to that general contract?
In my environment we have a large collection of such abstract interfaces that define a common interface to several different hardware systems. My current approach is to define a set of conformance tests that work solely with the abstract interfaces. These tests are then packed into a library which again is imported by the actual unit tests of the implementations. These instantiate the tests and also provide a factory which generates concrete testee instances that will be tested by the conformance tests.
In theory this approach sounds fine, but in practice writing the conformance tests is very difficult and the value of their results appears to be very limited, because a lot of additional information about the testee instances is required.
Example (pseudo code):
the abstract interface is
myinterface
{
// Triggers some behaviour and returns immediately. While the behaviour is active,
// getState() returns *Running*. If an error occurrs the state changes to *Halted*.
function run();
function getState : State;
};
This interface and its contract are very simple, yet the test case for this is (relatively) difficult to write and its result says little about whether or not the implementation is doing the right thing or not. Is my approach reasonable or would I be better off just writing separate unit tests for all implementations? Are there other techniques that could help to achieve what I want (i.e.: guarantee the conformance of different implementations to the contract of their general interface).