Add Junit3 and Junit4 adapters allowing to launch AntUnit script from JUnit runner (I still have some weakness to fix in the junit4 runner)

git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/antunit/trunk@743906 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Scokart Gilles 2009-02-12 22:21:28 +00:00
parent 0b6bc826c1
commit 5220af86b5
15 changed files with 954 additions and 1 deletions

View File

@ -25,5 +25,8 @@ under the License.
<!-- don't fork junit; regexp classes not available -->
<property name="junit.fork" value="false" />
<property name="javac.test-source" value="1.5"/>
<property name="javac.test-target" value="1.5"/>
<import file="common/build.xml"/>
</project>

View File

@ -38,6 +38,9 @@
</properties>
<release version="1.2" date="not-released">
<action type="add">
Add Junit3 and Junit4 adapters allowing to launch AntUnit script from JUnit runner
</action>
<action type="update">
expectfailure report the original build exception chained when failing
</action>

View File

@ -62,4 +62,8 @@
<first>Steve</first>
<last>Loughran</last>
</name>
<name>
<first>Gilles</first>
<last>Scokart</last>
</name>
</contributors>

View File

@ -0,0 +1,59 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project name="junit" default="all" xmlns:au="antlib:org.apache.ant.antunit"
basedir="../../../../">
<target name="all">
<fail message="These are not standalone tests." />
</target>
<property name="outputdir" location="target/test_output"/>
<property name="outputfile" location="${outputdir}/junit_out.xml"/>
<target name="suiteSetUp">
<mkdir dir="${outputdir}"/>
<delete file="${outputfile}"/>
<echo file="${outputfile}" append="true" message="suiteSetUp-" />
</target>
<target name="suiteTearDown">
<echo file="${outputfile}" append="true" message="suiteTearDown" />
</target>
<target name="setUp">
<echo file="${outputfile}" append="true" message="setUp-" />
</target>
<target name="tearDown">
<echo file="${outputfile}" append="true" message="tearDown-" />
</target>
<target name="test1">
<echo file="${outputfile}" append="true" message="test1-" />
</target>
<target name="test2">
<echo file="${outputfile}" append="true" message="test2-" />
</target>
</project>

View File

@ -4,7 +4,7 @@ import org.apache.tools.ant.Project;
/**
* Provides project instances for AntUnit execution.<br/>
* The aproach to creates a project depends on the context. When invoked from an
* The approach to creates a project depends on the context. When invoked from an
* ant project, some elements might be intialized from the parent project. When
* executed in a junit runner, a brand new project must be initialized.<br/>
* The AntScriptRunner will usually creates multiple project in order to provide test isolation.

View File

@ -0,0 +1,168 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit3;
import java.io.File;
import java.io.PrintStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
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.DefaultLogger;
import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
/**
* A JUnit 3 TestSuite that group a suite of AntUnit targets coming from an ant
* script.
*/
public class AntUnitSuite extends TestSuite {
private final AntUnitScriptRunner antScriptRunner;
private final MultiProjectDemuxOutputStream stderr;
private final MultiProjectDemuxOutputStream stdout;
/**
* Create a JUnit TestSuite that when executed will run the given ant
* script.<br/>
* Note that it is the responsibility of the caller to give the correct
* File reference. Namely, if the File is a relative file, it will
* be resolve relatively to the execution directory (which might be
* different different from the project root directory).
*
* @param scriptFile
* AntUnit script file
* @param rootClass
* 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);
stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
setName(antScriptRunner.getName() + "[" + scriptFile + "]");
List testTargets = antScriptRunner.getTestTartgets();
for (Iterator it = testTargets.iterator(); it.hasNext();) {
String target = (String) it.next();
AntUnitTestCase tc = new AntUnitTestCase(this, scriptFile, target);
addTest(tc);
}
}
/**
* @Override Run the full AntUnit suite
*/
public void run(TestResult testResult) {
List testTartgets = antScriptRunner.getTestTartgets();
runInContainer(testTartgets, testResult, tests());
}
/**
* @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);
}
/**
* Execute the test suite in a 'container' similar to the ant 'container'.
* When ant executes a project it redirect the input and the output. In this
* context we will only redirect output (unit test are not supposed to be
* interactive)
*
* @param targetList
* The list of test target to execute
* @param result
* The JUnit3 TestResult receiving result notification
* @param tests
* The JUnit3 Test classes instances to use in the notification.
*/
private void runInContainer(List targetList, TestResult result,
Enumeration/*<Test>*/tests) {
JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
result, tests);
PrintStream savedErr = System.err;
PrintStream savedOut = System.out;
try {
System.setOut(new PrintStream(stdout));
System.setErr(new PrintStream(stderr));
antScriptRunner.runSuite(targetList, notifier);
} finally {
System.setOut(savedOut);
System.setErr(savedErr);
}
}
/**
* The antscript project factory that creates projects in a junit context.
*/
private static class MyProjectFactory implements ProjectFactory {
private final File scriptFile;
private final PrintStream realStdErr = System.err;
private final PrintStream realStdOut = System.out;
public MyProjectFactory(File scriptFile) {
this.scriptFile = scriptFile;
}
public Project createProject() {
ProjectHelper prjHelper = ProjectHelper.getProjectHelper();
Project prj = new Project();
DefaultLogger logger = new DefaultLogger();
logger.setMessageOutputLevel(Project.MSG_INFO);
logger.setErrorPrintStream(realStdErr);
logger.setOutputPrintStream(realStdOut);
prj.addBuildListener(logger);
String absolutePath = scriptFile.getAbsolutePath();
prj.setUserProperty(MagicNames.ANT_FILE, absolutePath);
prj.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, prjHelper);
prj.init();
prjHelper.parse(prj, scriptFile);
return prj;
}
}
}

