-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package org.testng.internal; | ||
|
||
import org.testng.ITestNGMethod; | ||
|
||
import java.util.Comparator; | ||
|
||
public class Systematiser { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a huge fan of the name but I've nothing better to propose :) |
||
|
||
private Systematiser() { | ||
//Utility class. Defeat instantiation. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The class should be final too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
} | ||
|
||
public static Comparator<Graph.Node> getComparator() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot do this because the INSTANCES one doesn't work with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't catch it because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact, this point is important IMO. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @juherr - Ok, but I would like to understand why does |
||
Comparator<Graph.Node> comparator = null; | ||
String text = System.getProperty("testng.order", Order.INSTANCES.getValue()); | ||
|
||
Order order = Order.parse(text); | ||
switch (order) { | ||
case INSTANCES: | ||
comparator = new Comparator<Graph.Node>() { | ||
@Override | ||
public int compare(Graph.Node o1, Graph.Node o2) { | ||
return o1.getObject().toString().compareTo(o2.getObject().toString()); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Instance_Names"; | ||
} | ||
}; | ||
break; | ||
|
||
case METHOD_NAMES: | ||
comparator = new Comparator<Graph.Node>() { | ||
@Override | ||
public int compare(Graph.Node o1, Graph.Node o2) { | ||
if (o1.getObject() instanceof ITestNGMethod && o2.getObject() instanceof ITestNGMethod) { | ||
String n1 = ((ITestNGMethod) o1.getObject()).getMethodName(); | ||
String n2 = ((ITestNGMethod) o1.getObject()).getMethodName(); | ||
return n1.compareTo(n2); | ||
} | ||
return o1.getObject().getClass().getName().compareTo(o2.getObject().getClass().getName()); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Method_Names"; | ||
} | ||
}; | ||
break; | ||
|
||
case NONE: | ||
default: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of null, maybe we can use a default comparator (all params are equals)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
} | ||
|
||
return comparator; | ||
} | ||
|
||
enum Order { | ||
METHOD_NAMES("methods"), | ||
INSTANCES("instances"), | ||
NONE("none"); | ||
|
||
Order(String value) { | ||
this.value = value; | ||
} | ||
|
||
private String value; | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
|
||
public static Order parse(String value) { | ||
if (value == null || value.trim().isEmpty()) { | ||
return INSTANCES; | ||
} | ||
for (Order each : values()) { | ||
if (each.getValue().equalsIgnoreCase(value)) { | ||
return each; | ||
} | ||
} | ||
return INSTANCES; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package test.github799; | ||
|
||
import org.testng.Assert; | ||
import org.testng.IInvokedMethod; | ||
import org.testng.IInvokedMethodListener; | ||
import org.testng.ITestNGListener; | ||
import org.testng.ITestResult; | ||
import org.testng.Reporter; | ||
import org.testng.TestNG; | ||
import org.testng.annotations.Test; | ||
import org.testng.collections.Lists; | ||
import test.SimpleBaseTest; | ||
|
||
import java.util.List; | ||
|
||
public class EnsureInstancesAreOrderedViaFactories extends SimpleBaseTest { | ||
|
||
@Test | ||
public void testMethod() { | ||
System.setProperty("testng.order", "none"); | ||
runTest(TestSample.class, "1", "2", "3", "4"); | ||
} | ||
|
||
@Test | ||
public void randomOrderTestMethod() { | ||
System.setProperty("testng.order", "none"); | ||
runTest(ReverseOrderTestSample.class, "4", "1", "3", "2"); | ||
} | ||
|
||
@Test | ||
public void methodsOrderTest() { | ||
System.setProperty("testng.order", "methods"); | ||
runTest(MethodsTestSample.class, "android", "angry", "birds"); | ||
} | ||
|
||
@Test | ||
public void testInstancesOrder() { | ||
System.setProperty("testng.order", "instances"); | ||
runTest(InstanceTestSample.class, "Master Oogway:90", "Master Shifu:50"); | ||
} | ||
|
||
private void runTest(Class<?> clazz, String... expected) { | ||
TestNG tng = create(clazz); | ||
OrderEavesdropper listener = new OrderEavesdropper(); | ||
tng.addListener((ITestNGListener) listener); | ||
tng.run(); | ||
|
||
for (int i = 0; i < expected.length; i++) { | ||
String actual = listener.messages.get(i); | ||
Assert.assertEquals(actual, expected[i]); | ||
} | ||
} | ||
|
||
public static class OrderEavesdropper implements IInvokedMethodListener { | ||
List<String> messages = Lists.newArrayList(); | ||
|
||
@Override | ||
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { | ||
} | ||
|
||
@Override | ||
public void afterInvocation(IInvokedMethod method, ITestResult testResult) { | ||
messages.addAll(Reporter.getOutput(testResult)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package test.github799; | ||
|
||
import org.testng.Assert; | ||
import org.testng.Reporter; | ||
import org.testng.annotations.DataProvider; | ||
import org.testng.annotations.Factory; | ||
import org.testng.annotations.Test; | ||
|
||
public class InstanceTestSample { | ||
private String name; | ||
private int age; | ||
|
||
@Factory(dataProvider = "dp") | ||
public InstanceTestSample(String name, int age) { | ||
this.name = name; | ||
this.age = age; | ||
} | ||
|
||
@DataProvider(name = "dp") | ||
public static Object[][] getData() { | ||
return new Object[][]{ | ||
{"Master Shifu", 50}, | ||
{"Master Oogway", 90} | ||
}; | ||
} | ||
|
||
@Test | ||
public void testMethod() { | ||
Reporter.log(toString()); | ||
Assert.assertNotNull(this.name); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return name + ":" + age; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package test.github799; | ||
|
||
import org.testng.Assert; | ||
import org.testng.Reporter; | ||
import org.testng.annotations.Test; | ||
|
||
public class MethodsTestSample { | ||
@Test | ||
public void angry() { | ||
String methodName = Reporter.getCurrentTestResult().getMethod().getMethodName(); | ||
Reporter.log(methodName); | ||
Assert.assertNotNull(methodName); | ||
} | ||
|
||
@Test | ||
public void birds() { | ||
String methodName = Reporter.getCurrentTestResult().getMethod().getMethodName(); | ||
Reporter.log(methodName); | ||
Assert.assertNotNull(methodName); | ||
} | ||
|
||
@Test | ||
public void android() { | ||
String methodName = Reporter.getCurrentTestResult().getMethod().getMethodName(); | ||
Reporter.log(methodName); | ||
Assert.assertNotNull(methodName); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package test.github799; | ||
|
||
import org.testng.Assert; | ||
import org.testng.Reporter; | ||
import org.testng.annotations.DataProvider; | ||
import org.testng.annotations.Factory; | ||
import org.testng.annotations.Test; | ||
|
||
public class ReverseOrderTestSample { | ||
int num; | ||
|
||
@Factory(dataProvider = "data") | ||
public ReverseOrderTestSample(int n) { | ||
num = n; | ||
} | ||
|
||
@DataProvider | ||
public static Object[][] data() { | ||
return new Object[][]{{4}, {1}, {3}, {2}}; | ||
} | ||
|
||
@Test | ||
public void test() { | ||
Reporter.log(Integer.toString(num)); | ||
Assert.assertTrue(num > 0); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package test.github799; | ||
|
||
import org.testng.Assert; | ||
import org.testng.Reporter; | ||
import org.testng.annotations.DataProvider; | ||
import org.testng.annotations.Factory; | ||
import org.testng.annotations.Test; | ||
|
||
public class TestSample { | ||
int num; | ||
|
||
@Factory(dataProvider = "data") | ||
public TestSample(int n) { | ||
num = n; | ||
} | ||
|
||
@DataProvider | ||
public static Object[][] data() { | ||
return new Object[][]{{1}, {2}, {3}, {4}}; | ||
} | ||
|
||
@Test | ||
public void test() { | ||
Reporter.log(Integer.toString(num)); | ||
Assert.assertTrue(num > 0); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -815,12 +815,19 @@ | |
<class name="test.thread.parallelization.ParallelByMethodsTestCase8Scenario1"/> | ||
</classes> | ||
</test> | ||
|
||
<!--This test depends on System properties. So its intentionally being run at the end | ||
because the toggling of the system property will affect other tests --> | ||
<test name = "RunAtLast"> | ||
<classes> | ||
<class name="test.dataprovider.issue128.DataProviderParametersMismatchTest"/> | ||
</classes> | ||
</test> | ||
|
||
<test name="RunOrderingTest"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now, we may add a programmatically way to configure the test without system properties. |
||
<classes> | ||
<class name="test.github799.EnsureInstancesAreOrderedViaFactories"/> | ||
</classes> | ||
</test> | ||
</suite> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add the
Comparator<Node<T>>
as constructor param?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didnt quite understand this observation @juherr . Can you please elaborate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comparator should be an attribute of the graph and the comparator instantiation logic should be outside.
The attribute description will be:
private final Comparator<Node<T>> comparator
and its usage will beCollections.sort(nodes2, comparator)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I understood. But why would the
comparator
instantiation be plugged into aGraph
instance from outside ? Thecomparator
instantiation is completely dependent on just a JVM argument and as such I thought we can have it just query the comparator on an On-Demand basis fromSystematiser
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JVM argument is just a quick workaround which should not be used in the core.
I don't like it because it is a global variable which is bad by definition.
That's why I think we should manage the feature from a global point of view but offer JVM arg to the users in order to keep API in the same state.
At the same time, if the integration of the feature modifies all the structure, we may use some temporary tricks and think about the core redesign later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I have looked at, if one were to be resorting to make this available via a configuration instead of a JVM argument, this is going to require quite a few changes. Also if you look at it, a configuration would still be applicable at the entire TestNG instance level, which is kind of what the JVM argument is doing as well. Does that add a bit of clarity to your question ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try to have a deeper look asap.