Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@Factory with dataProvider changes order of iterations #1467

Merged
merged 4 commits into from
Jul 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Current
Fixed: GITHUB-799: @Factory with dataProvider changes order of iterations (Krishnan Mahadevan & Julien Herr)
New: Enhance XML Reporter to be able to customize the file name (Krishnan Mahadevan)
Fixed: GITHUB-1417: Class param injection is not working with @BeforeClass (Krishnan Mahadevan)
Fixed: GITHUB-1440: Improve error message when wrong params on configuration methods (Krishnan Mahadevan)
Expand Down
70 changes: 59 additions & 11 deletions src/main/java/org/testng/SuiteRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.testng.internal.Attributes;
import org.testng.internal.IConfiguration;
import org.testng.internal.IInvoker;
import org.testng.internal.Systematiser;
import org.testng.internal.Utils;
import org.testng.internal.annotations.IAnnotationFinder;
import org.testng.internal.thread.ThreadUtil;
Expand Down Expand Up @@ -78,14 +79,40 @@ public class SuiteRunner implements ISuite, Serializable, IInvokedMethodListener
private SuiteRunState suiteState = new SuiteRunState();
private IAttributes attributes = new Attributes();

public SuiteRunner(IConfiguration configuration, XmlSuite suite, String outputDir,
Comparator<ITestNGMethod> comparator) {
this(configuration, suite, outputDir, null, comparator);
}

public SuiteRunner(IConfiguration configuration, XmlSuite suite, String outputDir,
ITestRunnerFactory runnerFactory, Comparator<ITestNGMethod> comparator) {
this(configuration, suite, outputDir, runnerFactory, false, comparator);
}

public SuiteRunner(IConfiguration configuration,
XmlSuite suite,
String outputDir,
ITestRunnerFactory runnerFactory,
boolean useDefaultListeners, Comparator<ITestNGMethod> comparator)
{
this(configuration, suite, outputDir, runnerFactory, useDefaultListeners,
new ArrayList<IMethodInterceptor>() /* method interceptor */,
null /* invoked method listeners */,
null /* test listeners */,
null /* class listeners */, comparator);
}

@Deprecated
public SuiteRunner(IConfiguration configuration, XmlSuite suite, String outputDir) {
this(configuration, suite, outputDir, null);
this(configuration, suite, outputDir, (ITestRunnerFactory) null);
}

@Deprecated
public SuiteRunner(IConfiguration configuration, XmlSuite suite, String outputDir, ITestRunnerFactory runnerFactory) {
this(configuration, suite, outputDir, runnerFactory, false);
}

@Deprecated
public SuiteRunner(IConfiguration configuration,
XmlSuite suite,
String outputDir,
Expand All @@ -96,7 +123,7 @@ public SuiteRunner(IConfiguration configuration,
new ArrayList<IMethodInterceptor>() /* method interceptor */,
null /* invoked method listeners */,
null /* test listeners */,
null /* class listeners */);
null /* class listeners */, Systematiser.getComparator());
}

