Browse Source

JUnit4 tests marked @Ignore do not appear in XML output. PR 43969

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1452674 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 12 years ago
parent
commit
3930d3e938
25 changed files with 736 additions and 80 deletions
  1. +1
    -0
      CONTRIBUTORS
  2. +3
    -0
      WHATSNEW
  3. +4
    -0
      contributors.xml
  4. +1
    -1
      lib/libraries.properties
  5. BIN
      lib/optional/junit-4.11.jar
  6. BIN
      lib/optional/junit-4.8.1.jar
  7. +1
    -1
      release.sh
  8. +45
    -0
      src/etc/testcases/taskdefs/optional/junit.xml
  9. +43
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
  10. +89
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
  11. +53
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java
  12. +99
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
  13. +4
    -45
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
  14. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  15. +29
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
  16. +12
    -10
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  17. +42
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
  18. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
  19. +35
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java
  20. +74
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
  21. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java
  22. +101
    -18
      src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
  23. +1
    -0
      src/tests/antunit/taskdefs/optional/junit/junit-test.xml
  24. +38
    -1
      src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
  25. +56
    -0
      src/tests/junit/org/example/junit/Junit4Skippable.java

+ 1
- 0
CONTRIBUTORS View File

@@ -234,6 +234,7 @@ Matthew Inger
Matthew Kuperus Heun Matthew Kuperus Heun
Matthew Watson Matthew Watson
Michael Bayne Michael Bayne
Michael Clarke
Michael Davey Michael Davey
Michael J. Sikorsky Michael J. Sikorsky
Michael McCallum Michael McCallum


+ 3
- 0
WHATSNEW View File

@@ -87,6 +87,9 @@ Fixed bugs:
set to ANSI_X3.4-1968. set to ANSI_X3.4-1968.
Bugzilla Report 54606 Bugzilla Report 54606


* JUnit4 tests marked @Ignore do not appear in XML output
Bugzilla Report 43969

Other changes: Other changes:
-------------- --------------




+ 4
- 0
contributors.xml View File

@@ -957,6 +957,10 @@
<first>Michael</first> <first>Michael</first>
<last>Bayne</last> <last>Bayne</last>
</name> </name>
<name>
<first>Michael</first>
<last>Clarke</last>
</name>
<name> <name>
<first>Michael</first> <first>Michael</first>
<last>Davey</last> <last>Davey</last>


+ 1
- 1
lib/libraries.properties View File

@@ -45,7 +45,7 @@ jasper-compiler.version=4.1.36
jasper-runtime.version=${jasper-compiler.version} jasper-runtime.version=${jasper-compiler.version}
jdepend.version=2.9.1 jdepend.version=2.9.1
jruby.version=0.9.8 jruby.version=0.9.8
junit.version=4.8.1
junit.version=4.11
jsch.version=0.1.42 jsch.version=0.1.42
jython.version=2.1 jython.version=2.1
#log4j 1.2.15 requires JMS and a few other Sun jars that are not in the m2 repo #log4j 1.2.15 requires JMS and a few other Sun jars that are not in the m2 repo


BIN
lib/optional/junit-4.11.jar View File


BIN
lib/optional/junit-4.8.1.jar View File


+ 1
- 1
release.sh View File

@@ -17,7 +17,7 @@
# this is a first attempt to document the build of the distribution # this is a first attempt to document the build of the distribution
# paths are hard-coded and obviously this is for a Cygwin/Windows combo # paths are hard-coded and obviously this is for a Cygwin/Windows combo
####################################################################### #######################################################################
rm -rf bootstrap build dist distribution
rm -rf bootstrap build dist distribution java-repository
unset ANT_HOME unset ANT_HOME
# OS specific support. $var _must_ be set to either true or false. # OS specific support. $var _must_ be set to either true or false.
cygwin=false; cygwin=false;


+ 45
- 0
src/etc/testcases/taskdefs/optional/junit.xml View File

@@ -276,4 +276,49 @@
</junit> </junit>
</target> </target>


<!-- Junit4 Ignore and Assume for skipping tests -->
<target name="testSkippableTests">
<mkdir dir="out"/>
<junit fork="true">
<classpath refid="test"/>
<formatter type="xml"/>
<classpath refid="test"/>
<batchtest todir="out">
<fileset dir="../../../../tests/junit">
<include
name="org/example/junit/Junit4Skippable.java"/>
<!-- tests remove out-dir on tearDown -->
</fileset>
</batchtest>
</junit>
</target>

<target name="testTestMethods" >
<echo file="${tmp.dir}/T1.java">public class T1 extends
junit.framework.TestCase {
public void testOK() {}
public void testBad() {throw new RuntimeException("failed");}
}</echo>
<echo file="${tmp.dir}/T2.java">
import org.junit.Test;
public class T2 {
@Test
public void ok() {}
@Test
public void bad() {
throw new RuntimeException("failed");}
}</echo>
<javac srcdir="${tmp.dir}" destdir="${tmp.dir}" includes="T1.java,T2.java" source="5">

