From 5b43659aaf935ea11a419944b5ef73cdc22c7dad Mon Sep 17 00:00:00 2001 From: Krishnan Mahadevan Date: Sun, 4 Dec 2022 10:44:57 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20sporadic=20failure=20for=20=E2=80=9Cfirst?= =?UTF-8?q?TimeOnly=E2=80=9D=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that the listeners for “firstTimeOnly” methods are executed ONLY if the config method was run else skip listener execution as well. The test was failing because it relied on config listeners --- .../src/main/java/org/testng/ITestResult.java | 7 +++++++ .../org/testng/internal/invokers/ConfigInvoker.java | 11 ++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/testng-core-api/src/main/java/org/testng/ITestResult.java b/testng-core-api/src/main/java/org/testng/ITestResult.java index 00649a4615..86a8c2d348 100644 --- a/testng-core-api/src/main/java/org/testng/ITestResult.java +++ b/testng-core-api/src/main/java/org/testng/ITestResult.java @@ -115,6 +115,13 @@ default List getSkipCausedBy() { */ String id(); + /** + * @return true if the current method (test|configuration) was executed by TestNG. + */ + default boolean wasExecuted() { + return !isNotRunning(); + } + /** * @return - true if the current test result is either {@link ITestResult#STARTED} or * {@link ITestResult#CREATED} diff --git a/testng-core/src/main/java/org/testng/internal/invokers/ConfigInvoker.java b/testng-core/src/main/java/org/testng/internal/invokers/ConfigInvoker.java index 9ecb0a4a45..efc9a9bdb3 100644 --- a/testng-core/src/main/java/org/testng/internal/invokers/ConfigInvoker.java +++ b/testng-core/src/main/java/org/testng/internal/invokers/ConfigInvoker.java @@ -285,18 +285,23 @@ public void invokeConfigurations(ConfigMethodArguments arguments) { arguments.getTestMethodResult()); testResult.setParameters(parameters); - runConfigurationListeners(testResult, arguments.getTestMethod(), true /* before */); - Object newInstance = computeInstance(arguments.getInstance(), inst, tm); if (isConfigMethodEligibleForScrutiny(tm)) { if (m_executedConfigMethods.add(arguments.getTestMethod())) { + runConfigurationListeners(testResult, arguments.getTestMethod(), true /* before */); invokeConfigurationMethod(newInstance, tm, parameters, testResult); } } else { + runConfigurationListeners(testResult, arguments.getTestMethod(), true /* before */); invokeConfigurationMethod(newInstance, tm, parameters, testResult); } copyAttributesFromNativelyInjectedTestResult(parameters, arguments.getTestMethodResult()); - runConfigurationListeners(testResult, arguments.getTestMethod(), false /* after */); + + if (testResult.wasExecuted()) { + // When it comes to "firstTimeOnly" configurations, some of them would NOT be run + // by TestNG. For those occurrences, DONOT run the listener. + runConfigurationListeners(testResult, arguments.getTestMethod(), false /* after */); + } if (testResult.getStatus() == ITestResult.SKIP) { Throwable t = testResult.getThrowable(); if (t != null) {