I'm trying to write some code which recursively adds TestSuites in a project to a suite of suites located at the root of the package hierarcy.
I've already written the code which returns a Collection object which contains a File object for each Test Suite found in my project.
I'm now trying to loop through them and add them to a TestSuite in a file called AllTests.java:
public static Test suite() throws IOException, ClassNotFoundException {
TestSuite suite = new TestSuite();
//Code not included for getTestSuites() in this snippet.
Collection<File> testSuites = getTestSuites();
for(File f: testSuites) {
//Truncate the path of the test to the beginning of the package name
String testName = f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("net"));
//Replace backslashes with fullstops
testName = te开发者_如何学CstName.replaceAll("\\\\", ".");
//Take the .class reference off the end of the path to the class
testName = testName.replaceAll(".class", "");
//Add TestSuite to Suite of Suites
Class<? extends Test> test = (Class<? extends Test>) AllTests.class.getClassLoader().loadClass(testName);
suite.addTest(test);
}
Unfortunately I am getting the following compiler error on the suite.addTest(test) line:
The method addTest(Test) in the type TestSuite is not applicable for the arguments (Class < capture#3-of ? extends Test>)
Am I making a fundamental mistake by assuming that a Class< Test > reference and a Test reference are one and the same?
Yes, you are making a fundamental mistake by assuming that a Class< Test > reference and a Test reference are one and the same.
You need an instance of a Class that extends Test
, not an instance of a Class object whose definition extends Test
(Classes are objects too in java).
TestSuite.addTest
needs a Test class instance; not just a Class object.
You could try using Class.newInstance()
if your tests can be (they should) instantiated without parameters.
--
A maybe better strategy is to start using Maven; which automatically runs all Test classes in the src/test/java source folder. But that can be a quite big overhaul :).
Class<Test>
describes the concept of class Test
-- its fields, methods, and other stuff described by the Java code when defining class Test
. There is generally (to keep classloaders out of this discussion) one instance of Class<Test>
across the JVM, since there is basically just one Test
class.
The same applies for every Test
subclass -- there is generally one instance of Class<TestSubClass>
for every TestSubClass
.
On the other hand, there can be any number of Test
objects.
Java allows you to create Test
objects from a Class<Test>
, by invoking newInstance
against your Class<Test>
instance. So basically, change your line from:
suite.addTest(test);
to
suite.addTest(test.newInstance());
And handle all potential exceptions.
Method you are using expects instance of Test (sub)class. The one you are after is probably addTestSuite(Class testClass) which allows adding classes.
精彩评论