View File

@ -0,0 +1,133 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit3;
import java.io.File;
import junit.framework.TestCase;
import junit.framework.TestResult;
/**
* JUnit TestCase that will executes a single AntUnit target. This class is not
* supposed to be used directly. <br/>
* It is public only because junit must access it as a public.
*/
public class AntUnitTestCase extends TestCase {
// We have to extends TestCase, and not implements Test because otherwise
// JUnit4 will derive the Description composing the suite description from
// this className only (AntUnitTestCase), and not from the name.
// However, during execution it use the right Description (base on the
// toString)
/**
* AntUnitSuite that contains this AntUnitTestCase. Execution is done via
* this suite
*/
private final AntUnitSuite suite;
/**
* The test target
*/
private final String target;
/**
* Prepare an AntUnitTestCase that will be executed alone. This constructor
* is typically used by a junit 3 runner that will reexecute a specific
* test.</br>
* The execution of this test will be embed in a suiteSetUp and
* suiteTearDown.
* @param name The name of the AntUnitTestCase, normally obtained from a
* previous execution.
*/
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
}
/**
* Prepare an AntUnitTestCase that will be executed in a suite. It is the
* suite that prepare the antScriptRunner and the JUnitExcutionPlatform. It
* is the responsibility of the suite to execute the suiteSetUp and the
* suiteTearDown.
*
* @param target
* @param antScriptRunner
* @param executionEnv
*/
public AntUnitTestCase(AntUnitSuite suite, File scriptFile, String target) {
// The name can be reused by eclipse when running a single test
super(new TestCaseName(scriptFile, target).getName());
this.target = target;
this.suite = suite;
}
/** Get the AntUnit test target name */
public String getTarget() {
return target;
}
/** @overwrite */
public void run(TestResult result) {
suite.runTest(this, result);
}
/**
* 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,
* so that the name uniquely identify the TestCase, and a TestCase can be
* executed from its name.
*/
static class TestCaseName {
private final String name;
private final File script;
private final String target;
public TestCaseName(String name) {
this.name = name;
this.target = name.substring(0, name.indexOf(' '));
String filename = name.substring(name.indexOf(' ') + 2, name
.length() - 1);
this.script = new File(filename);
}
public TestCaseName(File script, String target) {
this.script = script;
this.target = target;
this.name = target + " [" + script + "]";
}
public String getName() {
return name;
}
public File getScript() {
return script;
}
public String getTarget() {
return target;
}
}
}

View File

@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit3;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.ant.antunit.AntUnitExecutionNotifier;
import org.apache.ant.antunit.AssertionFailedException;
/**
* Adapt AntUnitExecutionNotifier events into JUnit3 TestResult events
*/
class JUnitNotificationAdapter implements AntUnitExecutionNotifier {
private final TestResult junitTestResult;
private Map testByTarget = new HashMap();
public JUnitNotificationAdapter(TestResult testResult, Enumeration tests) {
this.junitTestResult = testResult;
while(tests.hasMoreElements()) {
AntUnitTestCase test = (AntUnitTestCase) tests.nextElement();
testByTarget.put(test.getTarget(), test);
}
}
public void fireStartTest(String targetName) {
//TODO : if it is null, eclipse stop the unit test (add a unit test)
junitTestResult.startTest((Test) testByTarget.get(targetName));
}
public void fireEndTest(String targetName) {
junitTestResult.endTest((Test) testByTarget.get(targetName));
}
public void fireError(String targetName, Throwable t) {
junitTestResult.addError((Test) testByTarget.get(targetName), t);
}
public void fireFail(String targetName, AssertionFailedException ae) {
//I don't see how to transform the AntUnit assertion exception into
//junit assertion exception (we would loose the stack trace).
//So failures will be reported as errors
junitTestResult.addError((Test) testByTarget.get(targetName), ae);
}
}