</javac>
<junit fork="false" printsummary="true" haltonerror="true">
<classpath>
<pathelement location="${tmp.dir}" />
<path refid="test" />
</classpath>
<test name="T1" methods="testOK" />
<test name="T2" methods="ok" />
</junit>
</target>

</project> </project>

+ 43
- 1
src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java View File

@@ -25,11 +25,13 @@ import java.io.StringWriter;
import java.text.NumberFormat; import java.text.NumberFormat;


import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.JUnit4TestCaseFacade;
import junit.framework.Test; import junit.framework.Test;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.StringUtils; import org.apache.tools.ant.util.StringUtils;
import org.junit.Ignore;


/** /**
* Prints plain text output of the test to a specified Writer. * Prints plain text output of the test to a specified Writer.
@@ -38,7 +40,7 @@ import org.apache.tools.ant.util.StringUtils;
* @see FormatterElement * @see FormatterElement
* @see PlainJUnitResultFormatter * @see PlainJUnitResultFormatter
*/ */
public class BriefJUnitResultFormatter implements JUnitResultFormatter {
public class BriefJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {


private static final double ONE_SECOND = 1000.0; private static final double ONE_SECOND = 1000.0;


@@ -141,6 +143,8 @@ public class BriefJUnitResultFormatter implements JUnitResultFormatter {
sb.append(suite.failureCount()); sb.append(suite.failureCount());
sb.append(", Errors: "); sb.append(", Errors: ");
sb.append(suite.errorCount()); sb.append(suite.errorCount());
sb.append(", Skipped: ");
sb.append(suite.skipCount());
sb.append(", Time elapsed: "); sb.append(", Time elapsed: ");
sb.append(numberFormat.format(suite.getRunTime() / ONE_SECOND)); sb.append(numberFormat.format(suite.getRunTime() / ONE_SECOND));
sb.append(" sec"); sb.append(" sec");
@@ -267,4 +271,42 @@ public class BriefJUnitResultFormatter implements JUnitResultFormatter {
throw new BuildException(ex); throw new BuildException(ex);
} }
} }


@Override
public void testIgnored(Test test) {
String message = null;
if (test instanceof JUnit4TestCaseFacade) {
JUnit4TestCaseFacade facade = (JUnit4TestCaseFacade) test;
Ignore annotation = facade.getDescription().getAnnotation(Ignore.class);
if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
message = annotation.value();
}
}
formatSkip(test, message);
}


public void formatSkip(Test test, String message) {
if (test != null) {
endTest(test);
}

try {
resultWriter.write(formatTest(test) + "SKIPPED");
if (message != null) {
resultWriter.write(": ");
resultWriter.write(message);
}
resultWriter.newLine();
} catch (IOException ex) {
throw new BuildException(ex);
}

}

@Override
public void testAssumptionFailure(Test test, Throwable cause) {
formatSkip(test, cause.getMessage());
}
} }

+ 89
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java View File

@@ -0,0 +1,89 @@
/*
* 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.tools.ant.taskdefs.optional.junit;

import junit.framework.JUnit4TestAdapter;
import junit.framework.JUnit4TestAdapterCache;
import junit.framework.TestResult;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;

/**
* Provides a custom implementation of the notifier for a Junit4TestAdapter
* so that skipped and ignored tests can be reported to the existing
* <tt>TestListener</tt>s.
*
*/
public class CustomJUnit4TestAdapterCache extends JUnit4TestAdapterCache {

private static final CustomJUnit4TestAdapterCache INSTANCE = new CustomJUnit4TestAdapterCache();

public static CustomJUnit4TestAdapterCache getInstance() {
return INSTANCE;
}

private CustomJUnit4TestAdapterCache() {
super();
}

public RunNotifier getNotifier(final TestResult result, final JUnit4TestAdapter adapter) {
return getNotifier(result);
}

public RunNotifier getNotifier(final TestResult result) {

final IgnoredTestResult resultWrapper = (IgnoredTestResult) result;

RunNotifier notifier = new RunNotifier();
notifier.addListener(new RunListener() {
@Override
public void testFailure(Failure failure) throws Exception {
result.addError(asTest(failure.getDescription()), failure.getException());
}

@Override
public void testFinished(Description description) throws Exception {
result.endTest(asTest(description));
}

@Override
public void testStarted(Description description) throws Exception {
result.startTest(asTest(description));
}

@Override
public void testIgnored(Description description) throws Exception {
if (resultWrapper != null) {
resultWrapper.testIgnored(asTest(description));
}
}

@Override
public void testAssumptionFailure(Failure failure) {
if (resultWrapper != null) {
resultWrapper.testAssumptionFailure(asTest(failure.getDescription()), failure.getException());
}
}
});

return notifier;
}
}

+ 53
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java View File

