Search code examples
bddscenarios

Best practise for many steps in one scenario outline


So I have a page where I have many buttons/ sliders/ inputs etc. I need almost every one of these buttons/slider... to create some form at the end of the page. How can I handle that situation in BDD when I have several steps needed to finish the case? Also in the end I'm doing assertions for every step is it a proper approach? Also, I want to change the values in Examples: table just to check different conditions/states.

This is a small part of my code:

    And as a deeplink url input "<deeplink_url_on_news_feed_banner>"
    And enter "<display_priority_on_news_feed>" as a display priority number
    And click cta on news feed banner
    And input cta text into cta news banner "<cta_text_news_banner>"
    And from the news_feed banner choose art file button
    And select available banner second
    And click create button
    Then announcement form has been created with valid announcement_name
    Then compare platform selection to announcement not the archive table    
    Then compare segment string "<segment_string>" to text in announcement 
    Then compare display priority number "<display_priority_number>" to text 
    Then compare deep link url "<deeplink_url>" to deep link url in 
    Then compare amount of cool down "<minutes>" to minutes in announcement ta

This above looks ugly maybe there is something I could do better?

I cannot separate these steps into small stories cos I need to have almost all buttons selected or no to create a form.


Solution

  • This is where using a Gherkin table is beneficial. Looking at your scenario, some of the inputs are parameterized. Others are essentially "hard coded" or constant between scenarios. There are two basic strategies that give you a balance between terseness and compose-ability of steps.

    When I see a step like And select available banner second I immediately think "this scenario requires a banner — any banner — and I don't care which banner is selected as long as a banner gets selected."

    Phrasing your step using a table allows you to specify the values in your scenario while providing defaults for the other necessary values you don't care about:

    When I create the following foo
        | Field                   | Value                              |
        | Deep link URL           | <deeplink_url_on_news_feed_banner> |
        | Display priority number | <display_priority_on_news_feed>    |
        | CTA news banner         | <cta_text_news_banner>             |
    

    The step definition would have a Table object as its last argument, and you can access the values one-by-one. For the required fields your scenario doesn't care about, you'll have an empty or null string. If you encounter an empty value, like for the "available banner" then your step definition could just choose an intelligent default (like the second available banner).

    The advantage is you can choose intelligent defaults for fields your current scenario doesn't care about, and shorten the scenario up. The disadvantage is you have some "magic" going on behind the scenes where required fields are given dummy data.

    The other strategy is to give generic steps for the other required fields, in conjunction with the new step above. Then there is no "magic" going on:

    When I create the following foo
        | Field                   | Value                              |
        | Deep link URL           | <deeplink_url_on_news_feed_banner> |
        | Display priority number | <display_priority_on_news_feed>    |
        | CTA news banner         | <cta_text_news_banner>             |
    And I choose a news feed banner
    

    The I choose a news banner step would replace the 4 procedural steps for choosing a banner:

    And click cta on news feed banner
    And input cta text into cta news banner "<cta_text_news_banner>"
    And from the news_feed banner choose art file button
    And select available banner second
    

    The When I choose a news feed banner step would implement the gritty details of navigating the user interface in order to choose a news feed banner.

    You assertion can be cleaned up a little too:

    Then the following announcement should exist:
        | Field                | Value                     |
        | Segment              | <segment_string>          |
        | Display priority     | <display_priority_number> |
        | Deep link URL        | <deeplink_url>            |
        | Cool down in minutes | <minutes>                 |
    

    Similar to the When step above, you can use the Gherkin table object to do your comparison.

    The other Then steps are about as concise as you can make them. You can only go so far to clean up your steps. Sometimes a scenario is just long. You can break it up into individual scenarios and only have a single assertion. This can make each scenario shorter, but then you end up with more scenarios. It's a balancing act.