Skip to content

Commit 32cee0a

Browse files
committed
Restore DependsOnGroups functionality
Closes testng-team#2664
1 parent 839e823 commit 32cee0a

15 files changed

+223
-9
lines changed

CHANGES.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Current
2+
Fixed: GITHUB-2664: Order for DependsOnGroups has changed after TestNg 7.4.0 (Krishnan Mahadevan)
23
Fixed: GITHUB-2501: TestNG 7.4.0 throws an exception "sun.net.www.protocol.file.FileURLConnection cannot be cast to java.net.HttpURLConnection" when xml file contain "ENTITY SYSTEM" grammer (Krishnan Mahadevan)
34
Fixed: GITHUB-2693: TestNG ignores 'dataproviderthreadcount' CLA (Krishnan Mahadevan)
45
Fixed: GITHUB-2685: TestInvoker should clear Thread.interrupted flag before calling ITestListeners (Roman Morskyi)

testng-core/src/main/java/org/testng/internal/MethodHelper.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,10 @@ private static Graph<ITestNGMethod> topologicalSort(
289289
}
290290
predecessors.addAll(Arrays.asList(methodsNamed));
291291
}
292-
if (XmlTest.isGroupBasedExecution(xmlTest)) {
292+
boolean anyConfigExceptGroupConfigs =
293+
!(m.isBeforeGroupsConfiguration() || m.isAfterGroupsConfiguration());
294+
boolean isGroupAgnosticConfigMethod = !m.isTest() && anyConfigExceptGroupConfigs;
295+
if (isGroupAgnosticConfigMethod) {
293296
String[] groupsDependedUpon = m.getGroupsDependedUpon();
294297
if (groupsDependedUpon.length > 0) {
295298
for (String group : groupsDependedUpon) {

testng-core/src/main/java/org/testng/internal/MethodInheritance.java

+20-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.testng.ITestNGMethod;
1111
import org.testng.collections.Lists;
1212
import org.testng.collections.Maps;
13-
import org.testng.xml.XmlTest;
1413

1514
public class MethodInheritance {
1615

@@ -135,12 +134,17 @@ public static void fixMethodInheritance(ITestNGMethod[] methods, boolean before)
135134
ITestNGMethod m1 = l.get(i);
136135
for (int j = i + 1; j < l.size(); j++) {
137136
ITestNGMethod m2 = l.get(j);
138-
boolean groupMode = XmlTest.isGroupBasedExecution(m2.getXmlTest());
139-
if (groupMode) {
140-
// Do not resort to adding implicit depends-on if there are groups
141-
continue;
142-
}
143-
if (!equalsEffectiveClass(m1, m2) && !dependencyExists(m1, m2, methods)) {
137+
boolean notEffectivelyEqual = !equalsEffectiveClass(m1, m2);
138+
boolean upstreamHierarchy = hasUpstreamHierarchy(m1, m2);
139+
boolean shouldConsider =
140+
before ? notEffectivelyEqual && upstreamHierarchy : notEffectivelyEqual;
141+
boolean hasGroupDependencies =
142+
m2.getGroupsDependedUpon().length == 0
143+
&& m1.getGroupsDependedUpon().length == 0;
144+
145+
if (shouldConsider
146+
&& !dependencyExists(m1, m2, methods)
147+
&& hasGroupDependencies) {
144148
Utils.log("MethodInheritance", 4, m2 + " DEPENDS ON " + m1);
145149
m2.addMethodDependedUpon(MethodHelper.calculateMethodCanonicalName(m1));
146150
}
@@ -149,6 +153,15 @@ public static void fixMethodInheritance(ITestNGMethod[] methods, boolean before)
149153
});
150154
}
151155

156+
private static boolean hasUpstreamHierarchy(ITestNGMethod m1, ITestNGMethod m2) {
157+
Class<?> c1 = m1.getRealClass();
158+
Class<?> c2 = m2.getRealClass();
159+
if (c1.equals(c2)) {
160+
return false;
161+
}
162+
return c1.isAssignableFrom(c2);
163+
}
164+
152165
private static boolean dependencyExists(
153166
ITestNGMethod m1, ITestNGMethod m2, ITestNGMethod[] methods) {
154167
return internalDependencyExists(m1, m2, methods) || internalDependencyExists(m2, m1, methods);

testng-core/src/test/java/test/configuration/ConfigurationGroupsTest.java

+24
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44

5+
import java.util.Collections;
56
import org.testng.TestNG;
67
import org.testng.annotations.DataProvider;
78
import org.testng.annotations.Test;
89
import test.SimpleBaseTest;
10+
import test.configuration.issue2664.MethodInvocationListener;
911

1012
public class ConfigurationGroupsTest extends SimpleBaseTest {
1113

@@ -37,4 +39,26 @@ public Object[][] getTestData() {
3739
{ConfigurationGroups7SampleTest.class, "A"}
3840
};
3941
}
42+
43+
@Test(description = "GITHUB-2664", dataProvider = "getTestClasses")
44+
public void ensureDependsOnGroupsHonouredForConfigs(Class<?> clazz) {
45+
MethodInvocationListener.logs.clear();
46+
TestNG testng = create(clazz);
47+
testng.setVerbose(2);
48+
testng.setListenerClasses(Collections.singletonList(MethodInvocationListener.class));
49+
testng.run();
50+
assertThat(MethodInvocationListener.logs).containsExactly("s3", "s1", "s2", "test3");
51+
}
52+
53+
@DataProvider(name = "getTestClasses")
54+
public Object[][] getTestClasses() {
55+
return new Object[][] {
56+
{test.configuration.issue2664.suite.GroupDependenciesSample.class},
57+
{test.configuration.issue2664.suite.GroupDependenciesChildSample.class},
58+
{test.configuration.issue2664.test.GroupDependenciesSample.class},
59+
{test.configuration.issue2664.test.GroupDependenciesChildSample.class},
60+
{test.configuration.issue2664.cls.GroupDependenciesSample.class},
61+
{test.configuration.issue2664.cls.GroupDependenciesChildSample.class},
62+
};
63+
}
4064
}

testng-core/src/test/java/test/configuration/issue2432/IssueTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public void ensureNoImplicitDependencyIsAddedWhenGroupsAreInvolved() {
3434
List<String> expected =
3535
Arrays.asList(
3636
"prepareConfig",
37+
"prepareConfigForTest1",
3738
"uploadConfigToDatabase",
3839
"verifyConfigurationAfterInstall",
39-
"prepareConfigForTest1",
4040
"test1");
4141
assertThat(listener.getInvokedMethodNames()).containsExactlyElementsOf(expected);
4242
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test.configuration.issue2664;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import org.testng.IInvokedMethod;
6+
import org.testng.IInvokedMethodListener;
7+
import org.testng.ITestResult;
8+
9+
public class MethodInvocationListener implements IInvokedMethodListener {
10+
11+
public static final List<String> logs = new ArrayList<>();
12+
13+
@Override
14+
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
15+
logs.add(method.getTestMethod().getMethodName());
16+
}
17+
18+
@Override
19+
public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package test.configuration.issue2664.cls;
2+
3+
import org.testng.annotations.BeforeClass;
4+
5+
public class GroupDependenciesBaseClass {
6+
@BeforeClass(groups = {"g1"})
7+
public void s3() {}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test.configuration.issue2664.cls;
2+
3+
import org.testng.annotations.BeforeClass;
4+
import org.testng.annotations.Test;
5+
6+
public class GroupDependenciesChildSample extends GroupDependenciesBaseClass {
7+
8+
@BeforeClass(
9+
groups = {"g2"},
10+
dependsOnGroups = "g1")
11+
public void s2() {}
12+
13+
@BeforeClass(
14+
groups = {"g2"},
15+
dependsOnGroups = "g1")
16+
public void s1() {}
17+
18+
@Test()
19+
public void test3() {}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package test.configuration.issue2664.cls;
2+
3+
import org.testng.annotations.BeforeClass;
4+
import org.testng.annotations.Test;
5+
6+
public class GroupDependenciesSample {
7+
8+
@BeforeClass(groups = {"g1"})
9+
public void s3() {}
10+
11+
@BeforeClass(
12+
groups = {"g2"},
13+
dependsOnGroups = "g1")
14+
public void s2() {}
15+
16+
@BeforeClass(
17+
groups = {"g2"},
18+
dependsOnGroups = "g1")
19+
public void s1() {}
20+
21+
@Test()
22+
public void test3() {}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package test.configuration.issue2664.suite;
2+
3+
import org.testng.annotations.BeforeSuite;
4+
5+
public class GroupDependenciesBaseClass {
6+
@BeforeSuite(groups = {"g1"})
7+
public void s3() {}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test.configuration.issue2664.suite;
2+
3+
import org.testng.annotations.BeforeSuite;
4+
import org.testng.annotations.Test;
5+
6+
public class GroupDependenciesChildSample extends GroupDependenciesBaseClass {
7+
8+
@BeforeSuite(
9+
groups = {"g2"},
10+
dependsOnGroups = "g1")
11+
public void s2() {}
12+
13+
@BeforeSuite(
14+
groups = {"g2"},
15+
dependsOnGroups = "g1")
16+
public void s1() {}
17+
18+
@Test()
19+
public void test3() {}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package test.configuration.issue2664.suite;
2+
3+
import org.testng.annotations.BeforeSuite;
4+
import org.testng.annotations.Test;
5+
6+
public class GroupDependenciesSample {
7+
8+
@BeforeSuite(groups = {"g1"})
9+
public void s3() {}
10+
11+
@BeforeSuite(
12+
groups = {"g2"},
13+
dependsOnGroups = "g1")
14+
public void s2() {}
15+
16+
@BeforeSuite(
17+
groups = {"g2"},
18+
dependsOnGroups = "g1")
19+
public void s1() {}
20+
21+
@Test()
22+
public void test3() {}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package test.configuration.issue2664.test;
2+
3+
import org.testng.annotations.BeforeTest;
4+
5+
public class GroupDependenciesBaseClass {
6+
@BeforeTest(groups = {"g1"})
7+
public void s3() {}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test.configuration.issue2664.test;
2+
3+
import org.testng.annotations.BeforeTest;
4+
import org.testng.annotations.Test;
5+
6+
public class GroupDependenciesChildSample extends GroupDependenciesBaseClass {
7+
8+
@BeforeTest(
9+
groups = {"g2"},
10+
dependsOnGroups = "g1")
11+
public void s2() {}
12+
13+
@BeforeTest(
14+
groups = {"g2"},
15+
dependsOnGroups = "g1")
16+
public void s1() {}
17+
18+
@Test()
19+
public void test3() {}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package test.configuration.issue2664.test;
2+
3+
import org.testng.annotations.BeforeTest;
4+
import org.testng.annotations.Test;
5+
6+
public class GroupDependenciesSample {
7+
8+
@BeforeTest(groups = {"g1"})
9+
public void s3() {}
10+
11+
@BeforeTest(
12+
groups = {"g2"},
13+
dependsOnGroups = "g1")
14+
public void s2() {}
15+
16+
@BeforeTest(
17+
groups = {"g2"},
18+
dependsOnGroups = "g1")
19+
public void s1() {}
20+
21+
@Test()
22+
public void test3() {}
23+
}

0 commit comments

Comments
 (0)