de.tivano.junit
Class ParametrizedTestSuite

java.lang.Object
  |
  +--junit.framework.TestSuite
        |
        +--de.tivano.junit.ParametrizedTestSuite
All Implemented Interfaces:
junit.framework.Test

public class ParametrizedTestSuite
extends junit.framework.TestSuite

A unit test suite that executes the same test case for a number of different sets of data.

Test data is defined as a standard Java Properties object, with a certain convention on the property keys used: Keys are expected to be of the form "<test name>.<attribute name>", where the test name part may be any string allowed as part of a property key, and the attribute name part must be a legal java identifier. The test name part is used to identify one of the test data definition in the property set (typically, a single property set contains many test data definitions), and the attribute name is used to identify a single attribute within a test data definition.

A test case is parametrized with a given test data definition by setting the accessible fields of this test case to the values specified by the corresponding property in the test data definition. A field in the test case is considered accessible if it either is a public field or if the test case class defines a public setter method matching the attribute name.

If both a public field and a setter method are present for a given attribute name, the setter method will be preferred. If more than one matching setter method is found, the test will fail with an appropriate error message.

Note that the fields that can be parametrized must have one of the types listed here:

The same restrictions hold for the the parameters of setter methods. In addition, a setter method may only have a single parameter to be used for test case parametrization.

Example: The property set

 Test1.count = 1
 Test1.isSpecial = false;
 Test1.url = http://www.tivano.de/

 Test2.count = 1
 Test2.isSpecial = false;
 Test2.url = file:///some/path

 My.Special.Test.count = 3
 My.Special.Test.isSpecial = true
 My.Special.Test.special = foo, bar, baz
 
defines three test data sets named "Test1", "Test2" and "My.Special.Test". Test1 and Test2 each define the attributes "count", "isSpecial" and "url", and My.Special.Test defines the attributes "count", "isSpecial" and "special".

Now, if the test class

 public class ExampleTest implements Test {
    public int count;
    public boolean isSpecial;
    private URL url;
    public void setIsSpecial(boolean value) { ... }
    public void setSpecial(String value) { ... }
    ....
 }
 
is parametrized by Test1, the variable count will be set to 1, the method setIsSpecial() will be called with the argument false and the variable url will be set to the equivalent of new URL("http://www.tivano.de/"). The method setSpecial() will not be called, as there is no attribute named "special" in Test1. When the example test is parametrized by My.Special.Test, however, setSpecial() will be called with the argument "foo, bar, baz", and the variable url will be left alone.

Parametrization occurs after the test case constructor has finished and before the test case is run. This means that you won't see the parametrized values in the constructor of your test cases, but they will be available in the run(...) and (for tests inheriting TestCase) setUp() methods.

If a test case cannot be parametrized e.g. because there is no corresponding public field or setter method for an attribute, the field or setter method violates the restrictions given above, or the field or setter method is not public, the test will fail with an appropriate error message.

Author:
Richard Kunze

Inner Class Summary
(package private)  class ParametrizedTestSuite.ParametrizedTestWrapper
          Helper class for parametrizing a single test case.
(package private) static class ParametrizedTestSuite.Warning
          Helper class for reporting warnings.
 
Constructor Summary
ParametrizedTestSuite(Class testClass)
          Construct a parametrized test suite for a given test class.
ParametrizedTestSuite(Properties testData)
          Construct an empty, parametrized test suite for the given test data set.
ParametrizedTestSuite(String name)
          Construct an empty, parametrized test suite named name.
ParametrizedTestSuite(String name, Properties testData)
          Construct an empty test suite named name for the test data set testData.
 
Method Summary
 void addTest(junit.framework.Test test)
          Adds a test to the suite.
 void addTestSuite(Class testClass)
          Add the parametrized test suite for testClass to this suite.
static junit.framework.Test warning(String message)
          Returns a test that will fail with a warning message.
 
Methods inherited from class junit.framework.TestSuite
countTestCases, createTest, getName, getTestConstructor, run, runTest, setName, testAt, testCount, tests, toString
 
Methods inherited from class java.lang.Object
, clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

ParametrizedTestSuite

