testng: BUG: Parameter alwaysRun=true for before-methods forces execution of those methods
TestNG Version
6.12, 6.11, …
Expected behavior
According to official documentation parameter ‘alwaysRun’ for before-methods is used only to enable/disable filtering by groups. It must not force method execution if higher-level configuration(s) failed. In any case alwaysRun should not be used both for filtering and for execution forcing
Actual behavior
BeforeTest/BeforeClass/BeforeMethod with (alwaysRun = true) is executed when higher - level configuration failed (BeforeSuite/BeforeTest/BeforeClass)
Is the issue reproductible on runner?
- Shell
- Maven
- Gradle
- Ant
- Eclipse
- IntelliJ
- NetBeans
Test case sample
Please, share the test case (as small as possible) which shows the issue
public class AlwaysRunTests {
@BeforeSuite
public void failedBeforeSuite() {
System.out.println("I'm beforeSuite. I should be alone in console log. Going to fail...");
throw new RuntimeException();
}
@BeforeTest(alwaysRun = true)
public void beforeTest() {
System.out.println("BUG: I'm beforeTest and I was invoked (((( ");
throw new RuntimeException();
}
@BeforeClass(alwaysRun = true)
public void beforeClass() {
System.out.println("BUG: I'm beforeClass and I was invoked (((( ");
throw new RuntimeException();
}
@BeforeMethod(alwaysRun = true)
public void beforeMethod() {
System.out.println("BUG: I'm beforeMethod and I was invoked (((( ");
throw new RuntimeException();
}
@Test
public void testMethod() {
System.out.println("I'm testMethod");
}
}
Console output (stacktraces truncated):
I'm beforeSuite. I should be alone in console log. Going to fail...
java.lang.RuntimeException
at qa.ok.testng.AlwaysRunTests.failedBeforeSuite(AlwaysRunTests.java:14)
BUG: I'm beforeTest and I was invoked ((((
java.lang.RuntimeException
at qa.ok.testng.AlwaysRunTests.beforeTest(AlwaysRunTests.java:21)
BUG: I'm beforeClass and I was invoked ((((
java.lang.RuntimeException
at qa.ok.testng.AlwaysRunTests.beforeClass(AlwaysRunTests.java:28)
BUG: I'm beforeMethod and I was invoked ((((
java.lang.RuntimeException
at qa.ok.testng.AlwaysRunTests.beforeMethod(AlwaysRunTests.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:523)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:224)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:599)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:877)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1201)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:776)
at org.testng.TestRunner.run(TestRunner.java:634)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:425)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:420)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:385)
at org.testng.SuiteRunner.run(SuiteRunner.java:334)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1318)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1243)
at org.testng.TestNG.runSuites(TestNG.java:1161)
at org.testng.TestNG.run(TestNG.java:1129)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Test ignored.
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 1
Configuration Failures: 4, Skips: 0
===============================================
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 7
- Comments: 15 (7 by maintainers)
Commits related to this issue
- Parameter alwaysRun=true for before-methods forces execution of those methods Closes #1622 — committed to krmahadevan/testng by krmahadevan 7 years ago
- Parameter alwaysRun=true for before-methods forces execution of those methods Closes #1622 — committed to krmahadevan/testng by krmahadevan 7 years ago
- Fix: alwaysRun should not force invocation of Before-methods Resolves #1622 — committed to kool79/testng by kool79 5 years ago
- Fix: alwaysRun should not force invocation of Before-methods Resolves cbeust/testng#1622 — committed to kool79/testng by kool79 5 years ago
- Fix: alwaysRun should not force invocation of Before-methods Resolves cbeust/testng#1622 — committed to kool79/testng by kool79 5 years ago
Guys, sorry but I just want to prevent breaking changes in testng, so will try to explain my opinion: Before testng v6.9.5 parameter
alwaysRunhad very different meaning in@Before-and@After-methods. Below I tried to describe behavior for that version (based on official testng documentation, javadocs and implementation):In context of
@BeforeSuite,@BeforeTest,@BeforeClass,@BeforeMethod: schedule this method for execution regardless to which group it belongs / does not belong (of cause if corresponding@Tests were scheduled) Please note: (by implementation up to 6.9.5): – method will be skipped if any parent or preceding configurations failed. – this behavior does not depend onconfig-failure-policyIn context of
@AfterSuite,@AfterTest,@AfterClass,@AfterMethod: (from javadoc and official documentation): configuration method will be run even if one or more methods invoked previously failed or was skippedIn context of
@Test: (from javadoc): run test-method even if it depends on a method that failed. This attribute ignored if test doesn’t depend on any method or group. Please note: – test-method will be skipped (will not run) if it depends on skipped methods. – test-method will be skipped in every case when any of parent configurations failed.Last note is very impotent. It means: even when if you force to execute
@BeforeMethodafter@BeforeClasswas failed , all the methods which belongs to class will be skipped. So why we need to force execution of@BeforeMethodif test ignored in any way???I think this behavior ( v6.9.5) should be saved because it was well-designed by @cbeust and it have meaning. There are no reasonable situations in testing when you should continue to execute ‘child’ prerequisites after ‘parent’ failed.
@krmahadevan, If I understand properly from PR 9d5e6d7, you want to force execution for before-methods only when
configfailurepolicy = continue. Please use SRP principle for parameters in testng. Currently (v13.1)configfailurepolicyused to avoid multiple execution of the same configuration method. (Same means: method with concrete signature which belongs to concrete instance) Please don’t use this parameter for any other purpose. This will break compatibility and will make process of testng configuration ugly.Finally: IMHO to fix current issue you should revert changes which were made in scope of #420 (328620f) - it was wrong fix. Maybe it fixed behavior in particular case but it does not fix root cause. I’m almost sure that issue #420 can be reproduced with or without
alwaysRunon@BeforeSuite@kool79 It looks you have a good knowledge of the issue. Maybe you can propose a pull request with the fix?
I’ve found this bug was introduced in testng-6.9.5 when fixing #420 Below the log for v6.9.4 (note that no other before methods were invoked except before-suite):