如何在TestNG的子类中禁用测试运行?

3
(更新:我报告后,TestNG团队确认漏洞。)
通常可以使用@Ignoreenabled=false来忽略一个类。
但是,在包含测试方法的超类中定义子类时,这种方法不起作用(子类在挂钩方法中定义其特定功能)。参见下面的ChildClassTest
请注意,@Ignore专门针对JUnit,而TestNG使用enabled
基类
import org.testng.annotations.Test;

public class ParentClassTest {
    @Test
    public void test1() {
        hook();
    }

    protected void hook() {};
}

子类
import org.testng.Reporter;
import org.testng.annotations.Ignore;

@Ignore
public class ChildClassTest extends ParentClassTest {
    @Override
    protected void hook() {
        Reporter.log("ChildClassTest#hook()");
    }
}

可能是忽略TestNG中的一个类的重复问题。 - Thiyagu
忽略TestNG中的一个类很容易,只需使用enabled=false即可。但如果该类是测试类的子类且没有自己的方法呢?这就是我的问题。 - Joshua Fox
@user7,事实证明这是一个真正的 bug,由 TestNg 团队确认! - Joshua Fox
Morfic 谢谢。是的,在这种情况下会忽略 @Ignore。覆盖实际的 @Test 方法可能会像描述的那样工作,但在这里我们有一个子类中的钩子方法实现,没有 @Test 方法。 - Joshua Fox
没问题。是的,我从一开始就知道子类中没有测试。我只是建议在您的子类中暂时覆盖所需的方法而不添加主体(或者可能添加注释以使其不那么奇怪),并添加@Test(enabled = false),作为解决方法,直到发布适当的解决方案。这样,它将被跳过,而其余部分将按需要运行,希望可以尽量减少工作量。 - Morfic
显示剩余3条评论
1个回答

2

出于好奇,我进行了一些头脑风暴,并想出了以下的解决方法,已在v6.14.2测试过。个人更喜欢第一种方式,它更简洁、优雅、灵活且易于维护和扩展。

上下文

import org.testng.annotations.Test;

import static org.testng.Assert.assertTrue;

public class MyTest {
    @Test
    public void shouldRun() {
        assertTrue(true);
    }

    @Test
    public void shouldNotRun() {
        assertTrue(true);
    }

    @Test
    public void shouldNotRunEither() {
        assertTrue(true);
    }
}

1)使用监听器 - 创建一个TestListenerAdapter和注释来跳过某些名称的方法:灵活,清晰易懂,并且容易重用和识别以进行删除。唯一的缺点是您必须注意方法名称的拼写错误。

注释

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SkipMethods {
    String[] value() default {};
}

TestListenerAdapter

import org.testng.ITestResult;
import org.testng.SkipException;
import org.testng.TestListenerAdapter;

public class TestSkippingListener extends TestListenerAdapter {
    @Override
    public void onTestStart(ITestResult result) {
        // get the skip annotation
        SkipMethods skipAnnotation = result.getMethod().getInstance().getClass().getAnnotation(SkipMethods.class);

        // if the annotation exists
        if (skipAnnotation != null) {
            for (String skippableMethod : skipAnnotation.value()) {

                // and defines the current method as skippable
                if (skippableMethod.equals(result.getMethod().getMethodName())) {

                    // skip it
                    throw new SkipException("Method [" + skippableMethod + "] marked for skipping");
                }
            }
        }
    }
}

测试子类

import org.testng.annotations.Listeners;

// use listener
@Listeners(TestSkippingListener.class)

// define what methods to skip
@SkipMethods({"shouldNotRun", "shouldNotRunEither"})
public class MyTestSkippingInheritedMethods extends MyTest {

}

结果

listener跳过


2) 覆盖超类中的方法并抛出SkipException:非常明确,没有拼写错误的可能性,但不可重用,不易维护,并且引入了无用的代码:

import org.testng.SkipException;

public class MyTestSkippingInheritedMethods extends MyTest {

    @Override
    public void shouldNotRun() {
        throw new SkipException("Skipped");
    }

    @Override
    public void shouldNotRunEither() {
        throw new SkipException("Skipped");
    }
}

结果

跳过重写


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接