public ParametrizedTestSuite(Properties testData)
Construct an empty, parametrized test suite for the given test data set. All tests that are subsequently added to this suite using the addTest(junit.framework.Test) or addTestSuite(java.lang.Class) methods will be parametrized according to testData.
Parameters:
testData - the property set defining the test data.

ParametrizedTestSuite

public ParametrizedTestSuite(String name,
                             Properties testData)
Construct an empty test suite named name for the test data set testData. All tests that are subsequently added to this suite using the addTest(junit.framework.Test) or addTestSuite(java.lang.Class) methods will be parametrized according to testData.
Parameters:
the - name for this test suite.
testData - the property set defining the test data.

ParametrizedTestSuite

public ParametrizedTestSuite(String name)
Construct an empty, parametrized test suite named name.

The test data for this test suite is expected to reside in a resource named "name.properties". If no such resource exists, the resource cannot be parsed into a properties object, or the corresponding properties object is empty, a warning with an appropriate error message is added to this test suite.

Parameters:
name - the name for this test suite

ParametrizedTestSuite

public ParametrizedTestSuite(Class testClass)
Construct a parametrized test suite for a given test class.

The test data for this suite is expected to reside in a resource with a name matching that of the test class (in detail: The resource name is constructed by replacing all occurrences of "." in the class name by "/" and appending the suffix ".properties"), and it will contain tests for all test methods defined by testClass and all test data sets specified in the associated test data resource.

Using this constructor is the exact equivalent of the code sequence

 String name = "/" + testClass.getName().replace(".", "/") + ".properties"
 TestSuite suite = new ParametrizedTestSuite(name);
 suite.addTestSuite(testClass);
 

See the documentation for addTestSuite(java.lang.Class) for an exact definition of the tests that are constructed by using this constructor.

If the resource defining the test data set for the test class cannot be found, cannot be parsed as a property set or if the resulting property set is empty, a warning will be added to this suite instead of the actual test. Likewise, a warning will be added if one of the resulting tests cannot be parametrized (e.g because of a mismatch of the test data and the fields respectively setter methods defined by the test class).

Parameters:
testClass - the test class.
Method Detail

warning

public static junit.framework.Test warning(String message)
Returns a test that will fail with a warning message. This method must be redefined here for two reasons: First, it is private in TestSuite and so not accessible here. Second, the implementation in TestSuite uses an anonymous class for the warning, which makes it impossible for addTest(junit.framework.Test) to distinguish between warnings that should not be wrapped in a ParametrizedTestSuite.ParametrizedTestWrapper (because doing so will almost certainly cause the wrapper to fail with a number of spurious errors when it tries to parametrize the warning) and real tests, which have to be wrapped.

Note: As of JUnit-3.8.2, warning is now public and it is a static method. Changed from protected to public and from instance to static to account for this. Still overriding for many of the same reasons stated above.

Parameters:
message - the warning message

addTestSuite

public void addTestSuite(Class testClass)
Add the parametrized test suite for testClass to this suite.

For every different test data set found in the associated property set, a test suite will be created and added to this suite that contains tests for all test...() method found in the test class. Every one of these tests is parametrized by the corresponding test data set.

Example: If the class

 public class ExampleTest extends TestCase {
    private String value;
    public void setValue(String str) { ... }
    public void testFoo() { ... }
    public void testBar() { ... }
 }
 
is passed as parameter testClass to this method, and the property set associated with this test suite has the content
 Test1.value = fnord
 Test2.value = snafu
 
then this method will create two test suites named "Test1" and "Test2" and add them to this suite. Each of the created test suites contains two instances of ExampleTest: One that runs the testFoo() test method, and one that runs testBar(). The tests in the "Test1" suite will have the value attribute set to "fnord", the tests in the "Test2" suite to "snafu".

Overrides:
addTestSuite in class junit.framework.TestSuite
Parameters:
testClass - the test class

addTest

public void addTest(junit.framework.Test test)
Adds a test to the suite.

If a test data set with a key of this.getName() exists in the test data associated with this test suite, the test will be parametrized with the test data in this data set.

Note that if test is an instance of TestSuite, then it will not parametrized.

Overrides:
addTest in class junit.framework.TestSuite
Parameters:
test - the test to be added to this suite.


Copyright © 2002 Tivano Software GmbH. All Rights reserved.