blob: 6f461679d12996ccc97e39e753085705c8221925 [file] [log] [blame]
package org.apache.maven.surefire.testng;
/*
* 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.
*/
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.surefire.report.ReporterManager;
import org.apache.maven.surefire.suite.SurefireTestSuite;
import org.apache.maven.surefire.testng.conf.Configurator;
import org.apache.maven.surefire.testng.conf.TestNG4751Configurator;
import org.apache.maven.surefire.testng.conf.TestNG52Configurator;
import org.apache.maven.surefire.testng.conf.TestNGMapConfigurator;
import org.apache.maven.surefire.testset.TestSetFailedException;
import org.testng.IReporter;
import org.testng.TestNG;
/**
* Contains utility methods for executing TestNG.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
*/
public class TestNGExecutor
{
private TestNGExecutor()
{
}
public static void run( Class[] testClasses, String testSourceDirectory, Map options, ArtifactVersion version,
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 );
testng.setTestClasses( testClasses );
testng.run();
}
public static void run( List suiteFiles, String testSourceDirectory, Map options, ArtifactVersion version,
String classifier, ReporterManager reportManager, SurefireTestSuite suite, File reportsDirectory )
throws TestSetFailedException
{
TestNG testng = new TestNG( false );
Configurator configurator = getConfigurator( version );
configurator.configure( testng, options );
postConfigure( testng, testSourceDirectory, (String) options.get("listener"), classifier, reportManager, suite, reportsDirectory );
testng.setTestSuites( suiteFiles );
testng.run();
}
private static Configurator getConfigurator( ArtifactVersion version ) throws TestSetFailedException
{
try
{
VersionRange range = VersionRange.createFromVersionSpec( "[4.7,5.1]" );
if ( range.containsVersion( version ) )
{
return new TestNG4751Configurator();
}
range = VersionRange.createFromVersionSpec( "[5.2]" );
if ( range.containsVersion( version ) )
{
return new TestNG52Configurator();
}
range = VersionRange.createFromVersionSpec( "[5.3,)" );
if ( range.containsVersion( version ) )
{
return new TestNGMapConfigurator();
}
throw new TestSetFailedException( "Unknown TestNG version " + version );
}
catch ( InvalidVersionSpecificationException invsex )
{
throw new TestSetFailedException( "Bug in plugin. Please report it with the attached stacktrace", invsex );
}
}
private static void postConfigure( TestNG testNG, String sourcePath, String listenerClasses,
String classifier, ReporterManager reportManager, SurefireTestSuite suite, File reportsDirectory )
throws TestSetFailedException
{
// turn off all TestNG output
testNG.setVerbose( 0 );
TestNGReporter reporter = createTestNGReporter( reportManager, suite );
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 )
{
testNG.setSourcePath( sourcePath );
}
testNG.setOutputDirectory( reportsDirectory.getAbsolutePath() );
}
// If we have access to IResultListener, return a ConfigurationAwareTestNGReporter
// But don't cause NoClassDefFoundErrors if it isn't available; just return a regular TestNGReporter instead
private static TestNGReporter createTestNGReporter( ReporterManager reportManager, SurefireTestSuite suite ) {
try {
Class.forName( "org.testng.internal.IResultListener" );
Class c = Class.forName( "org.apache.maven.surefire.testng.ConfigurationAwareTestNGReporter" );
try
{
Constructor ctor = c.getConstructor( new Class[] { ReporterManager.class, SurefireTestSuite.class } );
return (TestNGReporter) ctor.newInstance( new Object[] { reportManager, suite } );
}
catch ( Exception e )
{
throw new RuntimeException("Bug in ConfigurationAwareTestNGReporter", e);
}
} catch (ClassNotFoundException e) {
return new TestNGReporter( reportManager, suite );
}
}
private static List loadListenerClasses(String listenerClasses) throws TestSetFailedException
{
if (listenerClasses == null || "".equals(listenerClasses.trim())) {
return Collections.emptyList();
}
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 )
{
try
{
Class c = Class.forName( className );
if (IReporter.class.isAssignableFrom( c )) {
testNG.addListener( c.newInstance() );
}
}
catch ( Exception e ) {} // ignore
}
}