Add error handling in the initalisation of the project
git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/antunit/trunk@744468 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9fafac9d17
commit
f5e36a2c4e
|
|
@ -97,8 +97,9 @@ public class AntUnitScriptRunner {
|
|||
* Create a new AntScriptRunner on the given environment.
|
||||
* @param prjFactory A factory for the ant project that will contains the antunit test to execute.
|
||||
* The factory might be invoked multiple time in order to provide test isolation.
|
||||
* @throws BuildException The project can not be parsed
|
||||
*/
|
||||
public AntUnitScriptRunner(ProjectFactory prjFactory) {
|
||||
public AntUnitScriptRunner(ProjectFactory prjFactory) throws BuildException {
|
||||
this.prjFactory = prjFactory;
|
||||
Project newProject = getCurrentProject();
|
||||
Map targets = newProject.getTargets();
|
||||
|
|
@ -119,8 +120,9 @@ public class AntUnitScriptRunner {
|
|||
/**
|
||||
* Get the project currently in use. The caller is not allowed to invoke a target or
|
||||
* do anything that would break the isolation of the test targets.
|
||||
* @throws BuildException The project can not be parsed
|
||||
*/
|
||||
public final Project getCurrentProject() {
|
||||
public final Project getCurrentProject() throws BuildException {
|
||||
//Method is final because it is called from the constructor
|
||||
if (project == null) {
|
||||
project = prjFactory.createProject();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.apache.ant.antunit;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Project;
|
||||
|
||||
/**
|
||||
|
|
@ -14,7 +15,8 @@ public interface ProjectFactory {
|
|||
|
||||
/**
|
||||
* Creates a new project instance and configures it according to the execution context.
|
||||
* @throws BuildException The project can not be created (probably parsed)
|
||||
*/
|
||||
public Project createProject();
|
||||
public Project createProject() throws BuildException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestResult;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.apache.ant.antunit.AntUnitScriptRunner;
|
||||
import org.apache.ant.antunit.ProjectFactory;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.DefaultLogger;
|
||||
import org.apache.tools.ant.MagicNames;
|
||||
import org.apache.tools.ant.Project;
|
||||
|
|
@ -47,6 +49,7 @@ public class AntUnitSuite extends TestSuite {
|
|||
private final AntUnitScriptRunner antScriptRunner;
|
||||
private final MultiProjectDemuxOutputStream stderr;
|
||||
private final MultiProjectDemuxOutputStream stdout;
|
||||
private final Test initializationReportingTest;
|
||||
|
||||
/**
|
||||
* Create a JUnit TestSuite that when executed will run the given ant
|
||||
|
|
@ -62,22 +65,25 @@ public class AntUnitSuite extends TestSuite {
|
|||
* The test class that creates this suite. This is used to give
|
||||
* a name to the suite so that an IDE can reexecute this suite.
|
||||
*/
|
||||
public AntUnitSuite(final File scriptFile, Class rootClass) {
|
||||
this(scriptFile);
|
||||
setName(rootClass.getName());// Allows eclipse to reexecute the test
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used by AntUnitTestCase when a single test case is created.
|
||||
* The difference with the public constructor is this version doesn't set
|
||||
* the name.
|
||||
*/
|
||||
AntUnitSuite(final File scriptFile) {
|
||||
MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
|
||||
antScriptRunner = new AntUnitScriptRunner(prjFactory);
|
||||
public AntUnitSuite(File scriptFile, Class rootClass) {
|
||||
AntUnitScriptRunner createdScriptRunner = null;
|
||||
try {
|
||||
MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
|
||||
createdScriptRunner = new AntUnitScriptRunner(prjFactory);
|
||||
} catch (BuildException e) {
|
||||
antScriptRunner = null;
|
||||
stdout = null;
|
||||
stderr = null;
|
||||
initializationReportingTest = error(e);
|
||||
addTest(initializationReportingTest);
|
||||
return;
|
||||
}
|
||||
antScriptRunner = createdScriptRunner;
|
||||
initializationReportingTest = null;
|
||||
stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
|
||||
stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
|
||||
setName(antScriptRunner.getName() + "[" + scriptFile + "]");
|
||||
setName(antScriptRunner.getName() + "[" + scriptFile + "]");
|
||||
setName(rootClass.getName());// Allows eclipse to reexecute the test
|
||||
List testTargets = antScriptRunner.getTestTartgets();
|
||||
for (Iterator it = testTargets.iterator(); it.hasNext();) {
|
||||
String target = (String) it.next();
|
||||
|
|
@ -86,24 +92,58 @@ public class AntUnitSuite extends TestSuite {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used by AntUnitTestCase when a single test case is created.
|
||||
* The difference with the public constructor is this version doesn't set
|
||||
* the name.
|
||||
* @throws BuildException when the file project can not be create (parsed/read)
|
||||
*/
|
||||
AntUnitSuite(AntUnitTestCase singleTc , File scriptFile) throws BuildException {
|
||||
MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
|
||||
antScriptRunner = new AntUnitScriptRunner(prjFactory);
|
||||
//the exception is throwed, and it is up to the AntUnitTestCase to handle it.
|
||||
initializationReportingTest = null;
|
||||
stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
|
||||
stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
|
||||
setName(antScriptRunner.getName() + "[" + scriptFile + "]");
|
||||
addTest(singleTc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Override Run the full AntUnit suite
|
||||
*/
|
||||
public void run(TestResult testResult) {
|
||||
List testTartgets = antScriptRunner.getTestTartgets();
|
||||
runInContainer(testTartgets, testResult, tests());
|
||||
if (initializationReportingTest!=null) {
|
||||
initializationReportingTest.run(testResult);
|
||||
} else {
|
||||
List testTartgets = antScriptRunner.getTestTartgets();
|
||||
runInContainer(testTartgets, testResult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Test error(final BuildException ex) {
|
||||
return new TestCase("warning") {
|
||||
protected void runTest() throws BuildException {
|
||||
throw ex;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Override Run a single test target of the AntUnit suite. suiteSetUp,
|
||||
* setUp, tearDown and suiteTearDown are executed around it.
|
||||
*/
|
||||
public void runTest(Test test, TestResult result) {
|
||||
String targetName = ((AntUnitTestCase) test).getTarget();
|
||||
List singleTargetList = Collections.singletonList(targetName);
|
||||
Enumeration singleTestList = Collections.enumeration(Collections
|
||||
.singletonList(test));
|
||||
runInContainer(singleTargetList, result, singleTestList);
|
||||
if (initializationReportingTest!=null) {
|
||||
initializationReportingTest.run(result);
|
||||
} else {
|
||||
String targetName = ((AntUnitTestCase) test).getTarget();
|
||||
List singleTargetList = Collections.singletonList(targetName);
|
||||
runInContainer(singleTargetList, result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -119,10 +159,9 @@ public class AntUnitSuite extends TestSuite {
|
|||
* @param tests
|
||||
* The JUnit3 Test classes instances to use in the notification.
|
||||
*/
|
||||
private void runInContainer(List targetList, TestResult result,
|
||||
Enumeration/*<Test>*/tests) {
|
||||
private void runInContainer(List targetList, TestResult result) {
|
||||
JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
|
||||
result, tests);
|
||||
result, tests());
|
||||
PrintStream savedErr = System.err;
|
||||
PrintStream savedOut = System.out;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ package org.apache.ant.antunit.junit3;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestResult;
|
||||
|
||||
|
|
@ -48,6 +50,15 @@ public class AntUnitTestCase extends TestCase {
|
|||
*/
|
||||
private final String target;
|
||||
|
||||
/**
|
||||
* Store the exception when the project can not be parsed, but only if this
|
||||
* class has been created directly by the IDE from its name.
|
||||
* In case of initialisation problem when the test is build from the suite,
|
||||
* the problem is handled at the level of the suite (and this object is never
|
||||
* created)
|
||||
*/
|
||||
private final BuildException initialisationException;
|
||||
|
||||
/**
|
||||
* Prepare an AntUnitTestCase that will be executed alone. This constructor
|
||||
* is typically used by a junit 3 runner that will reexecute a specific
|
||||
|
|
@ -59,10 +70,19 @@ public class AntUnitTestCase extends TestCase {
|
|||
*/
|
||||
public AntUnitTestCase(String name) {
|
||||
super(name);
|
||||
TestCaseName nameParser = new TestCaseName(name);
|
||||
target = nameParser.getTarget();
|
||||
suite = new AntUnitSuite(nameParser.getScript());
|
||||
// TODO : check that target is in the list
|
||||
BuildException catchedEx = null;
|
||||
AntUnitSuite createdSuite = null;
|
||||
TestCaseName nameParser = new TestCaseName(name);
|
||||
try {
|
||||
createdSuite = new AntUnitSuite(this, nameParser.getScript());
|
||||
} catch (BuildException e) {
|
||||
catchedEx = e;
|
||||
}
|
||||
this.initialisationException = catchedEx;
|
||||
this.suite = createdSuite;
|
||||
this.target = nameParser.getTarget();
|
||||
//There is no need to check here if the target still exists. This check
|
||||
//will be done during execution, and we will get a very nice error
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,6 +100,7 @@ public class AntUnitTestCase extends TestCase {
|
|||
super(new TestCaseName(scriptFile, target).getName());
|
||||
this.target = target;
|
||||
this.suite = suite;
|
||||
this.initialisationException = null;
|
||||
}
|
||||
|
||||
/** Get the AntUnit test target name */
|
||||
|
|
@ -87,11 +108,34 @@ public class AntUnitTestCase extends TestCase {
|
|||
return target;
|
||||
}
|
||||
|
||||
/** @overwrite */
|
||||
/**
|
||||
* Called by a Junit Runner that want to executes specifically
|
||||
* this test target.
|
||||
* This implementation delegates the call to the suite.
|
||||
* @Overwrite
|
||||
*/
|
||||
public void run(TestResult result) {
|
||||
suite.runTest(this, result);
|
||||
if (initialisationException==null && suite!=null) {
|
||||
//normal case, the test is executed from the suite
|
||||
suite.runTest(this, result);
|
||||
} else {
|
||||
//special case, the suite failed to be created
|
||||
//the execution will be handled by this object
|
||||
//directly
|
||||
super.run(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally never used because this object delegates all execution
|
||||
* to an AntUnitSuite. However, when the suite can not be created
|
||||
* (because the ant project is invalid), this object is executed
|
||||
* and just throws the exception.
|
||||
*/
|
||||
protected void runTest() throws BuildException {
|
||||
throw initialisationException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the serialization and the parsing of the name of a TestCase. The
|
||||
* name of the TestCase contains the filename of the script and the target,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ public class AntUnitSuiteRunner extends CompositeRunner {
|
|||
super(suite.getName());
|
||||
Enumeration tests = suite.tests();
|
||||
while (tests.hasMoreElements()) {
|
||||
//TODO Handle the the case of FileNotFound.
|
||||
//In that case the suite contains an error Test and we have
|
||||
//a ClassCastException instead of a nice & clear error
|
||||
AntUnitTestCase tc = (AntUnitTestCase) tests.nextElement();
|
||||
add(new AntUnitTestCaseRunner(tc, junitTestClass));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.io.IOException;
|
|||
import java.util.Enumeration;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestFailure;
|
||||
import junit.framework.TestResult;
|
||||
|
||||
import org.apache.tools.ant.util.FileUtils;
|
||||
|
|
@ -34,7 +35,7 @@ import org.apache.tools.ant.util.FileUtils;
|
|||
public class AntUnitSuiteTest extends TestCase {
|
||||
|
||||
AntUnitSuite suite = new AntUnitSuite(new File(
|
||||
"src/etc/testcases/antunit/junit.xml"));
|
||||
"src/etc/testcases/antunit/junit.xml"), AntUnitSuiteTest.class);
|
||||
File outFile = new File("target/test_output/junit_out.xml");
|
||||
|
||||
public void testRunSuiteSetUp() throws FileNotFoundException, IOException {
|
||||
|
|
@ -51,8 +52,8 @@ public class AntUnitSuiteTest extends TestCase {
|
|||
}
|
||||
|
||||
public void testSuiteName() {
|
||||
assertTrue("Expected non empty suite name", suite.getName().trim()
|
||||
.length() > 0);
|
||||
assertTrue("Expected non empty suite name",
|
||||
suite.getName().trim().length() > 0);
|
||||
}
|
||||
|
||||
public void testChildNames() {
|
||||
|
|
@ -84,4 +85,16 @@ public class AntUnitSuiteTest extends TestCase {
|
|||
"suiteSetUp-setUp-test1-tearDown-suiteTearDown".equals(output));
|
||||
}
|
||||
|
||||
public void testFileNotFound() throws Exception {
|
||||
suite = new AntUnitSuite(new File("xxxx"), AntUnitSuiteTest.class);
|
||||
TestResult testResult = new TestResult();
|
||||
suite.run(testResult);
|
||||
|
||||
assertEquals(1 , testResult.errorCount());
|
||||
TestFailure error = (TestFailure) testResult.errors().nextElement();
|
||||
assertTrue("Unexpected error : " + error.exceptionMessage(),
|
||||
error.exceptionMessage().contains("xxxx"));
|
||||
}
|
||||
|
||||
//TODO test missing target error reporting
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,12 +30,16 @@ import org.apache.tools.ant.util.FileUtils;
|
|||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestFailure;
|
||||
import junit.framework.TestResult;
|
||||
|
||||
public class AntUnitTestCaseTest extends TestCase {
|
||||
|
||||
File f = new File("src/etc/testcases/antunit/junit.xml");
|
||||
File invalidF = new File("invalidFile");
|
||||
String test1Name = new AntUnitTestCase.TestCaseName(f, "test1").getName();
|
||||
String unknownName = new AntUnitTestCase.TestCaseName(f, "unknown").getName();
|
||||
String nameForInvalidF = new AntUnitTestCase.TestCaseName(invalidF, "x").getName();
|
||||
|
||||
File outFile = new File("target/test_output/junit_out.xml");
|
||||
|
||||
|
|
@ -84,7 +88,38 @@ public class AntUnitTestCaseTest extends TestCase {
|
|||
AntUnitTestCase antUnitTestCase = new AntUnitTestCase(test1Name);
|
||||
antUnitTestCase.run(testResultMock);
|
||||
|
||||
Assert.assertSame(antUnitTestCase, startedTest);
|
||||
Assert.assertSame(antUnitTestCase, endedTest);
|
||||
assertSame(antUnitTestCase, startedTest);
|
||||
assertSame(antUnitTestCase, endedTest);
|
||||
}
|
||||
|
||||
public void testUnknownTarget() {
|
||||
//when the antscript has changed (the target has been removed) and the user try
|
||||
//to rerun this target.
|
||||
TestResult testResult = new TestResult();
|
||||
|
||||
AntUnitTestCase antUnitTestCase = new AntUnitTestCase(unknownName);
|
||||
antUnitTestCase.run(testResult);
|
||||
|
||||
assertEquals(1 , testResult.errorCount());
|
||||
TestFailure error = (TestFailure) testResult.errors().nextElement();
|
||||
assertSame(antUnitTestCase, error.failedTest());
|
||||
assertTrue("Unexpected error : " + error.exceptionMessage(),
|
||||
error.exceptionMessage().contains("unknown"));
|
||||
}
|
||||
|
||||
public void testInvalidFile() {
|
||||
//when the ant script has changed (or just disappeared) and the user try
|
||||
//to rerun this target.
|
||||
TestResult testResult = new TestResult();
|
||||
|
||||
AntUnitTestCase antUnitTestCase = new AntUnitTestCase(nameForInvalidF);
|
||||
antUnitTestCase.run(testResult);
|
||||
|
||||
assertEquals(1 , testResult.errorCount());
|
||||
TestFailure error = (TestFailure) testResult.errors().nextElement();
|
||||
assertSame(antUnitTestCase, error.failedTest());
|
||||
assertTrue("Unexpected error : " + error.exceptionMessage(),
|
||||
error.exceptionMessage().contains("invalidFile"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue