order of execution of @AfterClass and @AfterTest is not correct

665 views
Skip to first unread message

kiri

unread,
Nov 10, 2010, 6:59:04 AM11/10/10
to testng-users
In below code snippet the expected order of execution is

@BeforeClass test.Base.baseBeforeClass()
@BeforeClass test.Child.childBeforeClass()
@Test test.Child.childTest
@AfterTest test.Child.childAfterTest()
@AfterClass test.Child.childAfterClass()
@AfterClass test.Base.baseAfterClass()

but execution order seems to be diferent

@BeforeClass test.Base.baseBeforeClass()
@BeforeClass test.Child.childBeforeClass()
@Test test.Child.childTest
@AfterClass test.Child.childAfterClass()
@AfterClass test.Base.baseAfterClass()
@AfterTest test.Child.childAfterTest()

also the log in eclipse is kind of confusing.

[TestRunner] Running the tests in 'classes' with parallel mode:false
[RunInfo] Adding method selector:
org.testng.internal.XmlMethodSelector@3c9217 priority: 10
[TestNGClassFinder] SKIPPING CLASS class test.Base no TestNG
annotations found
[TestClass] Creating TestClass for [ClassImpl test.Child]
[TestClass] Adding method test.Child.childTest() on TestClass class
test.Child
[XmlMethodSelector] Including method test.childBeforeTest()
[XmlMethodSelector] Including method test.baseBeforeClass()
[XmlMethodSelector] Including method test.childBeforeClass()
[MethodInheritance] test.Child.childBeforeClass() DEPENDS ON
test.Base.baseBeforeClass()
[MethodInheritance] test.Base.baseAfterClass() DEPENDS ON
test.Child.childAfterClass()
[XmlMethodSelector] Including method test.childTest()
[SuiteRunner] Created 1 TestRunners
[TestRunner] Running test classes on 1 classes, included groups:[]
excluded groups:[]
[TestClass]
======
TESTCLASS: test.Child
[TestClass] BeforeClass : test.Base.baseBeforeClass()
[TestClass] BeforeClass : test.Child.childBeforeClass()
[TestClass] Test : test.Child.childTest()
[TestClass] AfterClass : test.Child.childAfterClass()
[TestClass] AfterClass : test.Base.baseAfterClass()
[TestClass]
======

[Invoker 8728760] Invoking @BeforeTest test.Child.childBeforeTest()
[TestRunner] Found 1 applicable methods
[TestRunner] WILL BE RUN SEQUENTIALLY:
[TestRunner] WILL BE RUN IN RANDOM ORDER:
[TestRunner] test.Child.childTest()
[TestRunner] on instances
[TestRunner] test.Child@dcb03b
[TestRunner] ===
[Invoker 8728760] Invoking @BeforeClass test.Base.baseBeforeClass()
[Invoker 8728760] Invoking @BeforeClass test.Child.childBeforeClass()
[Invoker 8728760] Invoking test.Child.childTest
[Invoker 8728760] Invoking @AfterClass test.Child.childAfterClass()
[Invoker 8728760] Invoking @AfterClass test.Base.baseAfterClass()
[Invoker 8728760] Invoking @AfterTest test.Child.childAfterTest()

*********** INVOKED METHODS

test.Base.baseBeforeClass() 14463035
test.Child.childBeforeClass() 14463035
test.Child.childTest() 14463035
test.Child.childAfterClass() 14463035
test.Base.baseAfterClass() 14463035

***********

PASSED: childTest
--
import org.testng.annotations.*

public class Child extends Base
{
@BeforeClass public void childBeforeClass() { }
@BeforeTest public void childBeforeTest() { }
@Test public void childTest() { }
@AfterTest(alwaysRun = true) public void childAfterTest() { }
@AfterClass(alwaysRun = true) public void childAfterClass()
{ }
}
class Base
{
@BeforeClass void baseBeforeClass() { }
@AfterClass(alwaysRun = true) void baseAfterClass() { }
}
--

Nalin Makar

unread,
Nov 10, 2010, 12:07:32 PM11/10/10
to testng...@googlegroups.com