/**
Expand All @@ -115,9 +142,12 @@ protected SuiteRunner(IConfiguration configuration,
List<ITestListener> testListeners,
List<IClassListener> classListeners)
{
init(configuration, suite, outputDir, runnerFactory, useDefaultListeners, methodInterceptors, invokedMethodListeners, testListeners, classListeners);
init(configuration, suite, outputDir, runnerFactory, useDefaultListeners,
methodInterceptors, invokedMethodListeners, testListeners, classListeners,
Systematiser.getComparator());
}

@Deprecated
protected SuiteRunner(IConfiguration configuration,
XmlSuite suite,
String outputDir,
Expand All @@ -128,7 +158,21 @@ protected SuiteRunner(IConfiguration configuration,
Collection<ITestListener> testListeners,
Collection<IClassListener> classListeners)
{
init(configuration, suite, outputDir, runnerFactory, useDefaultListeners, methodInterceptors, invokedMethodListeners, testListeners, classListeners);
init(configuration, suite, outputDir, runnerFactory, useDefaultListeners, methodInterceptors, invokedMethodListeners, testListeners, classListeners, Systematiser.getComparator());
}

protected SuiteRunner(IConfiguration configuration,
XmlSuite suite,
String outputDir,
ITestRunnerFactory runnerFactory,
boolean useDefaultListeners,
List<IMethodInterceptor> methodInterceptors,
Collection<IInvokedMethodListener> invokedMethodListeners,
Collection<ITestListener> testListeners,
Collection<IClassListener> classListeners, Comparator<ITestNGMethod> comparator)
{
init(configuration, suite, outputDir, runnerFactory, useDefaultListeners,
methodInterceptors, invokedMethodListeners, testListeners, classListeners, comparator);
}

private void init(IConfiguration configuration,
Expand All @@ -139,8 +183,7 @@ private void init(IConfiguration configuration,
List<IMethodInterceptor> methodInterceptors,
Collection<IInvokedMethodListener> invokedMethodListener,
Collection<ITestListener> testListeners,
Collection<IClassListener> classListeners)
{
Collection<IClassListener> classListeners, Comparator<ITestNGMethod> comparator) {
this.configuration = configuration;
xmlSuite = suite;
this.useDefaultListeners = useDefaultListeners;
Expand Down Expand Up @@ -170,7 +213,10 @@ private void init(IConfiguration configuration,
this.classListeners.put(classListener.getClass(), classListener);
}
}
this.runnerFactory = buildRunnerFactory();
if (comparator == null) {
throw new IllegalArgumentException("comparator must not be null");
}
this.runnerFactory = buildRunnerFactory(comparator);

// Order the <test> tags based on their order of appearance in testng.xml
List<XmlTest> xmlTests = xmlSuite.getTests();
Expand Down Expand Up @@ -240,13 +286,13 @@ private void setOutputDir(String outputdir) {
: null;
}

private ITestRunnerFactory buildRunnerFactory() {
private ITestRunnerFactory buildRunnerFactory(Comparator<ITestNGMethod> comparator) {
ITestRunnerFactory factory;

if (null == tmpRunnerFactory) {
factory = new DefaultTestRunnerFactory(configuration,
testListeners.toArray(new ITestListener[testListeners.size()]),
useDefaultListeners, skipFailedInvocationCounts);
useDefaultListeners, skipFailedInvocationCounts, comparator);
}
else {
factory = new ProxyTestRunnerFactory(
Expand Down Expand Up @@ -555,16 +601,18 @@ private static class DefaultTestRunnerFactory implements ITestRunnerFactory {
private boolean useDefaultListeners;
private boolean skipFailedInvocationCounts;
private IConfiguration configuration;
private final Comparator<ITestNGMethod> comparator;

public DefaultTestRunnerFactory(IConfiguration configuration,
ITestListener[] failureListeners,
boolean useDefaultListeners,
boolean skipFailedInvocationCounts)
boolean skipFailedInvocationCounts, Comparator<ITestNGMethod> comparator)
{
this.configuration = configuration;
failureGenerators = failureListeners;
this.useDefaultListeners = useDefaultListeners;
this.skipFailedInvocationCounts = skipFailedInvocationCounts;
this.comparator = comparator;
}

@Override
Expand All @@ -576,7 +624,7 @@ public TestRunner newTestRunner(ISuite suite, XmlTest test,
}
TestRunner testRunner = new TestRunner(configuration, suite, test,
suite.getOutputDirectory(), suite.getAnnotationFinder(), skip,
listeners, classListeners);
listeners, classListeners, comparator);

if (useDefaultListeners) {
testRunner.addListener(new TestHTMLReporter());
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/testng/TestNG.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.testng.internal.IResultListener2;
import org.testng.internal.OverrideProcessor;
import org.testng.internal.SuiteRunnerMap;
import org.testng.internal.Systematiser;
import org.testng.internal.Utils;
import org.testng.internal.Version;
import org.testng.internal.annotations.DefaultAnnotationTransformer;
Expand Down Expand Up @@ -1393,7 +1394,7 @@ private SuiteRunner createSuiteRunner(XmlSuite xmlSuite) {
m_methodInterceptors,
m_invokedMethodListeners.values(),
m_testListeners.values(),
m_classListeners.values());
m_classListeners.values(), Systematiser.getComparator());

for (ISuiteListener isl : m_suiteListeners.values()) {
result.addListener(isl);
Expand Down
42 changes: 36 additions & 6 deletions src/main/java/org/testng/TestRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.testng.internal.MethodInstance;
import org.testng.internal.ResultMap;
import org.testng.internal.RunInfo;
import org.testng.internal.Systematiser;
import org.testng.internal.TestMethodWorker;
import org.testng.internal.TestNGClassFinder;
import org.testng.internal.TestNGMethodFinder;
Expand Down Expand Up @@ -67,6 +68,8 @@ public class TestRunner

/* generated */
private static final long serialVersionUID = 4247820024988306670L;

private final Comparator<ITestNGMethod> comparator;
private ISuite m_suite;
private XmlTest m_xmlTest;
private String m_testName;
Expand Down Expand Up @@ -151,6 +154,7 @@ private enum PriorityWeight {
groupByInstance, preserveOrder, priority, dependsOnGroups, dependsOnMethods
}

