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

#2734 keep the initial order of listeners #2737

Merged
merged 3 commits into from Mar 16, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.txt
Expand Up @@ -5,6 +5,7 @@ Fixed: assertEqualsNoOrder for Collection and Iterators size check was missing (
Fixed: GITHUB-2709: Testnames not working together with suites in suite (Martin Aldrin)
Fixed: GITHUB-2704: IHookable and IConfigurable callback discrepancy (Krishnan Mahadevan)
Fixed: GITHUB-2637: Upgrade to JDK11 as the minimum JDK requirements (Krishnan Mahadevan)
Fixed: GITHUB-2734: Keep the initial order of listeners (Andrei Solntsev)

7.5
Fixed: GITHUB-2701: Bump gradle version to 7.3.3 to support java17 build (ZhangJian He)
Expand Down
2 changes: 1 addition & 1 deletion testng-core/src/main/java/org/testng/TestRunner.java
Expand Up @@ -345,7 +345,7 @@ private void initListeners() {
// Find all the listener factories and collect all the listeners requested in a
// @Listeners annotation.
//
Set<Class<? extends ITestNGListener>> listenerClasses = Sets.newHashSet();
Set<Class<? extends ITestNGListener>> listenerClasses = Sets.newLinkedHashSet();
Class<? extends ITestNGListenerFactory> listenerFactoryClass = null;

for (IClass cls : getTestClasses()) {
Expand Down
94 changes: 94 additions & 0 deletions testng-core/src/test/java/org/testng/TestRunnerTest.java
@@ -0,0 +1,94 @@
package org.testng;

import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.stream.Collectors;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.testng.internal.Configuration;
import org.testng.internal.IConfiguration;
import org.testng.internal.objects.DefaultTestObjectFactory;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

public class TestRunnerTest {
@Test
public void listenersShouldBeAppliedInDeclarationOrder_one() {
TestRunner testRunner = createTestRunner(TestWithOneListener.class);

List<IConfigurationListener> configurationListeners = testRunner.getConfigurationListeners();

assertThat(classesOf(configurationListeners, 1)).containsExactly(FooListener.class);
}

@Test
public void listenersShouldBeAppliedInDeclarationOrder_two() {
TestRunner testRunner = createTestRunner(TestWithTwoListeners.class);

List<IConfigurationListener> configurationListeners = testRunner.getConfigurationListeners();

assertThat(classesOf(configurationListeners, 2))
.containsExactly(FooListener.class, BarListener.class);
}

@Test
public void listenersShouldBeAppliedInDeclarationOrder_three() {
TestRunner testRunner = createTestRunner(TestWithThreeListeners.class);

List<IConfigurationListener> configurationListeners = testRunner.getConfigurationListeners();

assertThat(classesOf(configurationListeners, 3))
.containsExactly(FooListener.class, BarListener.class, ZooListener.class);
}

@Listeners(FooListener.class)
public static class TestWithOneListener {
@Test
public void some() {}
}

@Listeners({FooListener.class, BarListener.class})
public static class TestWithTwoListeners {
@BeforeMethod
public void setup() {}

@Test
public void some() {}
}

@Listeners({FooListener.class, BarListener.class, ZooListener.class})
public static class TestWithThreeListeners {
@Test
public void some() {}
}

public static class FooListener implements IConfigurationListener {}

public static class BarListener implements IConfigurationListener {}

public static class ZooListener implements IConfigurationListener {}

private <T> List<Class<?>> classesOf(List<T> values, int limit) {
return values.stream().limit(limit).map(Object::getClass).collect(Collectors.toList());
}

private TestRunner createTestRunner(Class<?> testClass) {
IConfiguration configuration = new Configuration();
configuration.setObjectFactory(new DefaultTestObjectFactory());
XmlSuite xmlSuite = new XmlSuite();
XmlTest xmlTest = new XmlTest(xmlSuite);
xmlSuite.addTest(xmlTest);
XmlClass xmlClass = new XmlClass(testClass.getName());
xmlTest.getXmlClasses().add(xmlClass);
String outputDir = "build/reports/tests/test";
ITestRunnerFactory factory =
(suite, test, listeners, classListeners) ->
new TestRunner(configuration, suite, test, false, listeners, classListeners);
ISuite suite = new SuiteRunner(configuration, xmlSuite, outputDir, factory, (o1, o2) -> 0);
return factory.newTestRunner(suite, xmlTest, emptyList(), emptyList());
}
}
6 changes: 6 additions & 0 deletions testng-core/src/test/resources/testng.xml
Expand Up @@ -927,6 +927,12 @@
</classes>
</test>

<test name="TestRunner_unit_tests">
<classes>
<class name="org.testng.TestRunnerTest"/>
</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">
Expand Down