SpecFlow/Cucumber/Gherkin - Using tables in a scenario outline

后端 未结 2 1564
臣服心动
臣服心动 2020-12-31 04:20

Hopefully I can explain my issue clearly enough for others to understand, here we go, imagine I have the two following hypothetical scenarios:

Scenario: Filt         


        
相关标签:
2条回答
  • 2020-12-31 04:34

    I don't think what you're asking for is possible with SpecFlow, Gherkin, and out-of-the-box Cucumber. I can't speak for the authors, but I bet it purposely is not meant to be used this way because it goes against the overall "flow" of writing and implementing these specs. Among many things, the specs are meant to be readable to non-programmers, to give the programmer a guide to implement code that matches the specs, for integration testing, and to give a certian amount of flexibility when refactoring.

    I think this is one of the situations where the pain you're feeling is a sign that there's a problem, but it may not be the one you think. You said:

    "However copy/pasting scenarios for different filter tests will become repetitive and take up alot of code - something I would like to avoid. "

    First, I'd disagree that explaining yourself in writing is "repetitive," at least any more than it's repetitive to use specific words like "the, apple, car, etc." over and over again. The issue is: Are these words properly explaining what you're doing? If they are, and explaining your situation requires you to write out multiple scenarios, then that's just what it requires. Communication requires words, and sometimes the same ones.

    In fact, what you call "repetitive" is one of the benefits of using Gherkin and a tool like Cucumber or SpecFlow. If you're able to use that sentence over and over and over and over, it means you're not having to write the test code over and over and over and over.

    Second, are you sure you're writing a spec for the right thing? I ask only because if the number of scenarios gets out-of-hand, to the point where you have so many that a human can't follow what you write, it's possible that your spec isn't targeted at the right thing.

    A possible example of this could be how you're testing the filtering and the pagination in this scenario. Yes, you want your specs to cover full features and your site will have pagination on the same page as your filtering, but at what cost? It takes experience and practice to know when giving up on the supposed "ideal" of no-mocking, full-integration tests will yield better results.

    Third, don't think that specs are meant to be perfect coverage for every possible scenario. The scenarios are basically snapshots of state, which means that there are some features that could cover an infinitely-large set of scenarios, which is impossible. So what do you do? Write features that tell the story as best you can. Even let the story drive the development. However, details that don't translate to your specs or other cases are best left to straight-up TDD, done in addition to the specs.

    In your example, it seems that you basically are telling a story about a site that lets a user create a dynamic search against sweets and candy. They enter one of a large set of possible search criteria, click a button, and get results. Just stick to that, writing only enough specs to fulfill the story. If you're not satisfied with your coverage, clean it up with more specs or unit tests.


    Anyway, that's just my thoughts, hope it helps.

    0 讨论(0)
  • 2020-12-31 04:42

    Technically, I think you could try calling steps from within a step definition:

    Calling Steps from Step Definitions

    For example I think you could rewrite the

    Then I should see :
    | Output   |
    | <output> |
    

    To be a custom step like

    I should have output that contains <output>
    

    Where output is a comma separated list of expected values. In the custom step you could break the comma separated list into an array and iterate over it calling

    Then "I should see #{iterated_value}"
    

    You could use a similar technique to pass in lists of filters and filter values. Your example row for the king size test might look like

    | page       | filter                               | value       | output                           |
    | Sweet/List | Filter.KingSize, Filter.ContainsNuts | True, False | Yorkie King Size, Mars King Size |
    

    Or maybe

    | page       |                              filter-value-pairs | output                           |
    | Sweet/List | Filter.KingSize:True, Filter.ContainsNuts:False | Yorkie King Size, Mars King Size |
    

    That being said, you should perhaps take Darren's words to heart. I'm not really sure that this method would help the ultimate goal of having scenarios that are readable by non-developers.

    0 讨论(0)
提交回复
热议问题