@Deprecated
protected TestRunner(IConfiguration configuration,
ISuite suite,
XmlTest test,
Expand All @@ -160,14 +164,40 @@ protected TestRunner(IConfiguration configuration,
Collection<IInvokedMethodListener> invokedMethodListeners,
List<IClassListener> classListeners)
{
this.comparator = Systematiser.getComparator();
init(configuration, suite, test, outputDirectory, finder, skipFailedInvocationCounts,
invokedMethodListeners, classListeners);
}

@Deprecated
public TestRunner(IConfiguration configuration, ISuite suite, XmlTest test,
boolean skipFailedInvocationCounts,
Collection<IInvokedMethodListener> invokedMethodListeners,
List<IClassListener> classListeners) {
this.comparator = Systematiser.getComparator();
init(configuration, suite, test, suite.getOutputDirectory(),
suite.getAnnotationFinder(),
skipFailedInvocationCounts, invokedMethodListeners, classListeners);
}

protected TestRunner(IConfiguration configuration,
ISuite suite,
XmlTest test,
String outputDirectory,
IAnnotationFinder finder,
boolean skipFailedInvocationCounts,
Collection<IInvokedMethodListener> invokedMethodListeners,
List<IClassListener> classListeners, Comparator<ITestNGMethod> comparator) {
this.comparator = comparator;
init(configuration, suite, test, outputDirectory, finder, skipFailedInvocationCounts,
invokedMethodListeners, classListeners);
}

public TestRunner(IConfiguration configuration, ISuite suite, XmlTest test,
boolean skipFailedInvocationCounts,
Collection<IInvokedMethodListener> invokedMethodListeners,
List<IClassListener> classListeners, Comparator<ITestNGMethod> comparator) {
this.comparator = comparator;
init(configuration, suite, test, suite.getOutputDirectory(),
suite.getAnnotationFinder(),
skipFailedInvocationCounts, invokedMethodListeners, classListeners);
Expand Down Expand Up @@ -405,7 +435,7 @@ private void initMethods() {
m_configuration,
this);
ITestMethodFinder testMethodFinder
= new TestNGMethodFinder(m_runInfo, m_annotationFinder);
= new TestNGMethodFinder(m_runInfo, m_annotationFinder, comparator);

m_runInfo.setTestMethods(testMethods);

Expand Down Expand Up @@ -462,36 +492,36 @@ private void initMethods() {
m_runInfo,
m_annotationFinder,
true /* unique */,
m_excludedMethods);
m_excludedMethods, comparator);

m_beforeXmlTestMethods = MethodHelper.collectAndOrderMethods(beforeXmlTestMethods,
false /* forTests */,
m_runInfo,
m_annotationFinder,
true /* unique (CQ added by me)*/,
m_excludedMethods);
m_excludedMethods, comparator);

m_allTestMethods = MethodHelper.collectAndOrderMethods(testMethods,
true /* forTest? */,
m_runInfo,
m_annotationFinder,
false /* unique */,
m_excludedMethods);
m_excludedMethods, comparator);
m_classMethodMap = new ClassMethodMap(testMethods, m_xmlMethodSelector);

m_afterXmlTestMethods = MethodHelper.collectAndOrderMethods(afterXmlTestMethods,
false /* forTests */,
m_runInfo,
m_annotationFinder,
true /* unique (CQ added by me)*/,
m_excludedMethods);
m_excludedMethods, comparator);

m_afterSuiteMethods = MethodHelper.collectAndOrderMethods(afterSuiteMethods,
false /* forTests */,
m_runInfo,
m_annotationFinder,
true /* unique */,
m_excludedMethods);
m_excludedMethods, comparator);
// shared group methods
m_groupMethods = new ConfigurationGroupMethods(m_allTestMethods, beforeGroupMethods, afterGroupMethods);

Expand Down
20 changes: 11 additions & 9 deletions src/main/java/org/testng/internal/Graph.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
Expand All @@ -21,12 +22,17 @@ public class Graph<T> {
private static boolean m_verbose = false;
private Map<T, Node<T>> m_nodes = Maps.newLinkedHashMap();
private List<T> m_strictlySortedNodes = null;
private final Comparator<Node<T>> comparator;

// A map of nodes that are not the predecessors of any node
// (not needed for the algorithm but convenient to calculate
// the parallel/sequential lists in TestNG).
private Map<T, Node<T>> m_independentNodes = null;

public Graph(Comparator<Node<T>> comparator) {
this.comparator = comparator;
}

public void addNode(T tm) {
ppp("ADDING NODE " + tm + " " + tm.hashCode());
m_nodes.put(tm, new Node<>(tm));
Expand Down Expand Up @@ -121,7 +127,7 @@ public void topologicalSort() {
// Sort the nodes alphabetically to make sure that methods of the same class
// get run close to each other as much as possible
//
Collections.sort(nodes2);
Collections.sort(nodes2, comparator);

//
// Sort
Expand Down Expand Up @@ -158,9 +164,9 @@ private void initializeIndependentNodes() {
if (null == m_independentNodes) {
List<Node<T>> list = Lists.newArrayList(m_nodes.values());
// Ideally, we should not have to sort this. However, due to a bug where it treats all the methods as
// dependent nodes. Therefore, all the nodes were mostly sorted alphabetically. So we need to keep
// the behavior for now.
Collections.sort(list);
// dependent nodes.
Collections.sort(list, comparator);

m_independentNodes = Maps.newLinkedHashMap();
for (Node<T> node : list) {
m_independentNodes.put(node.getObject(), node);
Expand Down Expand Up @@ -255,7 +261,7 @@ public String toString() {
/////
// class Node
//
public static class Node<T> implements Comparable<Node<T>> {
public static class Node<T> {
private T m_object = null;
private Map<T, T> m_predecessors = Maps.newHashMap();

Expand Down Expand Up @@ -335,9 +341,5 @@ public boolean hasPredecessor(T m) {
return m_predecessors.containsKey(m);
}

@Override
public int compareTo(Node<T> o) {
return getObject().toString().compareTo(o.getObject().toString());
}
}
}
Loading