Pattern: Abstract Test
Intent
To create a set of tests which can be used against different implementation of the same contract
Also Known As
Abstract Test Case, Contract Test
Motivation
Every time there's an interface in the program and several different implementation of it a strong need to test both of implementation by the same set of tests in addition to their own specific tests. These reusable tests are usually a kind of [[Functional Test|functional tests]]. The implementation of Abstract Test pattern usually involves using the Factory Method pattern to create a base abstract class with all tests defined and to instantiate the concrete interface implementations in abstract test descendants. The concrete test might also include additional specific to this very implementation tests.
Applicability
Use Abstract Test when:
- multiple implementations of the same interface must be tested with the same set of tests.
Example
public interface AccountManager {
public Account createAccount(String accountName);
}
public abstract class AccountManagerAbstractTest extends TestCase {
private AccountManager accountManager;
abstract AccountManager createAccountManager();
protected void setUp() throws Exception {
super.setUp();
accountManager = createAccountManager();
}
public void testAccountCreation() throws Exception {
Account account = accountManager.createAccount("test account");
assertNotNull("null account created", account);
assertEquals("wrong name in created account", account.getName());
}
}
public class DatabaseAccountManagerTest extends AccountManagerAbstractTest {
AccountManager createAccountManager() {
return new DatabaseAccountManager();
}
}
In case of using JUnit ant runner all abstract tests should be excluded from execution. This is usually achieved by using a special naming scheme for abstract tests.
Related Patterns
- Functional Testing - abstract tests are usually a functional ones, since they perform a black-box interface testing.