@@ -0,0 +1,53 @@
/*
* 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.tools.ant.taskdefs.optional.junit;

import junit.framework.Test;
import junit.framework.TestListener;
import org.junit.runner.notification.Failure;

/**
* Provides the functionality for TestListeners to be able to be notified of
* the necessary Junit4 events for test being ignored (@Ignore annotation)
* or skipped (Assume failures). Tests written in Junit4 will report against
* the methods in this interface alongside the methods in the existing TestListener
*/
public interface IgnoredTestListener extends TestListener {

/**
* Reports when a test has been marked with the @Ignore annotation. The parameter
* should normally be typed to Junit's {@link junit.framework.JUnit4TestCaseFacade}
* so implementing classes should be able to get the details of the ignore by casting
* the argument and retrieving the descriptor from the test.
* @param test
*/
void testIgnored(Test test);

/**
* Receive a report that a test has failed an assumption. Within JUnit4
* this is normally treated as a test being skipped, although how any
* listener handles this is up to that specific listener.<br />
* <b>Note:</b> Tests that throw assumption failures will still report
* the endTest method, which may differ from how the addError and addFailure
* methods work, it's up for any implementing classes to handle this.
* @param test the details of the test and failure that have triggered this report.
* @param exception the AssumptionViolatedException thrown from the current assumption failure.
*/
void testAssumptionFailure(Test test, Throwable exception);
}

+ 99
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java View File

@@ -0,0 +1,99 @@
/*
* 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.tools.ant.taskdefs.optional.junit;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Test;
import junit.framework.TestListener;
import junit.framework.TestResult;

/**
* Records ignored and skipped tests reported as part of the execution of
* JUnit 4 tests.
*
*/
public class IgnoredTestResult extends TestResult {


private List<IgnoredTestListener> listeners = new ArrayList<IgnoredTestListener>();
private List<TestIgnored> ignored = new ArrayList<TestIgnored>();
private List<TestIgnored> skipped = new ArrayList<TestIgnored>();

public IgnoredTestResult() {
super();
}


public synchronized void addListener(TestListener listener) {
if (listener instanceof IgnoredTestListener) {
listeners.add((IgnoredTestListener)listener);
}
super.addListener(listener);
}

public synchronized void removeListener(TestListener listener) {
if (listener instanceof IgnoredTestListener) {
listeners.remove(listener);
}
super.removeListener(listener);
}

/**
* Record a test as having been ignored, normally by the @Ignore annotation.
* @param test the test that was ignored.
* @throws Exception is the listener thrown an exception on handling the notification.
*/
public synchronized void testIgnored(Test test) throws Exception {
ignored.add(new TestIgnored(test));
for (IgnoredTestListener listener : listeners) {
listener.testIgnored(test);
}
}

/**
* Report how many tests were ignored.
* @return the number of tests reported as ignored during the current execution.
*/
public long ignoredCount() {
return ignored.size();
}

/**
* Records a test as having an assumption failure so JUnit will no longer be executing it.
* Under normal circumstances this would be counted as a skipped test.
* @param test the test to record
* @param cause the details of the test and assumption failure.
*/
public void testAssumptionFailure(Test test, Throwable cause) {
skipped.add(new TestIgnored(test));
for (IgnoredTestListener listener : listeners) {
listener.testAssumptionFailure(test, cause);
}
}

/**
* Report how many tests has assumption failures.
* @return the number of tests that reported assumption failures during the current execution.
*/
public long skippedCount() {
return skipped.size();
}
}

+ 4
- 45
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java View File

@@ -20,20 +20,16 @@ package org.apache.tools.ant.taskdefs.optional.junit;


import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import junit.framework.JUnit4TestAdapterCache;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestResult; import junit.framework.TestResult;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.junit.runner.Request; import org.junit.runner.Request;
import org.junit.runner.Runner; import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter; import org.junit.runner.manipulation.Filter;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;


