如何获得黄瓜的迭代次数?

时间:2018-03-27 06:51:23

标签: java selenium cucumber

当我们在功能文件中执行带有多行的特征文件时,我希望获得黄瓜的迭代计数 - > 想象一下我们有两排First Scenario轮廓,比如A1和A2,以及第二个两个,比如B1和B2,要执行的情况。 情景1
例子:
| num1 | num2 |总计|
| -2 | 3 | 1 | - A1
| 10 | 15 | 25 | - A2
情景2
例子:
| num1 | num2 |总计|
| 4 | 5 | 9 | - B1
| 13 | 12 | 25 | - B2
并行执行上述两个场景的预期状态
Thread ScenarioOutline InvocationCount状态
1 A1 1 确定
2 B1 1 确定
3 A2 1 不行
请帮助我们如何处理,因为这可能是并行执行的情况。

2 个答案:

答案 0 :(得分:1)

您可以在main / java / cucumber / runtime / model下创建“ CucumberScenarioOutline.java”的副本。

然后,您可以在声明一个全局变量intCurrentRow之后修改以下方法-

@override
public void run(Formatter formatter, Reporter reporter, Runtimeruntime) {
    formatOutlineScenario(formatter);
    for (CucumberExamples cucumberExamples : cucumberExamplesList) {
        cucumberExamples.format(formatter);
        List<CucumberScenario> exampleScenario = cucumberExamples.createExampleScenarios();
        intCurrentRow = 1;  //Hereyou can ititiate your variable
        for (CucumberScenario exampleScenario : exampleScenarios) {
            exampleScenario.run(formatter, reporter, runtime);
            intCurrentRow++;  //Here you can increase iteration number
        }
    }
}

您还可以复制下面的代码来创建CucumberScenarioOutline.java

package cucumber.runtime.model;

import cucumber.runtime.CucumberException;
import cucumber.runtime.Runtime;
import gherkin.formatter.Formatter;
import gherkin.formatter.Reporter;
import gherkin.formatter.model.DataTableRow;
import gherkin.formatter.model.DocString;
import gherkin.formatter.model.Examples;
import gherkin.formatter.model.ExamplesTableRow;
import gherkin.formatter.model.Row;
import gherkin.formatter.model.Scenario;
import gherkin.formatter.model.ScenarioOutline;
import gherkin.formatter.model.Step;
import gherkin.formatter.model.Tag;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CucumberScenarioOutline extends CucumberTagStatement {
    private final List<CucumberExamples> cucumberExamplesList = new ArrayList<CucumberExamples>();
    private final CucumberBackground cucumberBackground;

    public CucumberScenarioOutline(CucumberFeature cucumberFeature, CucumberBackground cucumberBackground, ScenarioOutline scenarioOutline) {
        super(cucumberFeature, scenarioOutline);
        this.cucumberBackground = cucumberBackground;
    }

    public void examples(Examples examples) {
        cucumberExamplesList.add(new CucumberExamples(this, examples));
    }

    public List<CucumberExamples> getCucumberExamplesList() {
        return cucumberExamplesList;
    }

    @Override
    public void run(Formatter formatter, Reporter reporter, Runtime runtime) {
        format(formatter);
        for (CucumberExamples cucumberExamples : cucumberExamplesList) {
            cucumberExamples.format(formatter);
            List<CucumberScenario> exampleScenarios = cucumberExamples.createExampleScenarios();
            for (CucumberScenario exampleScenario : exampleScenarios) {
                exampleScenario.run(formatter, reporter, runtime);
            }
        }
    }

    CucumberScenario createExampleScenario(ExamplesTableRow header, ExamplesTableRow example, List<Tag> examplesTags) {
        // Make sure we replace the tokens in the name of the scenario
        String exampleScenarioName = replaceTokens(new HashSet<Integer>(), header.getCells(), example.getCells(), getGherkinModel().getName());

        Scenario exampleScenario = new Scenario(example.getComments(), examplesTags, getGherkinModel().getKeyword(), exampleScenarioName, "", example.getLine(), example.getId());
        CucumberScenario cucumberScenario = new CucumberScenario(cucumberFeature, cucumberBackground, exampleScenario, example);
        for (Step step : getSteps()) {
            cucumberScenario.step(createExampleStep(step, header, example));
        }
        return cucumberScenario;
    }

    static ExampleStep createExampleStep(Step step, ExamplesTableRow header, ExamplesTableRow example) {
        Set<Integer> matchedColumns = new HashSet<Integer>();
        List<String> headerCells = header.getCells();
        List<String> exampleCells = example.getCells();

        // Create a step with replaced tokens
        String name = replaceTokens(matchedColumns, headerCells, exampleCells, step.getName());

        return new ExampleStep(
                step.getComments(),
                step.getKeyword(),
                name,
                step.getLine(),
                rowsWithTokensReplaced(step.getRows(), headerCells, exampleCells, matchedColumns),
                docStringWithTokensReplaced(step.getDocString(), headerCells, exampleCells, matchedColumns),
                matchedColumns);
    }

    private static List<DataTableRow> rowsWithTokensReplaced(List<DataTableRow> rows, List<String> headerCells, List<String> exampleCells, Set<Integer> matchedColumns) {
        if (rows != null) {
            List<DataTableRow> newRows = new ArrayList<DataTableRow>(rows.size());
            for (Row row : rows) {
                List<String> newCells = new ArrayList<String>(row.getCells().size());
                for (String cell : row.getCells()) {
                    newCells.add(replaceTokens(matchedColumns, headerCells, exampleCells, cell));
                }
                newRows.add(new DataTableRow(row.getComments(), newCells, row.getLine()));
            }
            return newRows;
        } else {
            return null;
        }
    }

    private static DocString docStringWithTokensReplaced(DocString docString, List<String> headerCells, List<String> exampleCells, Set<Integer> matchedColumns) {
        if (docString != null) {
            String docStringValue = replaceTokens(matchedColumns, headerCells, exampleCells, docString.getValue());
            return new DocString(docString.getContentType(), docStringValue, docString.getLine());
        } else {
            return null;
        }
    }

    private static String replaceTokens(Set<Integer> matchedColumns, List<String> headerCells, List<String> exampleCells, String text) {
        for (int col = 0; col < headerCells.size(); col++) {
            String headerCell = headerCells.get(col);
            String value = exampleCells.get(col);
            String token = "<" + headerCell + ">";

            if (text.contains(token)) {
                text = text.replace(token, value);
                if (text.isEmpty()) {
                    throw new CucumberException("Step generated from scenario outline '" + token + "' is empty");
                }
                matchedColumns.add(col);
            }
        }
        return text;
    }
}

