Author: dfabulich Date: Fri Jan 25 13:06:26 2008 New Revision: 615340 URL: http://svn.apache.org/viewvc?rev=615340&view=rev Log: [SUREFIRE-439] Fix TestNG listeners and reporters
Added: maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/TestNgListenerReporter.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/pom.xml maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/FileHelper.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/Reporter.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/ResultListener.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/SuiteListener.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/TestNGSuiteTest.java Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java Added: maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/TestNgListenerReporter.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/TestNgListenerReporter.java?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/TestNgListenerReporter.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/TestNgListenerReporter.java Fri Jan 25 13:06:26 2008 @@ -0,0 +1,40 @@ +package org.apache.maven.surefire.its; + + +import junit.framework.TestCase; +import org.apache.maven.it.Verifier; +import org.apache.maven.it.util.ResourceExtractor; + +import java.io.File; + +/** + * Test simple TestNG listener and reporter + * + * @author <a href="mailto:[EMAIL PROTECTED]">Dan Fabulich</a> + * + */ +public class TestNgListenerReporter + extends TestCase +{ + public void testTestNgListenerReporter () + throws Exception + { + File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/testng-listener-reporter" ); + + Verifier verifier = new Verifier( testDir.getAbsolutePath() ); + verifier.executeGoal( "test" ); + verifier.verifyErrorFreeLog(); + verifier.resetStreams(); + + HelperAssertions.assertTestSuiteResults( 1, 0, 0, 0, testDir ); + File targetDir = new File( testDir, "target" ); + assertFileExists ( new File( targetDir, "resultlistener-output.txt" ) ); + assertFileExists ( new File( targetDir, "suitelistener-output.txt" ) ); + assertFileExists ( new File( targetDir, "reporter-output.txt" ) ); + } + + private void assertFileExists( File file ) + { + assertTrue( "File doesn't exist: " + file.getAbsolutePath(), file.exists() ); + } +} Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/pom.xml URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/pom.xml?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/pom.xml (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/pom.xml Fri Jan 25 13:06:26 2008 @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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 xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.maven.plugins.surefire</groupId> + <artifactId>testng-listener-reporter</artifactId> + <version>1.0-SNAPSHOT</version> + <name>TestNG listener and reporter test</name> + + <properties> + <testNgVersion>5.7</testNgVersion> + </properties> + + <dependencies> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>${testNgVersion}</version> + <classifier>jdk15</classifier> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <properties> + <property><name>listener</name><value>listenReport.ResultListener,listenReport.SuiteListener</value></property> + <property><name>reporter</name><value>listenReport.Reporter</value></property> + </properties> + </configuration> + </plugin> + </plugins> + </build> + + +</project> Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/FileHelper.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/FileHelper.java?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/FileHelper.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/FileHelper.java Fri Jan 25 13:06:26 2008 @@ -0,0 +1,25 @@ +package listenReport; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class FileHelper +{ + public static void writeFile(String fileName, String content) + { + try + { + File target = new File( "target" ).getAbsoluteFile(); + File listenerOutput = new File( target, fileName ); + FileWriter out = new FileWriter(listenerOutput); + out.write( content ); + out.flush(); + out.close(); + } + catch ( IOException e ) + { + throw new RuntimeException(e); + } + } +} Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/Reporter.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/Reporter.java?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/Reporter.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/Reporter.java Fri Jan 25 13:06:26 2008 @@ -0,0 +1,18 @@ +package listenReport; + +import java.util.List; + +import org.testng.IReporter; +import org.testng.ISuite; +import org.testng.xml.XmlSuite; + +public class Reporter + implements IReporter +{ + + public void generateReport( List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory ) + { + FileHelper.writeFile( "reporter-output.txt", "This is a reporter" ); + } + +} Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/ResultListener.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/ResultListener.java?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/ResultListener.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/ResultListener.java Fri Jan 25 13:06:26 2008 @@ -0,0 +1,67 @@ +package listenReport; +import org.testng.ITestContext; +import org.testng.ITestResult; +import org.testng.internal.IResultListener; + + +public class ResultListener + implements IResultListener +{ + + public void onFinish( ITestContext context ) + { + + } + + public void onStart( ITestContext context ) + { + FileHelper.writeFile( "resultlistener-output.txt", "This is a result listener" ); + } + + public void onTestFailedButWithinSuccessPercentage( ITestResult result ) + { + + } + + public void onTestFailure( ITestResult result ) + { + + } + + public void onTestSkipped( ITestResult result ) + { + + + } + + public void onTestStart( ITestResult result ) + { + + + } + + public void onTestSuccess( ITestResult result ) + { + + + } + + public void onConfigurationFailure( ITestResult itr ) + { + + + } + + public void onConfigurationSkip( ITestResult itr ) + { + + + } + + public void onConfigurationSuccess( ITestResult itr ) + { + + + } + +} Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/SuiteListener.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/SuiteListener.java?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/SuiteListener.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/SuiteListener.java Fri Jan 25 13:06:26 2008 @@ -0,0 +1,20 @@ +package listenReport; + +import org.testng.ISuite; +import org.testng.ISuiteListener; + +public class SuiteListener + implements ISuiteListener +{ + + public void onFinish( ISuite suite ) + { + + } + + public void onStart( ISuite suite ) + { + FileHelper.writeFile( "suitelistener-output.txt", "This is a suite listener" ); + } + +} Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/TestNGSuiteTest.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/TestNGSuiteTest.java?rev=615340&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/TestNGSuiteTest.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/testng-listener-reporter/src/test/java/listenReport/TestNGSuiteTest.java Fri Jan 25 13:06:26 2008 @@ -0,0 +1,13 @@ +package listenReport; + +import org.testng.annotations.Test; + + +public class TestNGSuiteTest { + + @Test + public void doNothing() + { + + } +} \ No newline at end of file Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java?rev=615340&r1=615339&r2=615340&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java (original) +++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java Fri Jan 25 13:06:26 2008 @@ -54,12 +54,10 @@ String classifier, ReporterManager reportManager, SurefireTestSuite suite, File reportsDirectory ) throws TestSetFailedException { - // kind of ugly, but listeners are configured differently - final String listeners = (String) options.remove("listener"); TestNG testng = new TestNG( false ); Configurator configurator = getConfigurator( version ); configurator.configure( testng, options ); - postConfigure( testng, testSourceDirectory, listeners, classifier, reportManager, suite, reportsDirectory ); + postConfigure( testng, testSourceDirectory, classifier, reportManager, suite, reportsDirectory ); testng.setTestClasses( testClasses ); testng.run(); } @@ -71,8 +69,7 @@ TestNG testng = new TestNG( false ); Configurator configurator = getConfigurator( version ); configurator.configure( testng, options ); - postConfigure( testng, testSourceDirectory, (String) options.get("listener"), classifier, reportManager, suite, reportsDirectory ); - + postConfigure( testng, testSourceDirectory, classifier, reportManager, suite, reportsDirectory ); testng.setTestSuites( suiteFiles ); testng.run(); } @@ -106,8 +103,8 @@ } - private static void postConfigure( TestNG testNG, String sourcePath, String listenerClasses, - String classifier, ReporterManager reportManager, SurefireTestSuite suite, File reportsDirectory ) + private static void postConfigure( TestNG testNG, String sourcePath, String classifier, + ReporterManager reportManager, SurefireTestSuite suite, File reportsDirectory ) throws TestSetFailedException { // turn off all TestNG output @@ -117,8 +114,6 @@ testNG.addListener( (Object) reporter ); attachNonStandardReporter( testNG, "org.testng.reporters.XMLReporter" ); attachNonStandardReporter( testNG, "org.testng.reporters.FailedReporter" ); - // TODO: we should have the Profile so that we can decide if this is needed or not - testNG.setListenerClasses(loadListenerClasses(listenerClasses)); // FIXME: use classifier to decide if we need to pass along the source dir (onyl for JDK14) if ( sourcePath != null ) @@ -147,29 +142,6 @@ } catch (ClassNotFoundException e) { return new TestNGReporter( reportManager ); } - } - - private static List loadListenerClasses(String listenerClasses) throws TestSetFailedException - { - if (listenerClasses == null || "".equals(listenerClasses.trim())) { - return new ArrayList(); - } - - List classes = new ArrayList(); - String[] classNames = listenerClasses.split(" *, *"); - for(int i = 0; i < classNames.length; i++) - { - try - { - classes.add(Class.forName(classNames[i])); - } - catch(Exception ex) - { - throw new TestSetFailedException("Cannot find listener class " + classNames[i], ex); - } - } - - return classes; } private static void attachNonStandardReporter( TestNG testNG, String className ) Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java?rev=615340&r1=615339&r2=615340&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java (original) +++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java Fri Jan 25 13:06:26 2008 @@ -19,12 +19,15 @@ * under the License. */ +import org.apache.maven.surefire.testset.TestSetFailedException; import org.apache.maven.surefire.util.NestedRuntimeException; import org.testng.TestNG; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; public abstract class AbstractDirectConfigurator @@ -42,8 +45,10 @@ this.setters = options; } - public void configure( TestNG testng, Map options ) + public void configure( TestNG testng, Map options ) throws TestSetFailedException { + // kind of ugly, but listeners are configured differently + final String listeners = (String) options.remove("listener"); for ( Iterator it = options.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry) it.next(); @@ -64,8 +69,33 @@ } } + // TODO: we should have the Profile so that we can decide if this is needed or not + testng.setListenerClasses(loadListenerClasses(listeners)); } + public static List loadListenerClasses(String listenerClasses) throws TestSetFailedException + { + if (listenerClasses == null || "".equals(listenerClasses.trim())) { + return new ArrayList(); + } + + List classes = new ArrayList(); + String[] classNames = listenerClasses.split(" *, *"); + for(int i = 0; i < classNames.length; i++) + { + try + { + classes.add(Class.forName(classNames[i])); + } + catch(Exception ex) + { + throw new TestSetFailedException("Cannot find listener class " + classNames[i], ex); + } + } + + return classes; + } + public static final class Setter { private final String setterName; Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java?rev=615340&r1=615339&r2=615340&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java (original) +++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java Fri Jan 25 13:06:26 2008 @@ -19,11 +19,12 @@ * under the License. */ +import org.apache.maven.surefire.testset.TestSetFailedException; import org.testng.TestNG; import java.util.Map; public interface Configurator { - void configure( TestNG testng, Map options ); + void configure( TestNG testng, Map options ) throws TestSetFailedException; } Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java?rev=615340&r1=615339&r2=615340&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java (original) +++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java Fri Jan 25 13:06:26 2008 @@ -19,18 +19,25 @@ * under the License. */ -import org.testng.TestNG; - +import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import org.apache.maven.surefire.testset.TestSetFailedException; +import org.testng.TestNG; + /** * TestNG configurator for 5.3+ versions. TestNG exposes * a [EMAIL PROTECTED] org.testng.TestNG#configure(java.util.Map)} method. * All suppported TestNG options are passed in String format, except - * <code>TestNGCommandLineArgs.LISTENER_COMMAND_OPT</code> which is <code>List<Class></code> - * and <code>TestNGCommandLineArgs.JUNIT_DEF_OPT</code> which is a <code>Boolean</code>. + * <code>TestNGCommandLineArgs.LISTENER_COMMAND_OPT</code> which is <code>List>Class<</code>, + * <code>TestNGCommandLineArgs.JUNIT_DEF_OPT</code> which is a <code>Boolean</code>, + * <code>TestNGCommandLineArgs.SKIP_FAILED_INVOCATION_COUNT_OPT</code> which is a <code>Boolean</code>, + * <code>TestNGCommandLineArgs.OBJECT_FACTORY_COMMAND_OPT</code> which is a <code>Class</code>, + * <code>TestNGCommandLineArgs.REPORTERS_LIST</code> which is a <code>List>ReporterConfig<</code>. + * * <p/> * Test classes and/or suite files are not passed along as options parameters, but * configured separately. @@ -40,7 +47,7 @@ public class TestNGMapConfigurator implements Configurator { - public void configure( TestNG testng, Map options ) + public void configure( TestNG testng, Map options ) throws TestSetFailedException { Map convertedOptions = new HashMap(); for ( Iterator it = options.entrySet().iterator(); it.hasNext(); ) @@ -48,14 +55,29 @@ Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); Object val = entry.getValue(); + if ( "listener".equals( key ) ) + { + val = AbstractDirectConfigurator.loadListenerClasses((String) val); + } + if ( "reporter".equals( key ) ) + { + // TODO support multiple reporters? + val = convertReporterConfig( val ); + key = "reporterslist"; + + } if ( "junit".equals( key ) ) { val = convert( val, Boolean.class ); + } else if ( "skipfailedinvocationcounts".equals( key ) ) + { + val = convert( val, Boolean.class ); } else if ( "threadcount".equals( key ) ) { val = convert( val, String.class ); } + // TODO objectfactory... not even documented, does it work? if ( key.startsWith("-") ) { convertedOptions.put( key, val ); @@ -67,6 +89,26 @@ } testng.configure( convertedOptions ); + + } + + // ReporterConfig only became available in later versions of TestNG + private Object convertReporterConfig( Object val ) + { + final String reporterConfigClassName = "org.testng.ReporterConfig"; + try + { + Class reporterConfig = Class.forName( reporterConfigClassName ); + Method deserialize = reporterConfig.getMethod( "deserialize", new Class[] { String.class } ); + Object rc = deserialize.invoke( null, new Object[] { val } ); + ArrayList reportersList = new ArrayList(); + reportersList.add( rc ); + return reportersList; + } + catch ( Exception e ) + { + return val; + } } protected Object convert( Object val, Class type )