anandhu
anandhu

Reputation: 780

Why does @AfterSuit doesnt run without alwaysRun=true?

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

Answers (3)

Rodrigo Vaamonde
Rodrigo Vaamonde

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

anandhu
anandhu

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

Sameera De Silva
Sameera De Silva

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

Related Questions