2

Well, I'm a bit confused.

public class GroupDemo {

   @Test()
   public void test1() {
        System.out.println("test1");
   }
}

and

public class GroupDemoChild extends GroupDemo{

   @Test
   public void atest(){
       System.out.println("atest");
   }

   @AfterMethod
   public void after() {
       System.out.println("after method");
   }
}

And what is logical to expect here:

test1
atest
after method

However I get:

test1
after method
atest
after method

So after() is invoked twice.

How do I run it only after methods of declaring class?

TestNG = 6.8.5; Java = 1.7

TEH EMPRAH
  • 1,828
  • 16
  • 32

4 Answers4

2

You can also utilize a custom implementation of the IInvokedMethodListener interface along with some custom annotation. Something like:

@Listeners({ com.somepackage.MethodInvocationListener.class })
public class GroupDemoChild extends GroupDemo{

   @Test
   @AfterEd
   public void atest(){
       System.out.println("atest");
   }
}

public class MethodInvocationListener implements IInvokedMethodListener {
    @Override
    public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
        // doNothing
    }

    @Override
    public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
        if (iInvokedMethod.getTestMethod().getConstructorOrMethod()
                .getMethod().getAnnotation(AfterEd.class) != null) {
                System.out.println("after method");
        }
    }
}
Nick
  • 130
  • 1
  • 10
0
@AfterMethod
public void after(Method method) {
    if(method.getDeclaringClass() == this.getClass()) {
        System.out.println("after method"); 
    }
}

Is a quick and dirty solution. But can we have anything more for normal people?

TEH EMPRAH
  • 1,828
  • 16
  • 32
  • Okay, I accept my own answer since it worked perfectly for launching with tests where invocationCount>1 and does not affect superclasses. **To possible Cedric Beust in this thread**: Could the described behavior be a bug of 6.8.5 ? – TEH EMPRAH May 29 '15 at 13:30
0

In fact current behavior is:

  • test1()
  • after()
  • atest()
  • after()
  • test1()

because @AfterMethod runs after each @Test method in 'current' class hierarchy and if you include class without it again it's not executed.

Solution is to not use extends GroupDemo and create more specific/generic classes (basically refactor your test class hierarchy).

Also you can use some attributes in @AfterMethod for better flow control (alwaysRun, groups, etc.). http://testng.org/javadoc/org/testng/annotations/AfterMethod.html

Jaroslav Cincera
  • 996
  • 6
  • 11
  • In fact, TestNG documentation does not state that AfterMethod will be run for every method in **hierarchy** up to superclasses. And this seems strange, since e.g. AfterClass works for the lowest instantiated class in hierarchy. – TEH EMPRAH May 27 '15 at 15:21
-1

In Testng, @AfterMethod will execute after every @Test method.

Use @AfterTest, this will execute after all @Test have been executed.