如何在Java中动态设置CucumberOptions

时间:2019-05-07 15:02:19

标签: java cucumber testng

我正在开发一个桌面应用程序,它将执行自动测试用例。用户可以从GUI中选择执行类型:按功能/按场景/按tagName。现在,我正在使用maven并在CMD中执行命令来执行测试用例,我想切换到TestNG执行,但是我需要从配置文件CucumberOptions动态设置

@CucumberOptions(features = { "src/test/resources/features/" }, tags = { "@Test3" }, glue = { "stepdefinitions" }, plugin = { "listeners.ExtentCucumberFormatter:" })
public class TestNGRunner extends AbstractTestNGCucumberTests {
}

但是CucumberOptions需要一个常量表达式,我无法设置它们。

有什么方法可以做到吗?

2 个答案:

答案 0 :(得分:1)

您可以通过命令行参数传递黄瓜选项:

  

您可以列出您所使用的黄瓜版本的可用选项   使用。

     

传递--help选项以打印出所有可用配置   选项:

     

java cucumber.api.cli.Main --help

     

或者:

     

mvn test -Dcucumber.options="--help"

     

您还可以使用标签来指定要运行的内容。

     

配置选项也可以被覆盖并传递给任何   通过Cucumber.options Java系统属性进入赛跑者。

     

例如,如果您正在使用Maven并希望运行   标有@smoke的场景:

     

mvn test -Dcucumber.options="--tags @smoke"

     

提供了将选项传递给黄瓜的其他机制。一些跑步者

Cucumber Options Documentation

答案 1 :(得分:0)

注意:这是来自 Java,我从 Eclipse 运行,而不是命令行。并不是说如果你知道自己在做什么,就会有巨大差异,但仍然......

我有一个 Excel 电子表格,其中每一行都包含一个角色和一个屏幕子集,并且我已经用 @tag 场景(及其相应的 Java/Selenium 代码片段)完成了我所有的 Gherkin 功能文件,这些文件测试了一个屏幕。有些角色只有 4 个屏幕;有些多达 46 个。我不想创建 24 个(可能更多)不同的 Cucumber Runners(Excel 电子表格中的每一行一个)。我首先尝试通过编辑 CucumberOptions 注释的 tags 属性来动态更改现有 Cucumber Runner 上的标签(在 Java 中;这是可能的!),但我无法让它接受多个标签的字符串数组;只有个别标签。 :-( 然后我偶然发现了cucumber.api.cli.Main 是如何工作的,这让一切变得更容易。最重要的类是cucumber.runtime.Runtime 和cucumber.runtime.RuntimeOptions。我将跳过所有POI 代码用于读取 Excel 文件,但重要的部分如下:

import org.junit.Test;
import org.junit.internal.TextListener;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;

import cucumber.api.CucumberOptions;
import cucumber.api.SnippetType;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;

public class MyRunner {

    /** Constructor */
    public MyRunner (String thisPath) {
           // This does all the POI stuff, plus making the data available to
           //   getCellData(sheet, columnName, row) (which you get to define). 
           // Any way that makes it return a dynamic value will work here.
    }   
 
    public static void main(String[] args) {
        MyRunner myRunner = new MyRunner ("src/main/resources/User Roles.xlsx");
        myRunner.runRunner();
    }

    public void runRunner() {
        String[] newTags = { "@Login" }; 
        String sheetName = "Sheet1";
        int rowCount = this.getRowCount(sheetName);
        String role = "";
        String userId = "";
        String password = "";
        //For each row in the Excel file (row 1 is column names)
        for (int i=2; i<rowCount; i++) { 
            System.out.println("\n run loop i: " + i);
            int rowNumber = i-1;
            role = this.getCellData(sheetName, "User Role", rowNumber).trim();
            userId = this.getCellData(sheetName, "UserID", rowNumber).trim();
            password = this.getCellData(sheetName, "Password", rowNumber).trim();
            String screens = this.getCellData(sheetName, "Screens", rowNumber).trim(); 
            System.out.println(rowNumber + ". runRbac role: '" + role + 
                    "', userId: '" + userId + "', password: '" + password + 
                    "', screens: '" + screens + "'.");
            // I had to do some indirection here because customer who edits the
            // Excel file does not want to see Tags, but uses Screen titles.
            // So I had to map it.
            ArrayList<String> tagList = this.screenTitlesToTags(screens);
            System.out.println(rowNumber + ". Check " + tagList.size() + " screens.");
            runOneRow(rowNumber, role, userId, password, tagList);                          
        }
        String[] finalTags = { "@LogoutCloseBrowser" }; 
        runOneRow(rowCount+1, role, userId, password, finalTags);
    }


    public static void runOneRow(int iteration, String role, String userId, 
                      String password, ArrayList<String> tags) {
        System.out.println("Starting runOneRow with iteration=" + iteration + 
           ", userid=" + userId + ", " + password + ", role=" + role);
        // I couldn't figure out a way to inject the UserId and password into JUnit,
        // so I did it old-school: as a file that the snippet reads. Yuck!
        Utils.writeFile("target/credential.txt", userId + ", " + password); 
        // !!!!!! Here is the heart of the matter!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        JUnitCore junit = new JUnitCore();
        junit.addListener(new TextListener(System.out));
        System.out.println("runOneRow- JUnit/Cucumber test with tags: " + tags);
        String tagString = tags.toString().replace("[", "").replace("]", "").trim();
        tagString = StringUtils.removeEnd(tagString, ",");
        // The tagString value should look something like: 
        // "@Login, @WelcomePage, @FirstScreen, @SecondScreen, @ThirdScreen, @Screen4"
        String[] argv = { "--plugin",  "com.cucumber.listener.ExtentCucumberFormatter:target/cucumber-reports/MyCukeReport.html",
                "--snippets",  "camelcase",
                "--glue", "com.myorg.cukes.stepDefinitions", // or wherever 
                "--tags",  tagString,
                "src/main/java/com/hhs/cms/cukes/features" };
        RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList<String>(asList(argv)));
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        ResourceLoader resourceLoader = new MultiLoader(classLoader);
        ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
        Runtime runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
        try {
            runtime.run();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Finished runOneRow with exitStatus=" + runtime.exitStatus() + ", iteration=" + iteration + ", userid=" + userId + ", " + password + ", role=" + role);
        Result jUnitResult = junit.run(cukeRunnerClass);
        resultReport(jUnitResult);
    }

}