/** /**
* Adapter between JUnit 3.8.x API and JUnit 4.x API for execution of tests * Adapter between JUnit 3.8.x API and JUnit 4.x API for execution of tests
* and listening of events (test start, test finish, test failure).
* and listening of events (test start, test finish, test failure, test skipped).
* The constructor is passed a JUnit 4 test class and a list of name of methods * The constructor is passed a JUnit 4 test class and a list of name of methods
* in it that should be executed. Method {@link #run run(TestResult)} executes * in it that should be executed. Method {@link #run run(TestResult)} executes
* the given JUnit-4-style test methods and notifies the given {@code TestResult} * the given JUnit-4-style test methods and notifies the given {@code TestResult}
@@ -46,7 +42,7 @@ public class JUnit4TestMethodAdapter implements Test {
private final Class testClass; private final Class testClass;
private final String[] methodNames; private final String[] methodNames;
private final Runner runner; private final Runner runner;
private final Cache cache;
private final CustomJUnit4TestAdapterCache cache;


/** /**
* Creates a new adapter for the given class and a method within the class. * Creates a new adapter for the given class and a method within the class.
@@ -75,7 +71,7 @@ public class JUnit4TestMethodAdapter implements Test {
} }
this.testClass = testClass; this.testClass = testClass;
this.methodNames = (String[]) methodNames.clone(); this.methodNames = (String[]) methodNames.clone();
this.cache = Cache.instance;
this.cache = CustomJUnit4TestAdapterCache.getInstance();


// Warning: If 'testClass' is an old-style (pre-JUnit-4) class, // Warning: If 'testClass' is an old-style (pre-JUnit-4) class,
// then all its test methods will be executed by the returned runner! // then all its test methods will be executed by the returned runner!
@@ -104,7 +100,7 @@ public class JUnit4TestMethodAdapter implements Test {
public Class getTestClass() { public Class getTestClass() {
return testClass; return testClass;
} }
public void run(final TestResult result) { public void run(final TestResult result) {
runner.run(cache.getNotifier(result)); runner.run(cache.getNotifier(result));
} }
@@ -188,42 +184,5 @@ public class JUnit4TestMethodAdapter implements Test {


} }


/**
* Effectively a copy of {@code JUnit4TestAdapterCache}, except that its
* method {@code getNotifier()} does not require an argument
* of type {@code JUnit4TestAdapter}.
*/
private static final class Cache extends JUnit4TestAdapterCache {
private static final long serialVersionUID = 8454901854293461610L;

private static final Cache instance = new Cache();

public static JUnit4TestAdapterCache getDefault() {
return instance;
}
public RunNotifier getNotifier(final TestResult result) {
RunNotifier notifier = new RunNotifier();
notifier.addListener(new RunListener() {
public void testFailure(Failure failure) throws Exception {
result.addError(asTest(failure.getDescription()),
failure.getException());
}

public void testFinished(Description description)
throws Exception {
result.endTest(asTest(description));
}

public void testStarted(Description description)
throws Exception {
result.startTest(asTest(description));
}
});
return notifier;
}

}


} }

+ 1
- 1
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java View File

@@ -1645,7 +1645,7 @@ public class JUnitTask extends Task {
classLoader.setThreadContextLoader(); classLoader.setThreadContextLoader();
} }


