Skip to content

Commit 4c92177

Browse files
authored
Streamline Listener factory invocation (#3256)
Closes #3120
1 parent 1791dc5 commit 4c92177

File tree

6 files changed

+108
-8
lines changed

6 files changed

+108
-8
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Current (7.13.0)
2+
Fixed: GITHUB-3120: ITestNGListenerFactory is broken and never invoked (Krishnan Mahadevan)
23

34
7.12.0
45
Fixed: GITHUB-3231: TestNG retry is going into infinite loop when the data provider returned object is modified before failure (Bartek Florczak)

testng-core/src/main/java/org/testng/TestRunner.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import java.util.List;
1313
import java.util.Map;
1414
import java.util.Objects;
15-
import java.util.Optional;
1615
import java.util.Set;
1716
import java.util.concurrent.BlockingQueue;
1817
import java.util.concurrent.LinkedBlockingQueue;
@@ -372,19 +371,20 @@ private void initListeners() {
372371
listenerClasses.addAll(listenerHolder.getListenerClasses());
373372
}
374373

375-
if (listenerFactoryClass == null) {
376-
listenerFactoryClass = DefaultListenerFactory.class;
377-
}
378-
379374
//
380375
// Now we have all the listeners collected from @Listeners and at most one
381376
// listener factory collected from a class implementing ITestNGListenerFactory.
382377
// Instantiate all the requested listeners.
383378
//
384379

385-
ITestNGListenerFactory factory =
386-
Optional.ofNullable(m_configuration.getListenerFactory())
387-
.orElse(new DefaultListenerFactory(m_objectFactory, this));
380+
ITestNGListenerFactory factory;
381+
if (listenerFactoryClass != null) {
382+
factory = m_objectFactory.newInstance(listenerFactoryClass);
383+
} else if (m_configuration.getListenerFactory() != null) {
384+
factory = m_configuration.getListenerFactory();
385+
} else {
386+
factory = new DefaultListenerFactory(m_objectFactory, this);
387+
}
388388

389389
// Instantiate all the listeners
390390
for (Class<? extends ITestNGListener> c : listenerClasses) {

testng-core/src/test/java/test/listeners/factory/TestNGFactoryTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@
33
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
44

55
import java.util.List;
6+
import java.util.concurrent.atomic.AtomicInteger;
67
import org.testng.CommandLineArgs;
8+
import org.testng.ITestListener;
9+
import org.testng.ITestResult;
710
import org.testng.TestNG;
11+
import org.testng.annotations.DataProvider;
812
import org.testng.annotations.Test;
913
import test.SimpleBaseTest;
14+
import test.listeners.factory.issue3120.FactoryListenerTestClassCombinedSample;
15+
import test.listeners.factory.issue3120.TestClassSample;
1016

1117
public class TestNGFactoryTest extends SimpleBaseTest {
1218

@@ -38,4 +44,27 @@ public void testListenerFactoryViaTestNGApi() {
3844
assertThat(testng.getStatus()).isZero();
3945
assertThat(factory.isInvoked()).isTrue();
4046
}
47+
48+
@Test(description = "GITHUB-3120", dataProvider = "dp-3120")
49+
public void testListenerFactoryInvocationWhenCoupledAsListener(Class<?> testClass) {
50+
TestNG testng = create(testClass);
51+
AtomicInteger counter = new AtomicInteger(0);
52+
testng.addListener(
53+
new ITestListener() {
54+
@Override
55+
public void onTestFailure(ITestResult result) {
56+
counter.incrementAndGet();
57+
}
58+
});
59+
testng.run();
60+
assertThat(testng.getStatus()).isZero();
61+
assertThat(counter.get()).withFailMessage("No test should have failed").isEqualTo(0);
62+
}
63+
64+
@DataProvider(name = "dp-3120")
65+
public Object[][] dp3120() {
66+
return new Object[][] {
67+
{TestClassSample.class}, {FactoryListenerTestClassCombinedSample.class},
68+
};
69+
}
4170
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package test.listeners.factory.issue3120;
2+
3+
import org.testng.IExecutionListener;
4+
import org.testng.ITestNGListener;
5+
import org.testng.ITestNGListenerFactory;
6+
7+
public class CustomFactory implements IExecutionListener, ITestNGListenerFactory {
8+
9+
public static boolean factoryInvoked = false;
10+
public static boolean listenerInvoked = false;
11+
12+
@Override
13+
public ITestNGListener createListener(Class<? extends ITestNGListener> aClass) {
14+
factoryInvoked = true;
15+
return this;
16+
}
17+
18+
@Override
19+
public void onExecutionStart() {
20+
listenerInvoked = true;
21+
}
22+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package test.listeners.factory.issue3120;
2+
3+
import org.testng.Assert;
4+
import org.testng.IExecutionListener;
5+
import org.testng.ITestNGListener;
6+
import org.testng.ITestNGListenerFactory;
7+
import org.testng.annotations.Listeners;
8+
import org.testng.annotations.Test;
9+
10+
@Listeners(FactoryListenerTestClassCombinedSample.class)
11+
public class FactoryListenerTestClassCombinedSample
12+
implements IExecutionListener, ITestNGListenerFactory {
13+
14+
private static boolean factoryInvoked = false;
15+
private static boolean listenerInvoked = false;
16+
17+
@Override
18+
public ITestNGListener createListener(Class<? extends ITestNGListener> listenerClass) {
19+
factoryInvoked = true;
20+
return this;
21+
}
22+
23+
@Override
24+
public void onExecutionStart() {
25+
listenerInvoked = true;
26+
}
27+
28+
@Test
29+
public void sampleTestMethod() {
30+
Assert.assertTrue(factoryInvoked, "Factory should have been invoked");
31+
Assert.assertTrue(listenerInvoked, "Listener should have been invoked");
32+
}
33+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test.listeners.factory.issue3120;
2+
3+
import org.testng.Assert;
4+
import org.testng.annotations.Listeners;
5+
import org.testng.annotations.Test;
6+
7+
@Listeners(CustomFactory.class)
8+
public class TestClassSample {
9+
10+
@Test
11+
public void sampleTestMethod() {
12+
Assert.assertTrue(CustomFactory.factoryInvoked, "Factory should have been invoked");
13+
Assert.assertTrue(CustomFactory.listenerInvoked, "Listener should have been invoked");
14+
}
15+
}

0 commit comments

Comments
 (0)