View File

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit3;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.ant.antunit.AntUnitScriptRunner;
import org.apache.tools.ant.DemuxOutputStream;
import org.apache.tools.ant.Project;
/**
* Forward stdout or stderr operation to the current antunit project.
*/
class MultiProjectDemuxOutputStream extends OutputStream {
private final AntUnitScriptRunner scriptRunner;
private Project lastProject;
private DemuxOutputStream lastDemuxOutputStream = null;
private final boolean isErrorStream;
public MultiProjectDemuxOutputStream(AntUnitScriptRunner scriptRunner, boolean isErrorStream) {
this.scriptRunner = scriptRunner;
this.isErrorStream = isErrorStream;
}
private DemuxOutputStream getDemuxOutputStream() {
if (lastProject != scriptRunner.getCurrentProject()) {
lastProject = scriptRunner.getCurrentProject();
lastDemuxOutputStream = new DemuxOutputStream(lastProject,isErrorStream);
}
return lastDemuxOutputStream;
}
public void write(int b) throws IOException {
getDemuxOutputStream().write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
getDemuxOutputStream().write(b, off, len);
}
public void close() throws IOException {
getDemuxOutputStream().close();
}
public void flush() throws IOException {
getDemuxOutputStream().flush();
}
}

View File

@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit4;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import org.apache.ant.antunit.junit3.AntUnitSuite;
import org.apache.ant.antunit.junit3.AntUnitTestCase;
import org.junit.internal.runners.CompositeRunner;
import org.junit.internal.runners.InitializationError;
/**
* JUnit4 Runner to put in a RunWith annotation of the AntUnitSuite when using a
* JUnit4 runner. Using this runner is not mandatory because junit4 is able to
* run junit3 test. However, the test will be faster (TODO make that true :-) )
* with this Runner. Also, more features are available when this runner is used
* (filtering & sorting)
* TODO Support filtering and sorting
*/
public class AntUnitSuiteRunner extends CompositeRunner {
private AntUnitSuiteRunner(AntUnitSuite suite, Class junitTestClass) {
super(suite.getName());
Enumeration tests = suite.tests();
while (tests.hasMoreElements()) {
AntUnitTestCase tc = (AntUnitTestCase) tests.nextElement();
add(new AntUnitTestCaseRunner(tc, junitTestClass));
}
}
public AntUnitSuiteRunner(Class testCaseClass) throws InitializationError {
this(getJUnit3AntSuite(testCaseClass), testCaseClass);
}
private static AntUnitSuite getJUnit3AntSuite(Class testCaseClass)
throws InitializationError {
try {
Method suiteMethod = testCaseClass.getMethod("suite", new Class[0]);
if (!Modifier.isStatic(suiteMethod.getModifiers())) {
throw new InitializationError("suite method must be static");
}
return (AntUnitSuite) suiteMethod.invoke(null, new Object[0]);
} catch (NoSuchMethodException e) {
throw new InitializationError(new Throwable[] { e });
} catch (IllegalAccessException e) {
throw new InitializationError(new Throwable[] { e });
} catch (InvocationTargetException e) {
throw new InitializationError(new Throwable[] { e });
} catch (ClassCastException e) {
throw new InitializationError(new Throwable[] { e });
}
}
}

View File