答案 1 :(得分:0)

简单方法,但不是一种非常灵活的方法是创建一个包含迭代编号的列。

Scenario Outline: Add two numbers <num1> & <num2>
    Given I have a calculator
    When I add <num1> and <num2> for iteration number <itrnum>
    Then the result should be <total>

  Examples: 
    | itrnum | num1 | num2 | total |
    | 1 | -2 | 3 | 1 |
    | 2 | 10 | 15 | 25 |
    | 3 | 99 | -99 | 0 |

其他是使用before hook获取此信息。为此,为scenariooutline添加一个标记,让我们说@Counter。仅为Before hook代码创建@Counter。使用静态变量来保持计数。所以这个挂钩只会在计数器标签出现的地方运行。需要静态作为钩子的新实例,并为场景轮廓的每一行创建步骤类。

@Counter
Scenario Outline: Add two numbers <num1> & <num2>
        Given I have a calculator
        When I add <num1> and <num2>
        Then the result should be <total>

      Examples: 
        | num1 | num2 | total |
        | -2 | 3 | 1 |
        | 10 | 15 | 25 |
        | 99 | -99 | 0 |
private static int count = 0;

@Before("@Counter") 
public void countScenarioOutlineRows() {
    count++;
}

----------

更新 - 适用于多种情景大纲。 您可以使用静态映射来存储计数器。但为此,您需要在scenariooutline描述中添加某种键。

@Counter
    Scenario Outline: SO1 ## Add two numbers <num1> & <num2>

@Counter
    Scenario Outline: SO2 ## Multiply two numbers <num1> & <num2>
private static Map<String, Integer> counter = new HashMap<>();

    @Before("@Counter") 
    public void countScenarioOutlineRows(Scenario sce) {
        //Get descrition on scenrio outline
        System.out.println("SCENARIO NAME -- " +sce.getName());
        String key = sce.getName().substring(0, sce.getName().indexOf("##") - 1);
        System.out.println("SCENARIO KEY --" + key + "--");

        counter.merge(key, 1, Integer::sum);
    }

如果您不想将所有细节存储在Map中,请将计数器存储在静态整数中。当描述更改时将其切换为0,否则添加1。为此,您还需要将scenariooutline描述存储在临时静态变量中以进行比较。