Reputation: 780
I have the below @AfterSuit
method. If I remove alwaysRun=true, TestNG is not executing it.
@AfterSuite(alwaysRun=true)
public void finishsuit()
{
System.out.println("completed suit");
}
I checked the documentation for alwaysRun and it says:
For after methods (afterSuite, afterClass, ...): If set to true, this configuration method will be run even if one or more methods invoked previously failed or was skipped.
This is what i understood : If any of the @Test
method defined inside any of the classes specified in any of the <test>
belonging to the current suit fails, then @AfterSuit
wont be executed unless we specify alwaysRun=true
.
But in my case none of the @Test
are failing. And still my @AfterSuite
is not executing without alwaysRun=true
Upvotes: 2
Views: 2671
Reputation: 503
You are probably running your test methods in groups and AfterSuite is not part of any group, that's why you need the alwaysRun=true
.
But because I see you are a little bit confused about alwaysRun behavior, I'll proceed to explain...
For @BeforeXXXX methods, alwaysRun needs to be assigned if you want to run the method despite it doesn't belong to the group you are running. Eg.
public class TestConfig {
@BeforeSuite
public void beforeSuite() {
doSomething();
}
}
public class TestClassA extends TestConfig {
@Test(groups = { "groupA" })
public void testA() {
doTest();
}
}
In this case, if we run group 'groupA', the @BeforeSuite method is not part of the group we are executing, unless we specify alwaysRun = true
.
The same applies for @AfterXXXX methods, plus they need alwaysRun=true if you want to run them despite their @Before counterpart has failed or any depending methods. For example:
public class TestClassA {
@BeforeSuite( groups = { "testA" })
public void beforeSuite() {
doSomethingBefore();
throw new RuntimeException();
}
@Test( groups = { "testA" })
public void testA() {
doTest();
}
@AfterSuite( groups = { "testA" })
public void afterSuite() {
doSomethingAfter();
}
}
Now, @AfterSuite method won't run because it's counterpart @BeforeSuite has failed. the same will apply if @AfterSuite is on a class where a @BeforeClass had failed. But if we add alwaysRun=true
testng will ignore any previous failure and proceed anyway.
NONE OF THIS APPLIES TO @TEST METHODS. @BeforeXXXX and @AfterXXXX methods will run ignoring any @Test results UNLESS you specify a test dependency.
Finally, alwaysRun in @Test methods will act in similar way as ignoreMissingDependencies=true
. For example:
@Test
public void testA() {
doTestA();
}
@Test(dependsOnMethods = { testA }))
public void testB() {
doTestB();
}
Again, in this case testB won't run because it depends on @TestA, unless we assign alwaysRun=true (or ignoreMissingDependencies=true).
Upvotes: 5
Reputation: 780
For after methods (afterSuite, afterClass, ...): If set to true, this configuration method will be run even if one or more methods invoked previously failed or was skipped.
Methods here means all the @test methods and the all the other annotated methods aswell. in my case i was using invalid arguments to my @AfterTest function, causing it to fail. That was why my @BeforeTest was not working without alwaysRun
Upvotes: 0
Reputation: 1980
If you run it as a TestNG class, only @BeforeSuite method get picked even though @AfterSuite(alwaysRun=true) However if you run it as a Testsuite via testplan.xml ,@AfterSuite method get picked directly and no need to have alwaysRun=true
Both BeforeSuite and AfterSuite, are work in optimal way if you run it as a test suite via xml rather than run it directly as a TestNG class. Since those are meant to be suite level annotations
Example - If I run below code as a class , the output will don't have the afterSuite method.
public class TestngExamples {
@BeforeSuite
public void initation() {
System.out.println("Before suite is ran ");
}
@Test
public void hello() {
System.out.println("Hello world method");
}
@Test
public void demo() {
System.out.println("demo method");
}
@AfterSuite
public void tearDown() {
System.out.println("After suite is ran ");
}
}
However If I run it as a Test suite xml it will print the Aftersuite method
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<classes>
<class name="com.webdriver.blogs.TestngExamples"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Sample output- Before suite is ran demo method Hello world method After suite is ran
Upvotes: 0