1
package com.clarkware.junitperf;
3
import junit.framework.Test;
4
import junit.framework.TestCase;
5
import junit.framework.TestResult;
6
import junit.framework.TestSuite;
9
* The <code>TestFactory</code> class creates thread-local
10
* <code>TestSuite</code> instances.
12
* This factory class should be used in cases when a stateful test
13
* is intended to be decorated by a <code>LoadTest</code>. A stateful
14
* test is defined as any test that defines test-specific state in
15
* its <code>setUp()</code> method.
18
* Use of the <code>TestFactory</code> ensures that each thread spawned
19
* by a <code>LoadTest</code> contains its own <code>TestSuite</code>
20
* instance containing all tests defined in the specified
21
* <code>TestCase</code> class.
24
* A typical usage scenario is as follows:
27
* Test factory = new TestFactory(YourTestCase.class);
28
* LoadTest test = new LoadTest(factory, numberOfUsers, ...);
34
* Of course, static variables cannot be protected externally, so tests
35
* intended to be run in a multi-threaded environment should ensure
36
* that the use of static variables is thread-safe.
39
* This class is dependent on Java 2. For earlier platforms a
40
* local cache implementation should be changed to use, for example,
41
* a HashMap to track thread-local information.
43
* @author <a href="mailto:mike@clarkware.com">Mike Clark</a>
44
* @author <a href="http://www.clarkware.com">Clarkware Consulting, Inc.</a>
47
* @see junit.framework.Test
48
* @see com.clarkware.junitperf.LoadTest
51
public class TestFactory implements Test {
53
protected final Class _testClass;
54
private TestSuite _suite;
55
private final TestCache _testCache;
58
* Constructs a <code>TestFactory</code> instance.
60
* @param testClass The <code>TestCase</code> class to load test.
62
public TestFactory(Class testClass) {
64
if (!(TestCase.class.isAssignableFrom(testClass))) {
65
throw new IllegalArgumentException("TestFactory must " +
66
"be constructed with a TestCase class.");
69
_testClass = testClass;
70
_testCache = new TestCache();
74
* Runs an instance of the <code>Test</code> class and
75
* collects its result in the specified <code>TestResult</code>.
77
* Each invocation of this method triggers the creation of a
78
* new <code>Test</code> class instance as specified in the
79
* construction of this <code>TestFactory</code>.
81
* @param result Test result.
83
public void run(TestResult result) {
84
getTest().run(result);
88
* Returns the number of tests in this test.
90
* @return Number of tests.
92
public int countTestCases() {
93
return getTestSuite().countTestCases();
97
* Returns the test description.
99
* @return Description.
101
public String toString() {
102
return "TestFactory: " + getTestSuite().toString();
105
protected Test getTest() {
106
return _testCache.getTest();
109
protected TestSuite getTestSuite() {
110
if (_suite == null) {
111
_suite = makeTestSuite();
117
protected TestSuite makeTestSuite() {
118
return new TestSuite(_testClass);
122
* The <code>TestCache</code> class provides thread-local
123
* instances of a <code>TestSuite</code> class containing
124
* tests defined in the <code>TestCase</code> class
125
* specified in the <code>TestFactory</code>.
127
private final class TestCache {
129
private final ThreadLocal _localCache = new ThreadLocal() {
131
protected Object initialValue() {
132
return makeTestSuite();
137
* Returns the <code>Test</code> instance local to the
140
* @return Thread-local <code>Test</code> instance.
143
return (Test)_localCache.get();