提问者:小点点

cucumber场景大纲当输入本身是表格时


因此,假设正在开发的功能正在描述如何处理表格或CSV/Excel文件。第一种方法可能是简单地使用场景和数据表

Feature: Calculate from CSVs
  Scenario: sum column C filtered by A
    Given the CSV file:
     | A | B     | C |
     | a | true  | 9 |
     | e | false | 8 |
     | a | false | 5 |
    When I calculate sum filtered by value in A being "a"
    Then the answer is 14

  Scenario: sum column C sum by A
    Given the CSV file:
      | A | B     | C |
      | a | true  | 9 |
      | e | false | 8 |
      | a | false | 5 |
    When I calculate sum of C grouped by A values
    Then the answer table is:
      | A | C  |
      | a | 14 |
      | e | 8  |

令人惊叹的Intellij插件似乎很难处理一般的数据表,所以这里没有示例,但我很确定可以转换为代码(在我的情况下Java)。然而,使用场景大纲和示例来覆盖更广泛的集合会很好。当然,这是无效的gherkin,但本质上是以某种方式将多行表嵌套到示例块中,也许具有不同的列分隔符

  Scenario Outline:
    Given input csv <example>
    When I use filter <filter> on A
    Then I get table <output>
    Examples:
      | example   | filter | output  |
      |  ! A  ! B ! C !   |  a |      ! A  ! C !       |
         ! a ! true  ! 9 !            ! a ! 14 !
         ! e ! false ! 8 !
         ! a ! false ! 5 !
      |  ! A ! B ! C !    |  e |     ! A  ! C !      |
         ! a ! true  ! 9 !           ! e ! 8 !
         ! e ! false ! 8 !
         ! a ! false ! 5 !

我想99%肯定这不会很容易,也不会在小cucumber语法中得到支持,尽管很高兴被证明是错误的:-)而是对如何处理这个问题的任何建议感兴趣。CSV的例子是一个,但也可能有其他情况,例如一组JSON或XML输入用于特定的计算。到目前为止,我描述该功能的两个选项是

  1. 继续使用场景并接受大量重复
  2. 我假设场景大纲示例可以通过文件名或类似名称引用外部测试资源。可以工作,但功能文件并没有真正封装期望

共1个答案

匿名用户

不,这不可能。

Cucumber的目的是支持行为驱动开发。所以假设场景是与人共享的。所以应该强调易读性。

有时这意味着你可以自己DSL,例如,cucumber表达式模块使用yaml编写的测试用例。

---
expression: three {string} and {string} mice
text: three '' and 'handsome' mice
expected_args:
- ''
- handsome

这些作为JUnit 5测试执行:

    private static List<Path> acceptance_tests_pass() throws IOException {
        List<Path> paths = new ArrayList<>();
        newDirectoryStream(Paths.get("..", "testdata", "cucumber-expression", "matching")).forEach(paths::add);
        paths.sort(Comparator.naturalOrder());
        return paths;
    }

    @ParameterizedTest
    @MethodSource
    void acceptance_tests_pass(@ConvertWith(Converter.class) Expectation expectation) {
        if (expectation.exception == null) {
            CucumberExpression expression = new CucumberExpression(expectation.expression, parameterTypeRegistry);
            List<Argument<?>> match = expression.match(expectation.text);
            List<?> values = match == null ? null : match.stream()
                    .map(Argument::getValue)
                    .collect(Collectors.toList());

            assertThat(values, CustomMatchers.equalOrCloseTo(expectation.expected_args));
        } else {
            Executable executable = () -> {
                CucumberExpression expression = new CucumberExpression(expectation.expression, parameterTypeRegistry);
                expression.match(expectation.text);
            };
            CucumberExpressionException exception = assertThrows(CucumberExpressionException.class, executable);
            assertThat(exception.getMessage(), equalTo(expectation.exception));
        }
    }

您可以做同样的事情并共享这些文件,而不是在您的功能文件之外共享这些文件。只是不要在您的功能文件中列出外部文件。那将是一个毫无意义的间接层。