Cucumber 7 + TestNG - 测试运行开始前的动态标签操作

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

我在我的项目中使用 TestNG 和 Cucumber。

使用过的版本:

    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.4.0</version>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>7.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>7.0.0</version>
    </dependency>

一切正常,但我需要在测试运行开始之前进行一些动态标签操作。 更具体地说 - 我需要根据某些环境条件添加额外的过滤标签表达式。

当前的实现是带有

AbstractTestNGCucumberTests
字段的
TestNGCucumberRunner
类。

我需要更改/添加一些代码行的地方是在

TestNGCucumberRunner
类的构造函数中,因为运行程序就在那里初始化并开始测试运行。

问题是 cucumber-testng 依赖项中的几乎所有类都不是

public
final
。所以我无法扩展类并覆盖一些逻辑。

我看到的唯一方法是复制依赖于我的源文件夹的所有类,这是一个奇怪而愚蠢的想法。

有什么建议可以让我实现我的目标吗?

java testing cucumber testng
2个回答
0
投票

扩展

AbstractTestNGCucumberTests
时,您可以过滤
scenarios()

的输出
public class RunCucumberTest extends AbstractTestNGCucumberTests {

    @DataProvider(parallel = true)
    @Override
    public Object[][] scenarios() {
        Object[][] scenarios = super.scenarios();
        // Do filtering here
        return scenarios;
    }

}

由于数据提供程序用于调用测试方法,因此您可以安全地将第一个数组元素转换为

PickleWrapper
并使用
pickleWrapper.getPickle().get tags()
访问标签。


0
投票

上面这个解决方案非常好。它让我走上了正确的道路。我不明白如何在运行时覆盖标签。但我希望整个过滤工作与黄瓜标签的常见“和”“或”“非”表达式一起工作,并且也像传递用逗号分隔的多个标签一样简单。

因此,在从 AbstractTestNGCucumberTests 开始挖掘黄瓜类一整天后,我了解了标签的具体处理方式。然后,我找到了完美的解决方案。这是完整的代码。

/**
 * This runner is a hybrid runner which can run normally as local runner with Cucumber Options or run with tags variable passed from Pipeline tools or from any other sources
 * <br></br>
 * This runner works with either of them or both combined. Let's say You have passed '@smoke' tag in @CucumberOptions annotation which have 100 scenarios, then additionally you can also pass a runtime tag "@Login" and filter again.
 */
@CucumberOptions( features = "src/test/resources/features/",
                  glue = { "stepDefinitions", "hooks" },
                  plugin = { "pretty", "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:" },
                  tags = "" )       //Pass tags here as usual
public class CucumberRunnerTest extends AbstractTestNGCucumberTests
{

    @DataProvider
    @Override
    public Object[][] scenarios()
    {
        Object[][] scenarios = super.scenarios();

        String dynamicTags = System.getenv("tags");   //passed from Pipeline 
        //Or add any other sources you want to get the tags from

        if ( dynamicTags != null && !dynamicTags.equals("") ) return (Arrays.stream(scenarios).filter(scenario -> TagExpressionParser.parse(dynamicTags).evaluate((( PickleWrapper ) scenario[0]).getPickle().getTags())).collect(Collectors.toList())).toArray(new Object[0][0]);
        else return scenarios;
    }
}

我将其范围缩小到一行简单的 TagExpression,但我花了几个小时才找到这些并理解这么多不同的类。

尝试一次,希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.