testng-failed.xml不包含always run = true的方法

问题描述 投票:0回答:1

可以说我有两节课

Class A
{
     @BeforeClass
     public void abc()
     {
        ----
     }
     @Test(alwaysRun = true)
     public void def()
     {
        -----
     }
}

另一堂课

Class B
{
    @Test
    public void xyz()
    {
         SoftAssert sa = new SoftAssert();
         -----
         sa.fail();
         sa.assertAll();
    }
}

让我们说B类失败然后testng-failed.xml将如下所示

<test name="test1(failed)">
<classes>
  <class name="A">
    <methods>
      <include name="abc"/>
    </methods>
  </class>

   <class name="B">
    <methods>
      <include name="xyz"/>
    </methods>
  </class>    

我已经提到,如果方法def为true,那么run = true,那么该方法也必须包含在testng-failed.xml中。

为什么testng-failed.xml中没有这个?

testng
1个回答
0
投票

根据定义,alwaysRun方法的@Test属性表示以下内容(引用javadocs)

如果设置为true,则即使依赖于失败的方法,也始终会运行此测试方法。

根据行为,TestNG仅包括那些在testng-failed.xml中失败的方法。因此,如果你的def()方法没有失败,那么它就不会被包含在你的testng-failed.xml中。

如果你想要始终包含def()方法(然后猜测,它不是@Test方法,但似乎更像是一种配置方法),那么你有以下选择。

  1. 将它移出@Test方法(因为它看起来确实不是一个测试方法,而是某种条件设置,只需要对某些方法进行)和一个TestNG监听器[例如,一个org.testng.IInvokedMethodListener]和在侦听器中,基于某些自定义注释执行此操作。因此,所有需要运行此特殊代码片段的方法都会添加自定义注释[请参阅here示例],在此侦听器的beforeInvocation()中,您将查找自定义注释,如果找到,则运行它。
  2. 另一个选项基本上是拥有实现org.testng.IHookable接口的基类的这一部分。所有的测试方法都会扩展这个基类,并且通过IHookable接口在基类[run()方法的run()实现中)你会添加我上面提到的相同的自定义注释逻辑。

这是一个展示所有这些内容的示例。

样品(1)

标记注释。

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;

/**
 * A marker annotation that indicates a special setup is needed.
 */
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD})
public @interface NeedSpecialSetup {}
/**
 * This interface which when implemented by test classes (classes that hold one or more {@link org.testng.annotations.Test}
 * annotated methods lets you perform special actions. But the methods should also be annotated using {@link NeedSpecialSetup}
 * annotation for this implementation to be invoked.
 */
public interface PerformSpecialSetup {
    void perform();
}

听众

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class SimpleMethodListener implements IInvokedMethodListener {
    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        //Did the method have our custom annotation which indicates that special setup is needed ?
        NeedSpecialSetup specialsetup = method.getTestMethod().getConstructorOrMethod().getMethod().getAnnotation(NeedSpecialSetup.class);
        if (specialsetup != null) {
            //Now lets check if the Object to which the method belongs to, has the capability to do the special setup
            //and if it does, just delegate the call back to the respective test class instance. This way, we are not
            //hard wiring any logic to our listener, but letting the respective test classes do whatever custom
            //setup it requires.
            Object instance = testResult.getInstance();
            if (instance instanceof PerformSpecialSetup) {
                ((PerformSpecialSetup) instance).perform();
            }
        }
    }

    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) { }
}

考试班

import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(SimpleMethodListener.class)
public class MyTestClass implements PerformSpecialSetup {

    @Test
    public void method1() {
        System.err.println("method1() invoked");
    }

    @Test
    @NeedSpecialSetup
    public void method2() {
        System.err.println("method2() invoked");
    }

    @Override
    public void perform() {
        System.err.println("Special setup completed");
    }
}

样本(2)

import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import org.testng.annotations.Test;

public class AnotherTestClass implements IHookable {
    @Override
    public void run(IHookCallBack callBack, ITestResult testResult) {
        NeedSpecialSetup specialsetup = testResult.getMethod().getConstructorOrMethod().getMethod().getAnnotation(NeedSpecialSetup.class);
        if (specialsetup != null) {
            perform();
        }
        callBack.runTestMethod(testResult);
    }

    @Test
    public void method1() {
        System.err.println("method1() invoked");
    }

    @Test
    @NeedSpecialSetup
    public void method2() {
        System.err.println("method2() invoked");
    }

    public void perform() {
        System.err.println("Special setup completed");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.