Search code examples
bddspecflow

BDD: Should I add multiple givens and outcomes to a single scenario or split scenarios based on outcome?


Given a scenario that tests sending a message to a 3rd-party API, I can add multiple givens and outcomes to a single scenario, for each property of the message. This makes the scenario quite complex.

I can also break these out into separate scenarios. But they really are not different scenarios.

This is a scenario with multiple givens and outcomes:

Scenario 1: An order
  Given an order
  And that has order ID equal to 42
  And that has affiliate reference equal to foo
  When the conversion for the order is sent
  Then the conversion has an ID equal to 42
  And the conversion has an affiliate ID equal to foo

And here I have broken it up into multiple scenarios:

Scenario 1: An order with a specific order ID
  Given an order that has order ID equal to 42
  When the conversion for the order is sent
  Then the conversion has an ID equal to 42

Scenario 2: An order with a specific affiliate reference
  Given an order that has affiliate reference equal to foo
  When the conversion for the order is sent
  Then the conversion has an affiliate ID equal to foo

Solution

  • Try having a conversation with someone in the business about the order. Ask them for an example of the kind of order that has an affiliate reference.

    If they naturally talk about an order with a certain ID and affiliate reference, and those two things come together, it's fine to put it in one scenario. You'll probably hear them talk about both things in the same clause, for instance:

    Bus: So, when we send the order for conversion, it should have the same ID and affiliate reference.

    MvO: Can you give me an example of those? The ID and affiliate reference?

    Bus: Sure, an ID is a simple integer, so, 42, and the affiliate reference is the name of our affiliate, so something like 'Foo'.

    (By the way, use realistic affiliate names if you can - it makes it easier for the business to spot if you've missed something!)

    When we convert this to Gherkin, keeping the language as natural as possible (I wrote a blog post on this), we get something like:

    Given an order with ID 42 and affiliate reference "foo"
    When we send the order for conversion
    Then the conversion should have the same ID and affiliate reference.
    

    If, however, there are some orders which don't have affiliate references, or retaining the affiliate reference is a completely separate capability and the business talk about it separately, probably you want two scenarios.

    Note there are some other benefits to talking to your business representatives!

    First, they'll probably phrase the "when" in the active voice (we send the order) rather than the passive (the order is sent) which makes it much easier to see who's doing what. This is especially important in scenarios with multiple roles, and helps us think about who or what triggers the outcome. (Here's a blog post about tenses and voices in BDD.)

    Second, you get a chance to question them! "Are there any orders which don't have affiliate references? Do all orders have IDs like that, or do you have some old orders with old-style IDs floating around in the system?" And so forth. If you can't think of questions to ask easily, bring a tester with you. Testers are great at thinking of questions to ask. (I wrote a blog post on this, too.)

    Third, you're more likely to carry the same language the business use into the code, so it's going to be easier to maintain, and you'll be able to have conversations about it more easily too.

    If your business aren't actually interested in conversations around what the API does then don't use Gherkin-based tools for the API tests. You can maintain a little DSL in plain old XUnit much more easily than in English.

    To cover your question more generically: yes, it's fine to have multiple givens and outcomes in a scenario. I generally reckon that once you've got more than seven steps, you want to be splitting it into separate scenarios.

    Make sure you have conversations around the scenarios, though, because a lot of these problems go away when you do.