当输入本身是表格时,黄瓜方案大纲

发布于 2025-02-01 10:48:28 字数 1574 浏览 2 评论 0原文

因此,请想象开发的功能正在描述如何处理表或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%的人确定这不会容易或在Gherkin Syntax中得到支持,尽管很高兴被证明是错误的:-) 取而代之的是,对如何解决此问题的任何建议感兴趣。 CSV示例是一个,但是可能还有其他情况,例如一组JSON或XML输入用于特定计算。 到目前为止,我拥有的2个选项要描述该功能,

  1. 继续使用方案并接受大量重复,
  2. 我想场景概述示例可以通过文件名或类似方式参考外部测试资源。可以正常工作,但是功能文件实际上并没有真正封装了期望

So imagine a feature being developed is describing how to process tables or CSV/Excel files. The first approach might be to simply use Scenarios and data tables

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  |

Awkardly Intellij plugin seems to have a hard time with data tables in general so no example here, but I'm pretty sure that can be converted to code (Java in my case).
However what would be nice would be to use scenario outline and examples to cover a wider set. Of course this is invalid gherkin but essentially nest multiline tables into an example block somehow, perhaps with different column delimiters

  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 !

I'm like 99% sure this is not going to be easy or ever supported in Gherkin syntax although happy to be proved wrong :-)
Instead then interested in any recommendations for how to approach this. The CSV example is one, but there could be other situations, e.g. a set of JSON or XML inputs for a particular computation.
The 2 options I have so far for describing the feature is

  1. Continue using Scenarios and accept lots of duplication
  2. I suppose the scenario outline examples could refer to external test resources by file name or similar. Could work but then the feature file doesn't really encapsulate expectations

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢欲 2025-02-08 10:48:28

不,这是不可能的。

黄瓜的目的是支持行为驱动的发展。因此,假设场景与人共享。因此应强调可读性。

有时,这可能意味着制作自己的DSL。 For example the

---
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));
        }
    }

您可以执行相同的操作并共享这些文件或除了功能文件之外。只是不要列出功能文件中的外部文件。那将是毫无意义的间接层。

No this isn't possible.

The purpose of Cucumber is to support Behavior Driven Development. So it is assumed scenarios are shared with people. So readability should be emphasized.

And sometimes this can mean making your own DSL. For example the cucumber-expressions module uses test cases written in yaml.

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

These are executed as JUnit 5 tests:

    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));
        }
    }

You can do the same thing and share those files instead or in addition to your feature files. Just don't list the external files in your feature file. That would be a pointless layer of indirection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文