@AfterTest doesnt mean after test method. You should replace @AfterTest with @AfterMethod. Go though the TestNG documentation regarding these annotations.

-nalin


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.


kiri

unread,
Nov 11, 2010, 12:40:56 AM11/11/10
to testng-users
Thanks Nalin.
After changing the annotation its going fine.

On Nov 10, 10:07 pm, Nalin Makar <nalin.ma...@gmail.com> wrote:
> @AfterTest doesnt mean after test method. You should replace @AfterTest with
> @AfterMethod. Go though the TestNG documentation regarding these
> annotations.
>
> -nalin
>
> > testng-users...@googlegroups.com<testng-users%2Bunsu...@googlegroups.com>
> > .

kiri

unread,
Nov 15, 2010, 4:20:05 AM11/15/10
to testng-users
A small modification resulted in order mismatch now
In the base class add new xyz() method with @AfterClass & make
baseAfterClass() depend on xyz() as below.

@AfterClass(dependsOnGroups = "xyz", alwaysRun = true)
void baseAfterClass()
{
log.info("** 8 **");
}

@AfterClass
void xyz()
{
log.info("** 7 **");
}
== Order of execution is skewed as below ==
14:46:30.028 [main] INFO test.Base - ** 1 **
14:46:30.028 [main] INFO test.Child - ** 2 **
14:46:30.028 [main] INFO test.Child - ** 3 **
14:46:30.028 [main] INFO test.Child - ** 4 **
14:46:30.028 [main] INFO test.Child - ** 5 **
14:46:30.028 [main] INFO test.Base - ** 8 **
14:46:30.028 [main] INFO test.Base - ** 7 **
14:46:30.028 [main] INFO test.Child - ** 6 **

== source ==
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class Child extends Base
{
static final Logger log = LoggerFactory.getLogger(Child.class);

@BeforeClass
public void childBeforeClass()
{
log.info("** 2 **");
}

@BeforeMethod
public void childBeforeTest()
{
log.info("** 3 **");
}

@Test
public void childTest()
{
log.info("** 4 **");
}

@AfterMethod(alwaysRun = true)
public void childAfterTest()
{
log.info("** 5 **");
}

@AfterClass(alwaysRun = true)
public void childAfterClass()
{
log.info("** 6 **");
}
}

class Base
{
static final Logger log = LoggerFactory.getLogger(Base.class);

@BeforeClass
void baseBeforeClass()
{
log.info("** 1 **");
}

@AfterClass(dependsOnGroups = "verify", alwaysRun = true)
void baseAfterClass()
{
log.info("** 8 **");
}

@AfterClass
void verify()
{
log.info("** 7 **");
}
}
==

Cédric Beust ♔

unread,
Nov 15, 2010, 12:54:35 PM11/15/10
to testng...@googlegroups.com
@Before methods in base classes are always run before those in subclasses (and in reverse order for @After).

-- 
Cédric


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.




--
Cédric


kiri

unread,
Nov 16, 2010, 1:22:46 AM11/16/10
to testng-users
Thanks Cedric,
But in the @AfterClass method in base is getting executed before the
one in subclass.(see the code below)

14:46:30.028 [main] INFO test.Base - ** 8 **
14:46:30.028 [main] INFO test.Base - ** 7 **
14:46:30.028 [main] INFO test.Child - ** 6 **

We login(@BeforeClass) and logout (@AfterClass) of a service in a base
class & use sublassses to test. Now in a subclass we need to do some
costly stuff for all @Test's and clean it up.
So used @BeforeClass for setup & @AfterClass for cleanup but logout is
happening before cleanup so cleanup is failing as not authenticated.
This happens only when we use dependsOnMethods in base class.
It will be helpful