test.setCounts(1, 0, 1);
test.setCounts(1, 0, 1, 0);
test.setProperties(getProject().getProperties()); test.setProperties(getProject().getProperties());
for (int i = 0; i < feArray.length; i++) { for (int i = 0; i < feArray.length; i++) {
FormatterElement fe = feArray[i]; FormatterElement fe = feArray[i];


+ 29
- 1
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java View File

@@ -62,6 +62,11 @@ public class JUnitTest extends BaseTest implements Cloneable {
// part of the result. So we'd better derive a new class from TestResult // part of the result. So we'd better derive a new class from TestResult
// and deal with it. (SB) // and deal with it. (SB)
private long runs, failures, errors; private long runs, failures, errors;
/**
@since Ant 1.9.0
*/
private long skips;

private long runTime; private long runTime;


// Snapshot of the system properties // Snapshot of the system properties
@@ -352,16 +357,31 @@ public class JUnitTest extends BaseTest implements Cloneable {
} }


/** /**
* Set the number of runs, failures and errors.
* Set the number of runs, failures, errors, and skipped tests.
* @param runs the number of runs. * @param runs the number of runs.
* @param failures the number of failures. * @param failures the number of failures.
* @param errors the number of errors. * @param errors the number of errors.
* Kept for backward compatibility with Ant 1.8.4
*/ */
public void setCounts(long runs, long failures, long errors) { public void setCounts(long runs, long failures, long errors) {
this.runs = runs; this.runs = runs;
this.failures = failures; this.failures = failures;
this.errors = errors; this.errors = errors;
} }
/**
* Set the number of runs, failures, errors, and skipped tests.
* @param runs the number of runs.
* @param failures the number of failures.
* @param errors the number of errors.
* @param skips the number of skipped tests.
* @since Ant 1.9.0
*/
public void setCounts(long runs, long failures, long errors, long skips) {
this.runs = runs;
this.failures = failures;
this.errors = errors;
this.skips = skips;
}


/** /**
* Set the runtime. * Set the runtime.
@@ -395,6 +415,14 @@ public class JUnitTest extends BaseTest implements Cloneable {
return errors; return errors;
} }


/**
* Get the number of skipped tests.
* @return the number of skipped tests.
*/
public long skipCount() {
return skips;
}

/** /**
* Get the run time. * Get the run time.
* @return the run time in milliseconds. * @return the run time in milliseconds.


+ 12
- 10
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java View File

@@ -36,6 +36,7 @@ import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.Vector; import java.util.Vector;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.JUnit4TestAdapterCache;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestFailure; import junit.framework.TestFailure;
import junit.framework.TestListener; import junit.framework.TestListener;
@@ -76,7 +77,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
/** /**
* Collects TestResults. * Collects TestResults.
*/ */
private TestResult res;
private IgnoredTestResult res;


/** /**
* Do we filter junit.*.* stack frames out of failure and error exceptions. * Do we filter junit.*.* stack frames out of failure and error exceptions.
@@ -289,6 +290,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
boolean filtertrace, boolean haltOnFailure, boolean filtertrace, boolean haltOnFailure,
boolean showOutput, boolean logTestListenerEvents, boolean showOutput, boolean logTestListenerEvents,
ClassLoader loader) { ClassLoader loader) {
super();
JUnitTestRunner.filtertrace = filtertrace; // XXX clumsy, should use instance field somehow JUnitTestRunner.filtertrace = filtertrace; // XXX clumsy, should use instance field somehow
this.junitTest = test; this.junitTest = test;
this.haltOnError = haltOnError; this.haltOnError = haltOnError;
@@ -350,7 +352,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
* Run the test. * Run the test.
*/ */
public void run() { public void run() {
res = new TestResult();
res = new IgnoredTestResult();
res.addListener(wrapListener(this)); res.addListener(wrapListener(this));
final int size = formatters.size(); final int size = formatters.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -468,8 +470,8 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
formalParams = new Class[] {Class.class, String[].class}; formalParams = new Class[] {Class.class, String[].class};
actualParams = new Object[] {testClass, methods}; actualParams = new Object[] {testClass, methods};
} else { } else {
formalParams = new Class[] {Class.class};
actualParams = new Object[] {testClass};
formalParams = new Class[] {Class.class, JUnit4TestAdapterCache.class};
actualParams = new Object[] {testClass, CustomJUnit4TestAdapterCache.getInstance()};
} }
suite = suite =
(Test) junit4TestAdapterClass (Test) junit4TestAdapterClass
@@ -512,7 +514,7 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
((TestListener) formatters.elementAt(i)) ((TestListener) formatters.elementAt(i))
.addError(null, exception); .addError(null, exception);
} }
junitTest.setCounts(1, 0, 1);
junitTest.setCounts(1, 0, 1, 0);
junitTest.setRunTime(0); junitTest.setRunTime(0);
} else { } else {
try { try {
@@ -522,10 +524,10 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
if (junit4 || if (junit4 ||
suite.getClass().getName().equals(JUNIT_4_TEST_ADAPTER)) { suite.getClass().getName().equals(JUNIT_4_TEST_ADAPTER)) {
int[] cnts = findJUnit4FailureErrorCount(res); int[] cnts = findJUnit4FailureErrorCount(res);
junitTest.setCounts(res.runCount(), cnts[0], cnts[1]);
junitTest.setCounts(res.runCount() + res.ignoredCount(), cnts[0], cnts[1], res.ignoredCount() + res.skippedCount());
} else { } else {
junitTest.setCounts(res.runCount(), res.failureCount(),
res.errorCount());
junitTest.setCounts(res.runCount() + res.ignoredCount(), res.failureCount(),
res.errorCount(), res.ignoredCount() + res.skippedCount());
} }
junitTest.setRunTime(System.currentTimeMillis() - start); junitTest.setRunTime(System.currentTimeMillis() - start);
} }
@@ -1101,8 +1103,8 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
* *
* @since Ant 1.7 * @since Ant 1.7
*/ */
private TestListener wrapListener(final TestListener testListener) {
return new TestListener() {
private TestListenerWrapper wrapListener(final TestListener testListener) {
return new TestListenerWrapper(testListener) {
public void addError(Test test, Throwable t) { public void addError(Test test, Throwable t) {
if (junit4 && t instanceof AssertionFailedError) { if (junit4 && t instanceof AssertionFailedError) {
// JUnit 4 does not distinguish between errors and failures // JUnit 4 does not distinguish between errors and failures


+ 42
- 1
src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java View File

@@ -26,11 +26,14 @@ import java.text.NumberFormat;
import java.util.Hashtable; import java.util.Hashtable;


import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.JUnit4TestCaseFacade;
import junit.framework.Test; import junit.framework.Test;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.StringUtils; import org.apache.tools.ant.util.StringUtils;
import org.junit.Ignore;
import org.junit.runner.notification.Failure;




/** /**
@@ -38,7 +41,7 @@ import org.apache.tools.ant.util.StringUtils;
* *
*/ */


public class PlainJUnitResultFormatter implements JUnitResultFormatter {
public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {


private static final double ONE_SECOND = 1000.0; private static final double ONE_SECOND = 1000.0;


@@ -123,6 +126,8 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter {
sb.append(suite.failureCount()); sb.append(suite.failureCount());
sb.append(", Errors: "); sb.append(", Errors: ");
sb.append(suite.errorCount()); sb.append(suite.errorCount());
sb.append(", Skipped: ");
sb.append(suite.skipCount());
sb.append(", Time elapsed: "); sb.append(", Time elapsed: ");
sb.append(nf.format(suite.getRunTime() / ONE_SECOND)); sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
sb.append(" sec"); sb.append(" sec");
@@ -258,4 +263,40 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter {
} }
} }


@Override
public void testIgnored(Test test) {
String message = null;
if (test instanceof JUnit4TestCaseFacade) {
JUnit4TestCaseFacade facade = (JUnit4TestCaseFacade) test;
Ignore annotation = facade.getDescription().getAnnotation(Ignore.class);
if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
message = annotation.value();
}
}
formatSkip(test, message);
}


public void formatSkip(Test test, String message) {
if (test != null) {
endTest(test);
}

try {
wri.write("\tSKIPPED");
if (message != null) {
wri.write(": ");
wri.write(message);
}
wri.newLine();
} catch (IOException ex) {
throw new BuildException(ex);
}

}

@Override
public void testAssumptionFailure(Test test, Throwable throwable) {
formatSkip(test, throwable.getMessage());
}
} // PlainJUnitResultFormatter } // PlainJUnitResultFormatter

+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java View File

@@ -144,6 +144,8 @@ public class SummaryJUnitResultFormatter
sb.append(suite.failureCount()); sb.append(suite.failureCount());
sb.append(", Errors: "); sb.append(", Errors: ");
sb.append(suite.errorCount()); sb.append(suite.errorCount());
sb.append(", Skipped: ");
sb.append(suite.skipCount());
sb.append(", Time elapsed: "); sb.append(", Time elapsed: ");
sb.append(nf.format(suite.getRunTime() / ONE_SECOND)); sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
sb.append(" sec"); sb.append(" sec");


+ 35
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java View File

@@ -0,0 +1,35 @@
/*
* 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.tools.ant.taskdefs.optional.junit;

import junit.framework.Test;

public class TestIgnored {

private Test test;

public TestIgnored(Test test) {
this.test = test;
}

public Test getTest() {
return test;
}

}

+ 74
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java View File

@@ -0,0 +1,74 @@
/*
* 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.tools.ant.taskdefs.optional.junit;

import junit.framework.AssertionFailedError;
import junit.framework.JUnit4TestAdapterCache;
import junit.framework.Test;
import junit.framework.TestListener;

import org.junit.internal.AssumptionViolatedException;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;

public class TestListenerWrapper implements TestListener, IgnoredTestListener {

private TestListener wrapped;

public TestListenerWrapper(TestListener listener) {
super();
wrapped = listener;
}

@Override
public void addError(Test test, Throwable throwable) {
wrapped.addError(test, throwable);
}

@Override
public void addFailure(Test test, AssertionFailedError assertionFailedError) {
wrapped.addFailure(test, assertionFailedError);
}

@Override
public void endTest(Test test) {
wrapped.endTest(test);
}

@Override
public void startTest(Test test) {
wrapped.startTest(test);
}

@Override
public void testIgnored(Test test) {
if (wrapped instanceof IgnoredTestListener) {
((IgnoredTestListener)wrapped).testIgnored(test);
}
}

@Override
public void testAssumptionFailure(Test test, Throwable throwable) {
if (wrapped instanceof IgnoredTestListener) {
((IgnoredTestListener)wrapped).testAssumptionFailure(test, throwable);
}
}


}

+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java View File

@@ -106,6 +106,8 @@ public interface XMLConstants {
/** tests attribute for testsuite elements */ /** tests attribute for testsuite elements */
String ATTR_TESTS = "tests"; String ATTR_TESTS = "tests";


String ATTR_SKIPPED = "skipped";

/** type attribute for failure and error elements */ /** type attribute for failure and error elements */
String ATTR_TYPE = "type"; String ATTR_TYPE = "type";




+ 101
- 18
src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java View File

@@ -23,20 +23,26 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Properties; import java.util.Properties;
import java.util.Date;
import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;

import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.JUnit4TestCaseFacade;
import junit.framework.Test; import junit.framework.Test;

import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.DOMElementWriter; import org.apache.tools.ant.util.DOMElementWriter;
import org.apache.tools.ant.util.DateUtils; import org.apache.tools.ant.util.DateUtils;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.junit.Ignore;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Text; import org.w3c.dom.Text;
@@ -48,7 +54,7 @@ import org.w3c.dom.Text;
* @see FormatterElement * @see FormatterElement
*/ */


public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants {
public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants, IgnoredTestListener {


private static final double ONE_SECOND = 1000.0; private static final double ONE_SECOND = 1000.0;


@@ -73,16 +79,29 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
private Element rootElement; private Element rootElement;
/** /**
* Element for the current test. * Element for the current test.
*
* The keying of this map is a bit of a hack: tests are keyed by caseName(className) since
* the Test we get for Test-start isn't the same as the Test we get during test-assumption-fail,
* so we can't easily match Test objects without manually iterating over all keys and checking
* individual fields.
*/ */
private Hashtable testElements = new Hashtable();
private Hashtable<String, Element> testElements = new Hashtable<String, Element>();
/** /**
* tests that failed. * tests that failed.
*/ */
private Hashtable failedTests = new Hashtable(); private Hashtable failedTests = new Hashtable();
/**
* Tests that were skipped.
*/
private Hashtable<String, Test> skippedTests = new Hashtable<String, Test>();
/**
* Tests that were ignored. See the note above about the key being a bit of a hack.
*/
private Hashtable<String, Test> ignoredTests = new Hashtable<String, Test>();
/** /**
* Timing helper. * Timing helper.
*/ */
private Hashtable testStarts = new Hashtable();
private Hashtable<String, Long> testStarts = new Hashtable<String, Long>();
/** /**
* Where to write the log to. * Where to write the log to.
*/ */
@@ -161,6 +180,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount()); rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount());
rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount()); rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount());
rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount()); rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount());
rootElement.setAttribute(ATTR_SKIPPED, "" + suite.skipCount());
rootElement.setAttribute( rootElement.setAttribute(
ATTR_TIME, "" + (suite.getRunTime() / ONE_SECOND)); ATTR_TIME, "" + (suite.getRunTime() / ONE_SECOND));
if (out != null) { if (out != null) {
@@ -193,9 +213,13 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
* @param t the test. * @param t the test.
*/ */
public void startTest(Test t) { public void startTest(Test t) {
testStarts.put(t, new Long(System.currentTimeMillis()));
testStarts.put(createDescription(t), System.currentTimeMillis());
} }


private static String createDescription(Test test) throws BuildException {
return JUnitVersionHelper.getTestCaseName(test) + "(" + JUnitVersionHelper.getTestCaseClassName(test) + ")";
}

/** /**
* Interface TestListener. * Interface TestListener.
* *
@@ -203,15 +227,16 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
* @param test the test. * @param test the test.
*/ */
public void endTest(Test test) { public void endTest(Test test) {
String testDescription = createDescription(test);

// Fix for bug #5637 - if a junit.extensions.TestSetup is // Fix for bug #5637 - if a junit.extensions.TestSetup is
// used and throws an exception during setUp then startTest // used and throws an exception during setUp then startTest
// would never have been called // would never have been called
if (!testStarts.containsKey(test)) {
if (!testStarts.containsKey(testDescription)) {
startTest(test); startTest(test);
} }

Element currentTest = null;
if (!failedTests.containsKey(test)) {
Element currentTest;
if (!failedTests.containsKey(test) && !skippedTests.containsKey(testDescription) && !ignoredTests.containsKey(testDescription)) {
currentTest = doc.createElement(TESTCASE); currentTest = doc.createElement(TESTCASE);
String n = JUnitVersionHelper.getTestCaseName(test); String n = JUnitVersionHelper.getTestCaseName(test);
currentTest.setAttribute(ATTR_NAME, currentTest.setAttribute(ATTR_NAME,
@@ -221,15 +246,14 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
currentTest.setAttribute(ATTR_CLASSNAME, currentTest.setAttribute(ATTR_CLASSNAME,
JUnitVersionHelper.getTestCaseClassName(test)); JUnitVersionHelper.getTestCaseClassName(test));
rootElement.appendChild(currentTest); rootElement.appendChild(currentTest);
testElements.put(test, currentTest);
testElements.put(createDescription(test), currentTest);
} else { } else {
currentTest = (Element) testElements.get(test);
currentTest = testElements.get(testDescription);
} }


Long l = (Long) testStarts.get(test);
Long l = testStarts.get(createDescription(test));
currentTest.setAttribute(ATTR_TIME, currentTest.setAttribute(ATTR_TIME,
"" + ((System.currentTimeMillis()
- l.longValue()) / ONE_SECOND));
"" + ((System.currentTimeMillis() - l) / ONE_SECOND));
} }


/** /**
@@ -272,9 +296,9 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
} }


Element nested = doc.createElement(type); Element nested = doc.createElement(type);
Element currentTest = null;
Element currentTest;
if (test != null) { if (test != null) {
currentTest = (Element) testElements.get(test);
currentTest = testElements.get(createDescription(test));
} else { } else {
currentTest = rootElement; currentTest = rootElement;
} }
@@ -298,4 +322,63 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan
nested.appendChild(doc.createCDATASection(output)); nested.appendChild(doc.createCDATASection(output));
} }


@Override
public void testIgnored(Test test) {
String message = null;
if (test != null && test instanceof JUnit4TestCaseFacade) {
//try and get the message coded as part of the ignore
/*
* org.junit.runner.Description contains a getAnnotation(Class) method... but this
* wasn't in older versions of JUnit4 so we have to try and do this by reflection
*/
try {
Class<?> testClass = Class.forName(JUnitVersionHelper.getTestCaseClassName(test));
Method testMethod = testClass.getMethod(JUnitVersionHelper.getTestCaseName(test));
Ignore annotation = testMethod.getAnnotation(Ignore.class);
if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
message = annotation.value();
}
} catch (NoSuchMethodException e) {
// silently ignore - we'll report a skip with no message
} catch (ClassNotFoundException e) {
// silently ignore - we'll report a skip with no message
}
}
formatSkip(test, message);
if (test != null) {
ignoredTests.put(createDescription(test), test);
}
}


public void formatSkip(Test test, String message) {
if (test != null) {
endTest(test);
}

Element nested = doc.createElement("skipped");

if (message != null) {
nested.setAttribute("message", message);
}

Element currentTest;
if (test != null) {
currentTest = testElements.get(createDescription(test));
} else {
currentTest = rootElement;
}

currentTest.appendChild(nested);

}

@Override
public void testAssumptionFailure(Test test, Throwable failure) {
String message = failure.getMessage();
formatSkip(test, message);
skippedTests.put(createDescription(test), test);

}
} // XMLJUnitResultFormatter } // XMLJUnitResultFormatter

+ 1
- 0
src/tests/antunit/taskdefs/optional/junit/junit-test.xml View File

@@ -20,6 +20,7 @@


<path id="junit"> <path id="junit">
<fileset dir="../../../../../../lib/optional" includes="junit*" /> <fileset dir="../../../../../../lib/optional" includes="junit*" />
<fileset dir="../../../../../../lib/optional" includes="hamcrest-core*" />
</path> </path>


<macrodef name="empty-test"> <macrodef name="empty-test">


+ 38
- 1
src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java View File

@@ -25,6 +25,14 @@ import java.io.IOException;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildFileTest; import org.apache.tools.ant.BuildFileTest;
import org.apache.tools.ant.util.JavaEnvUtils; import org.apache.tools.ant.util.JavaEnvUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;


public class JUnitTaskTest extends BuildFileTest { public class JUnitTaskTest extends BuildFileTest {


@@ -262,7 +270,7 @@ public class JUnitTaskTest extends BuildFileTest {
line); line);
line = reader.readLine(); line = reader.readLine();
assertNotNull(line); assertNotNull(line);
assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Time elapsed:"));
assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:"));
line = reader.readLine(); line = reader.readLine();
assertEquals("------------- Standard Output ---------------", assertEquals("------------- Standard Output ---------------",
line); line);
@@ -296,4 +304,33 @@ public class JUnitTaskTest extends BuildFileTest {
assertEquals(search, line); assertEquals(search, line);
} }


public void testJunit4Skip() throws Exception {
executeTarget("testSkippableTests");

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(getProject().getResource("out/TEST-org.example.junit.Junit4Skippable.xml").getInputStream());

assertEquals("Incorrect number of nodes created", 8, doc.getElementsByTagName("testcase").getLength());

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

assertEquals("Incorrect number of skipped tests in header", 4, Integer.parseInt(xpath.compile("//testsuite/@skipped").evaluate(doc)));
assertEquals("Incorrect number of error tests in header", 1, Integer.parseInt(xpath.compile("//testsuite/@errors").evaluate(doc)));
assertEquals("Incorrect number of failure tests in header", 2, Integer.parseInt(xpath.compile("//testsuite/@failures").evaluate(doc)));
assertEquals("Incorrect number of tests in header", 8, Integer.parseInt(xpath.compile("//testsuite/@tests").evaluate(doc)));


assertEquals("Incorrect ignore message on explicit ignored test", "Please don't ignore me!", xpath.compile("//testsuite/testcase[@name='explicitIgnoreTest']/skipped/@message").evaluate(doc));
assertEquals("No message should be set on Ignored tests with no Ignore annotation text", 0, ((Node)xpath.compile("//testsuite/testcase[@name='explicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)).getAttributes().getLength());
assertEquals("Incorrect ignore message on implicit ignored test", "This test will be ignored", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTest']/skipped/@message").evaluate(doc));
assertNotNull("Implicit ignore test should have an ignore element", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE));

}

public void testTestMethods() throws Exception {
executeTarget("testTestMethods");
}

} }

+ 56
- 0
src/tests/junit/org/example/junit/Junit4Skippable.java View File

@@ -0,0 +1,56 @@
package org.example.junit;

import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class Junit4Skippable {

@Test
public void passingTest() {
assertTrue("This test passed", true);
}

@Ignore("Please don't ignore me!")
@Test
public void explicitIgnoreTest() {
fail("This test should be skipped");
}

@Test
public void implicitlyIgnoreTest() {
Assume.assumeFalse("This test will be ignored", true);
fail("I told you, this test should have been ignored!");
}

@Test
@Ignore
public void explicitlyIgnoreTestNoMessage() {
fail("This test should be skipped");
}

@Test
public void implicitlyIgnoreTestNoMessage() {
Assume.assumeFalse(true);
fail("I told you, this test should have been ignored!");
}

@Test
public void failingTest() {
fail("I told you this test was going to fail");
}

@Test
public void failingTestNoMessage() {
fail();
}

@Test
public void errorTest() {
throw new RuntimeException("Whoops, this test went wrong");
}

}

Loading…
Cancel
Save