首页 > 解决方案 > 我们可以通过 Vm 参数覆盖 TestNg 中 @BeforeTest 中的“启用”吗?

问题描述

我们是否可以@BeforeTest通过具有默认值的 vm 参数禁用enabled=true

@BeforeTest(enabled = true)
public void someMethod(){
...}

我不想跑someMethod。我不想添加任何参数并检查条件。

标签: javatestng

解决方案


org.testng.IAnnotationTransformer您可以使用实现很好地做到这一点。

下面是一个示例,显示了转换器的外观 [确保您使用的是最新发布的 TestNG 版本,即7.1.0截至今天]

要记住的要点:

  • 确保仅通过套件文件连接注释转换器。
  • 要选择性地禁用任何配置方法(不仅仅是@BeforeTest),您只需将完全限定的方法名称作为逗号分隔值作为 JVM 参数传递 [例如,-Dmethods.disable=com.rationaleemotions.stackoverflow.qn59840389.SampleTestClass#skippingBeforeTest]。必须使用分隔类名和方法名,并且可以使用分隔#多个值,
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.IConfigurationAnnotation;

public class SampleAnnotationTransformer implements IAnnotationTransformer {

  @Override
  public void transform(
      IConfigurationAnnotation annotation,
      Class testClass,
      Constructor testConstructor,
      Method testMethod) {
    if (testMethod == null) {
      return;
    }

    String jvmValue = System.getProperty("methods.disable");
    if (jvmValue == null || jvmValue.trim().isEmpty()) {
      return;
    }

    List<String> methods = Arrays.asList(jvmValue.split(","));

    String fullyQualifiedMethodName =
        testMethod.getDeclaringClass().getCanonicalName() + "#" + testMethod.getName();
    if (methods.contains(fullyQualifiedMethodName)) {
      annotation.setEnabled(false);
    }
  }
}

然后创建一个套件 xml 文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="59840389_suite" parallel="false" configfailurepolicy="continue" verbose="2">
  <listeners>
    <listener
      class-name="com.rationaleemotions.stackoverflow.qn59840389.SampleAnnotationTransformer"/>
  </listeners>
  <test name="59840389_test">
    <classes>
      <class name="com.rationaleemotions.stackoverflow.qn59840389.SampleTestClass">
      </class>
    </classes>
  </test>
</suite>

这是测试类

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class SampleTestClass {
  private boolean skipMarkedBeforeTest = false;

  @BeforeTest
  public void skippingBeforeTest() {
    skipMarkedBeforeTest = true;
  }

  @BeforeTest
  public void runnableBeforeTest() {
    System.err.println("runnableBeforeTest");
  }

  @Test
  public void beforeMethod() {
    Assert.assertFalse(skipMarkedBeforeTest);
  }
}

推荐阅读