= src =
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class Child extends Base {
static final Logger log = LoggerFactory.getLogger(Child.class);

@BeforeClass
public void childBeforeClass() {
Assert.assertTrue(loggedIn, "Not logged in");
log.info("** 2 **");
}

@BeforeMethod
public void childBeforeTest() {
Assert.assertTrue(loggedIn, "Not logged in");
log.info("** 3 **");
}

@Test
public void childTest() {
Assert.assertTrue(loggedIn, "Not logged in");
log.info("** 4 **");
}

@AfterMethod(alwaysRun = true)
public void childAfterTest() {
Assert.assertTrue(loggedIn, "Not logged in");
log.info("** 5 **");
}

@AfterClass(alwaysRun = true)
public void childAfterClass() {
Assert.assertTrue(loggedIn, "Not logged in");
log.info("** 6 **");
}
}

class Base {
protected boolean loggedIn;
static final Logger log = LoggerFactory.getLogger(Base.class);

@BeforeClass
void baseBeforeClass() {
loggedIn = true;
log.info("** 1 **");
}

@AfterClass(dependsOnMethods = "verify", alwaysRun = true)
void baseAfterClass() {
loggedIn = false;
log.info("** 8 **");
}

@AfterClass
void verify() {
Assert.assertTrue(loggedIn, "Not logged in");

kiri

unread,
Nov 16, 2010, 11:55:35 PM11/16/10
to testng-users
Is there any workaround to the problem I mentioned?

Cédric Beust ♔

unread,
Nov 17, 2010, 12:04:07 AM11/17/10
to testng...@googlegroups.com
  @AfterClass(dependsOnGroups = "xyz", alwaysRun = true)
  void baseAfterClass()
  {
     log.info("** 8 **");
  }
  @AfterClass
  void xyz()
  {
     log.info("** 7 **");
  }

If these two methods are on the same class, then their ordering is non deterministic unless you have one depend on the other.

If this doesn't answer your question, please email me a small test case that I can compile to reproduce the problem.

Thanks.

-- 
Cédric

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.




--
Cédric


Jason McSwain

unread,
Nov 17, 2010, 12:06:54 AM11/17/10
to testng...@googlegroups.com

I see u r using dependsongroup=xyz, but method xyz is not in a group.  Is that the problem?

On Nov 16, 2010 11:04 PM, "Cédric Beust ♔" <ced...@beust.com> wrote:

>   @AfterClass(dependsOnGroups = "xyz", alwaysRun = true)
>   void baseAfterClass()
>   {

     log.info("** 8 **");
  }
  @AfterClass
  void xyz()
  {
     log.info("** 7 **");
  }

If these two methods are on the same class, then their ordering is non deterministic unless you have one depend on the other.

If this doesn't answer your question, please email me a small test case that I can compile to reproduce the problem.

Thanks.

-- 
Cédric



On Tue, Nov 16, 2010 at 8:55 PM, kiri <kiran.es...@gmail.com> wrote:
>

> Is there any workaro...

--
Cédric


--
You received this message because you are subscribed to the Google Groups "testng-users" group.

...

kiri

unread,
Nov 17, 2010, 12:55:31 AM11/17/10
to testng-users
Cedric,
My concern is the order of execution of AfterClass in Base and Child
class (Child class's AfterClass method should get executed before Base
classes AfterClass method)

== code to reproduce the problem ==
import org.slf4j.*;
import org.testng.*;
import org.testng.annotations.*;

kiri

unread,
Nov 17, 2010, 12:57:50 AM11/17/10
to testng-users
Jason,
There was a typo in the mail I sent before it's actually
dependsOnMethods not dependsOnGroups, please refer to my latest post.
Thanks

Cédric Beust ♔

unread,
Nov 17, 2010, 1:12:16 AM11/17/10
to testng...@googlegroups.com
I ran your two classes (well, only Child in my testng.xml) and I get:

** 1 **

** 2 **

** 3 **

** 4 **

** 5 **

** 6 **

** 7 **

** 8 **

PASSED: childTest


Are you doing something else that you forgot to mention?


-- 
Cédric

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.




--
Cédric


null.in

unread,
Nov 17, 2010, 2:00:06 AM11/17/10
to testng-users
Also, Kiri,

which version of TestNG are you using? Are you running this from
eclipse? Can you reproduce this problem with latest TestNG code?

-nalin
> > testng-users...@googlegroups.com<testng-users%2Bunsu...@googlegroups.com>
> > .
Reply all
Reply to author
Forward
0 new messages