@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit4;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestListener;
import junit.framework.TestResult;
import org.apache.ant.antunit.junit3.AntUnitTestCase;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
class AntUnitTestCaseRunner extends Runner {
private final AntUnitTestCase fTest;
private final Class junitTestClass;
public AntUnitTestCaseRunner(AntUnitTestCase testCase, Class junitTestClass) {
this.fTest = testCase;
this.junitTestClass = junitTestClass;
}
public void run(final RunNotifier notifier) {
final Description description = getDescription();
TestListener testListener = new TestListener() {
// TODO implement directly the mapping from AntUnitExecutionNotifier
// to junit4 RunNotifier
public void endTest(Test test) {
notifier.fireTestFinished(description);
}
public void startTest(Test test) {
notifier.fireTestStarted(description);
}
public void addError(Test test, Throwable t) {
Failure failure = new Failure(description, t);
notifier.fireTestFailure(failure);
}
public void addFailure(Test test, AssertionFailedError t) {
addError(test, t);
}
};
TestResult result = new TestResult();
result.addListener(testListener);
fTest.run(result);
}
public Description getDescription() {
return Description.createTestDescription(junitTestClass, fTest
.getName());
}
}

View File

@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.ant.antunit.junit3;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.apache.tools.ant.util.FileUtils;
public class AntUnitSuiteTest extends TestCase {
AntUnitSuite suite = new AntUnitSuite(new File(
"src/etc/testcases/antunit/junit.xml"));
File outFile = new File("target/test_output/junit_out.xml");
public void testRunSuiteSetUp() throws FileNotFoundException, IOException {
TestResult testResult = new TestResult();
suite.run(testResult);
assertTrue(testResult.wasSuccessful());
String output = FileUtils.readFully(new FileReader(outFile));
String EXPECT1 = "suiteSetUp-setUp-test1-tearDown-setUp-test2-tearDown-suiteTearDown";
String EXPECT2 = "suiteSetUp-setUp-test2-tearDown-setUp-test1-tearDown-suiteTearDown";
assertTrue("unexted output : " + output, EXPECT1.equals(output)
|| EXPECT2.equals(output));
}
public void testSuiteName() {
assertTrue("Expected non empty suite name", suite.getName().trim()
.length() > 0);
}
public void testChildNames() {
assertTrue("Expected more test, received " + suite.testCount(),
suite.testCount() >= 1);
Enumeration/*<Test>*/tests = suite.tests();
StringBuffer testTargets = new StringBuffer();
while (tests.hasMoreElements()) {
String nextName = tests.nextElement().toString();
testTargets.append(" ").append(nextName).append(" ,");
}
assertTrue("test1 not found in child : " + testTargets, testTargets
.toString().contains(" test1 "));
}
public void testSingleTestRunSuiteSetUp() throws Exception {
AntUnitTestCase test1 = (AntUnitTestCase) suite.testAt(0);
if (test1.getTarget().equals("test2")) {
test1 = (AntUnitTestCase) suite.testAt(1);
}
TestResult testResult = new TestResult();
suite.runTest(test1, testResult);
assertTrue(testResult.wasSuccessful());
String output = FileUtils.readFully(new FileReader(outFile));
assertTrue("unexted output : " + output,
"suiteSetUp-setUp-test1-tearDown-suiteTearDown".equals(output));
}
}

View File

@ -0,0 +1,71 @@
package org.apache.ant.antunit.junit3;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.apache.ant.antunit.junit3.AntUnitTestCase;
import org.apache.tools.ant.util.FileUtils;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestResult;
public class AntUnitTestCaseTest extends TestCase {
File f = new File("src/etc/testcases/antunit/junit.xml");
String test1Name = new AntUnitTestCase.TestCaseName(f, "test1").getName();
File outFile = new File("target/test_output/junit_out.xml");
public void testNameParsing() {
AntUnitTestCase.TestCaseName nameObj = new AntUnitTestCase.TestCaseName(
test1Name);
assertEquals(f, nameObj.getScript());
assertEquals("test1", nameObj.getTarget());
}
public void testRunSuiteSetUp() throws FileNotFoundException, IOException {
// When eclipse has to run a specific testCase (user click Run on it),
// an AntUnitTestCase(name) is created, and the run should execute the
// suiteSetup/SuiteTearDown
AntUnitTestCase antUnitTestCase = new AntUnitTestCase(test1Name);
TestResult testResult = new TestResult();
antUnitTestCase.run(testResult);
assertTrue(testResult.wasSuccessful());
String output = FileUtils.readFully(new FileReader(outFile));
assertEquals("suiteSetUp-setUp-test1-tearDown-suiteTearDown", output);
}
private Test startedTest = null;
private Test endedTest = null;
public void testTestIdentityInNotification() {
// When eclipse has to run a specific testCase (user click Run on it),
// an AntUnitTestCase(name) is created, and this instance must be used
// in the notification (otherwise the test appears twice, once normal
// but never executed, and once with "Unrooted Tests" parent.
TestResult testResultMock = new TestResult() {
public void startTest(Test test) {
// Note that putting an assertion here to fail fatser doesn't
// work because
// exceptions are catched by the runner
startedTest = test;
}
public void endTest(Test test) {
endedTest = test;
}
};
AntUnitTestCase antUnitTestCase = new AntUnitTestCase(test1Name);
antUnitTestCase.run(testResultMock);
Assert.assertSame(antUnitTestCase, startedTest);
Assert.assertSame(antUnitTestCase, endedTest);
}
}

