26

目前有没有办法根据条件禁用 TestNG 测试

我知道您目前可以在 TestNG 中禁用测试:

@Test(enabled=false, group={"blah"})
public void testCurrency(){
...
}

我想根据条件禁用相同的测试,但不知道如何。像这样的东西:

@Test(enabled={isUk() ? false : true), group={"blah"})
public void testCurrency(){
...
}

任何人都知道这是否可能。

4

7 回答 7

39

一个更简单的选择是在检查您的条件的方法上使用 @BeforeMethod 注释。如果你想跳过测试,那么只需抛出一个SkipException。像这样:

@BeforeMethod
protected void checkEnvironment() {
  if (!resourceAvailable) {
    throw new SkipException("Skipping tests because resource was not available.");
  }
}
于 2010-12-13T22:36:38.280 回答
16

你有两个选择:

如果条件不满足,您的注释转换器将测试条件,然后覆盖@Test 注释以添加属性“enabled=false”。

于 2010-10-15T20:57:25.670 回答
10

我知道有两种方法可以让您控制 TestNG 中的“禁用”测试。

需要注意的非常重要的区别是,在实现 IAnnotationTransformer 时,SkipException 将中断所有后续测试,并根据您指定的条件使用反射来禁用单个测试。我将解释 SkipException 和 IAnnotationTransfomer。

跳过异常示例

import org.testng.*;
import org.testng.annotations.*;

public class TestSuite
{
    // You set this however you like.
    boolean myCondition;
    
    // Execute before each test is run
    @BeforeMethod
    public void before(Method methodName){
        // check condition, note once you condition is met the rest of the tests will be skipped as well
        if(myCondition)
            throw new SkipException();
    }
    
    @Test(priority = 1)
    public void test1(){}
    
    @Test(priority = 2)
    public void test2(){}
    
    @Test(priority = 3)
    public void test3(){}
}

IAnnotationTransformer 示例

有点复杂,但其背后的想法是一个称为反射的概念。

维基 - http://en.wikipedia.org/wiki/Reflection_(computer_programming)

首先实现 IAnnotation 接口,将其保存在 *.java 文件中。

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

public class Transformer implements IAnnotationTransformer {

    // Do not worry about calling this method as testNG calls it behind the scenes before EVERY method (or test).
    // It will disable single tests, not the entire suite like SkipException
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod){

        // If we have chose not to run this test then disable it.
        if (disableMe()){
            annotation.setEnabled(false);
        }
    }

    // logic YOU control
    private boolean disableMe() {
    }
}

然后在您的测试套件 java 文件中,在 @BeforeClass 函数中执行以下操作

import org.testng.*;
import org.testng.annotations.*;

/* Execute before the tests run. */    
@BeforeClass
public void before(){

    TestNG testNG = new TestNG();
    testNG.setAnnotationTransformer(new Transformer());
}

@Test(priority = 1)
public void test1(){}

@Test(priority = 2)
public void test2(){}

@Test(priority = 3)
public void test3(){}

最后一步是确保在 build.xml 文件中添加一个侦听器。我的最终看起来像这样,这只是 build.xml 中的一行:

<testng classpath="${test.classpath}:${build.dir}" outputdir="${report.dir}" 
    haltonfailure="false" useDefaultListeners="true"
    listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter,Transformer" 
    classpathref="reportnglibs"></testng>
于 2014-03-18T20:46:28.943 回答
3

第三选项也可以是 TestNG 的 Assumption Assumptions - 当假设失败时,TestNG 将被指示忽略测试用例,因此不会执行它。

  • 使用@Assumption 注解
  • 使用 AssumptionListener 使用 Assumes.assumeThat(...) 方法

您可以使用此示例:示例

于 2018-07-22T10:40:04.030 回答
3

我更喜欢这种基于注释的方式来禁用/跳过一些基于环境设置的测试。易于维护,不需要任何特殊的编码技术。

  • 使用 IInvokedMethodListener 接口
  • 创建自定义注释,例如:@SkipInHeadlessMode
  • 抛出跳过异常
public class ConditionalSkipTestAnalyzer implements IInvokedMethodListener {
    protected static PropertiesHandler properties = new PropertiesHandler();

    @Override
    public void beforeInvocation(IInvokedMethod invokedMethod, ITestResult result) {
        Method method = result.getMethod().getConstructorOrMethod().getMethod();
        if (method == null) {
            return;
        }
        if (method.isAnnotationPresent(SkipInHeadlessMode.class)
                && properties.isHeadlessMode()) {
            throw new SkipException("These Tests shouldn't be run in HEADLESS mode!");
        }
    }

    @Override
    public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
        //Auto generated
    }
}

查看详情: https ://www.lenar.io/skip-testng-tests-based-condition-using-iinvokedmethodlistener/

于 2020-02-10T08:57:28.597 回答
0

SkipException在带有注释的方法中抛出 a@BeforeMethod对我不起作用,因为它跳过了我的测试套件的所有剩余测试,而不考虑是否SkipException为这些测试抛出了 a。

我没有彻底调查它,但我找到了另一种方法:使用注释dependsOnMethods上的属性:@Test

import org.testng.SkipException;
import org.testng.annotations.Test;

public class MyTest {

  private boolean conditionX = true;
  private boolean conditionY = false;

  @Test
  public void isConditionX(){
    if(!conditionX){
      throw new SkipException("skipped because of X is false");
    }
  }

  @Test
  public void isConditionY(){
    if(!conditionY){
      throw new SkipException("skipped because of Y is false");
    }
  }

  @Test(dependsOnMethods="isConditionX")
  public void test1(){

  }

  @Test(dependsOnMethods="isConditionY")
  public void test2(){

  }
}
于 2017-04-18T18:38:09.913 回答
0

SkipException:如果我们在类中只有一个 @Test 方法,这很有用。与数据驱动框架一样,我只有一个测试方法需要根据某些条件执行或跳过。因此,我将检查条件的逻辑放在 @Test 方法中并获得所需的结果。它帮助我获得了测试用例结果为 Pass/Fail 和特定 Skip 的范围报告。

于 2019-01-18T10:26:47.023 回答