From 8630a7e8fe12985d71c00212f9362fd38fb0cb9e Mon Sep 17 00:00:00 2001 From: Krishnan Mahadevan Date: Sat, 3 Dec 2022 22:23:15 +0530 Subject: [PATCH] Ensure ITestContext available for JUnit4 tests Closes #2792 --- CHANGES.txt | 1 + .../org/testng/junit/JUnit4TestRunner.java | 6 +++- .../org/testng/junit/JUnitTestRunner.java | 11 +++++-- .../src/test/java/test/JUnit4Test.java | 17 ++++++++++ .../junit4/issue2792/TestClassSample.java | 9 ++++++ .../TestContextGatheringListener.java | 31 +++++++++++++++++++ 6 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 testng-core/src/test/java/test/junit4/issue2792/TestClassSample.java create mode 100644 testng-core/src/test/java/test/junit4/issue2792/TestContextGatheringListener.java diff --git a/CHANGES.txt b/CHANGES.txt index 55e8d0347d..18fa6fbbb0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ Current +Fixed: GITHUB-2792: JUnitTestClass sets XmlTest as null when running JUnit 4 Tests using TestNG (Krishnan Mahadevan) Fixed: GITHUB-2844: Deprecate support for running Spock Tests (Krishnan Mahadevan) Fixed: GITHUB-550: Weird @BeforeMethod and @AfterMethod behaviour with dependsOnMethods (Krishnan Mahadevan) Fixed: GITHUB-893: TestNG should provide an Api which allow to find all dependent of a specific test (Krishnan Mahadevan) diff --git a/testng-core/src/main/java/org/testng/junit/JUnit4TestRunner.java b/testng-core/src/main/java/org/testng/junit/JUnit4TestRunner.java index 32688bbf2d..86ca94331b 100644 --- a/testng-core/src/main/java/org/testng/junit/JUnit4TestRunner.java +++ b/testng-core/src/main/java/org/testng/junit/JUnit4TestRunner.java @@ -231,7 +231,11 @@ private ITestResult createTestResult(ITestObjectFactory objectFactory, Descripti JUnit4TestClass tc = new JUnit4TestClass(test); JUnitTestMethod tm = new JUnit4TestMethod(objectFactory, tc, test); - TestResult tr = TestResult.newTestResultFor(tm); + ITestContext ctx = null; + if (m_parentRunner instanceof ITestContext) { + ctx = (ITestContext) m_parentRunner; + } + TestResult tr = TestResult.newContextAwareTestResult(tm, ctx); InvokedMethod im = new InvokedMethod(tr.getStartMillis(), tr); if (tr.getMethod() instanceof IInvocationStatus) { diff --git a/testng-core/src/main/java/org/testng/junit/JUnitTestRunner.java b/testng-core/src/main/java/org/testng/junit/JUnitTestRunner.java index 7ec4d2d5a4..42002a2309 100644 --- a/testng-core/src/main/java/org/testng/junit/JUnitTestRunner.java +++ b/testng-core/src/main/java/org/testng/junit/JUnitTestRunner.java @@ -27,8 +27,8 @@ public class JUnitTestRunner implements TestListener, IJUnitTestRunner { private final ITestObjectFactory m_objectFactory; private final ITestResultNotifier m_parentRunner; - private Map m_tests = new WeakHashMap<>(); - private List m_methods = Lists.newArrayList(); + private final Map m_tests = new WeakHashMap<>(); + private final List m_methods = Lists.newArrayList(); private Collection m_invokedMethodListeners = Lists.newArrayList(); public JUnitTestRunner(ITestObjectFactory objectFactory, ITestResultNotifier tr) { @@ -102,9 +102,14 @@ private org.testng.internal.TestResult recordResults(Test test, TestRunInfo tri) JUnitTestClass tc = new JUnit3TestClass(test); JUnitTestMethod tm = new JUnit3TestMethod(m_objectFactory, tc, test); + ITestContext ctx = null; + if (m_parentRunner instanceof ITestContext) { + ctx = (ITestContext) m_parentRunner; + } + org.testng.internal.TestResult tr = org.testng.internal.TestResult.newEndTimeAwareTestResult( - tm, null, tri.m_failure, tri.m_start); + tm, ctx, tri.m_failure, tri.m_start); if (tri.isFailure()) { tr.setStatus(ITestResult.FAILURE); diff --git a/testng-core/src/test/java/test/JUnit4Test.java b/testng-core/src/test/java/test/JUnit4Test.java index 9145a76006..04724c6d69 100644 --- a/testng-core/src/test/java/test/JUnit4Test.java +++ b/testng-core/src/test/java/test/JUnit4Test.java @@ -1,9 +1,14 @@ package test; +import static org.assertj.core.api.Assertions.assertThat; + +import org.testng.TestNG; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import test.junit4.*; +import test.junit4.issue2792.TestClassSample; +import test.junit4.issue2792.TestContextGatheringListener; public class JUnit4Test extends BaseTest { @@ -72,4 +77,16 @@ public void testTests( verifyFailedTests(expectedFailedTests); verifySkippedTests(expectedSkippedTests); } + + @Test(description = "GITHUB-2792") + public void ensureTestContextAvailableForListeners() { + TestNG testng = new TestNG(); + testng.setTestClasses(new Class[] {TestClassSample.class}); + TestContextGatheringListener listener = new TestContextGatheringListener(); + testng.addListener(listener); + testng.setJUnit(true); + testng.run(); + assertThat(listener.isTestContextFoundOnTestStart()).isTrue(); + assertThat(listener.isTestContextFoundOnAfterInvocation()).isTrue(); + } } diff --git a/testng-core/src/test/java/test/junit4/issue2792/TestClassSample.java b/testng-core/src/test/java/test/junit4/issue2792/TestClassSample.java new file mode 100644 index 0000000000..d7af869d3b --- /dev/null +++ b/testng-core/src/test/java/test/junit4/issue2792/TestClassSample.java @@ -0,0 +1,9 @@ +package test.junit4.issue2792; + +import org.junit.Test; + +public class TestClassSample { + + @Test + public void testMethod() {} +} diff --git a/testng-core/src/test/java/test/junit4/issue2792/TestContextGatheringListener.java b/testng-core/src/test/java/test/junit4/issue2792/TestContextGatheringListener.java new file mode 100644 index 0000000000..0ced6a78e8 --- /dev/null +++ b/testng-core/src/test/java/test/junit4/issue2792/TestContextGatheringListener.java @@ -0,0 +1,31 @@ +package test.junit4.issue2792; + +import java.util.Objects; +import org.testng.IInvokedMethod; +import org.testng.IInvokedMethodListener; +import org.testng.ITestListener; +import org.testng.ITestResult; + +public class TestContextGatheringListener implements IInvokedMethodListener, ITestListener { + + private boolean testContextFoundOnTestStart = false; + private boolean testContextFoundOnAfterInvocation = false; + + public boolean isTestContextFoundOnAfterInvocation() { + return testContextFoundOnAfterInvocation; + } + + public boolean isTestContextFoundOnTestStart() { + return testContextFoundOnTestStart; + } + + @Override + public void afterInvocation(IInvokedMethod method, ITestResult testResult) { + testContextFoundOnAfterInvocation = Objects.nonNull(testResult.getTestContext()); + } + + @Override + public void onTestStart(ITestResult result) { + testContextFoundOnTestStart = Objects.nonNull(result.getTestContext()); + } +}