View File

@ -0,0 +1,22 @@
package org.apache.ant.antunit.junit3;
import java.io.File;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
import org.junit.runner.RunWith;
/**
* A unit test using the junit3 and junit4 adapter.
*/
@RunWith(AntUnitSuiteRunner.class)
public class EatYourOwnDogFoodTest extends TestCase {
public static TestSuite suite() {
File script = new File("src/etc/testcases/antunit/java-io.xml");
return new AntUnitSuite(script, EatYourOwnDogFoodTest.class);
}
}

View File

@ -0,0 +1,110 @@
package org.apache.ant.antunit.junit4;
import java.io.File;
import java.util.ArrayList;
import junit.framework.TestCase;
import org.apache.ant.antunit.junit3.AntUnitSuite;
import org.junit.Ignore;
import org.junit.internal.runners.InitializationError;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
public class AntUnitSuiteTest extends TestCase {
private boolean mockExecutionOK = false;
private String mockExcutionError = "";
/**
* When a test is executed, the description used in the notification must be
* equals to the description declared, otherwise the runner is confused (for
* example in eclipse you have all the tests listed twice, but reported only
* once as executed.
*
* @throws InitializationError
*/
public void testDescriptionsReportedInNotifier() throws InitializationError {
final AntUnitSuiteRunner runner = new AntUnitSuiteRunner(
JUnit4AntUnitRunnable.class);
final ArrayList tDescs = runner.getDescription().getChildren();
final int TEST_STARTED = 1, TEST_FINISHED = 2;
RunNotifier notifierMock = new RunNotifier() {
Description curTest = null;
public void fireTestStarted(Description description) {
if (curTest != null) {
mockExcutionError += "Unexpected fireTestStarted("
+ description.getDisplayName() + "\n";
}
if (!tDescs.contains(description)) {
mockExcutionError += "Unexpected fireTestStarted("
+ description.getDisplayName() + ")\n";
}
curTest = description;
}
@Override
public void fireTestFinished(Description description) {
if (curTest == null) {
mockExcutionError += "Unexpected fireTestFinished("
+ description.getDisplayName() + "\n";
}
if (!curTest.equals(description)) {
mockExcutionError += "Unexpected fireTestFinished("
+ description.getDisplayName() + "); expect "
+ curTest.getDisplayName() + "\n";
}
curTest = null;
mockExecutionOK = true;
}
};
runner.run(notifierMock);
assertTrue(mockExcutionError, mockExcutionError.isEmpty());
assertTrue(mockExecutionOK);
}
public void testMissingSuiteMethodInitializationError() {
try {
AntUnitSuiteRunner runner = new AntUnitSuiteRunner(
JUnit4AntUnitRunnableWithoutSuiteMethod.class);
fail("InitializationError expected");
} catch (InitializationError e) {
String msg = e.getCauses().get(0).getMessage();
assertTrue("Unexpected error : " + msg, msg.contains("suite"));
}
}
public void testNonStaticSuiteMethodInitializationError() {
try {
AntUnitSuiteRunner runner = new AntUnitSuiteRunner(
JUnit4AntUnitRunnableWithNonStaticSuite.class);
fail("InitializationError expected");
} catch (InitializationError e) {
String msg = e.getCauses().get(0).getMessage();
assertTrue("Unexpected error : " + msg, msg.contains("suite"));
assertTrue("Unexpected error : " + msg, msg.contains("static"));
}
}
public static class JUnit4AntUnitRunnable {
public static AntUnitSuite suite() {
File f = new File("src/etc/testcases/antunit/junit.xml");
return new AntUnitSuite(f, JUnit4AntUnitRunnable.class);
}
}
public static class JUnit4AntUnitRunnableWithNonStaticSuite {
public AntUnitSuite suite() {
File f = new File("src/etc/testcases/antunit/junit.xml");
return new AntUnitSuite(f,
JUnit4AntUnitRunnableWithNonStaticSuite.class);
}
}
public static class JUnit4AntUnitRunnableWithoutSuiteMethod {
}
}