Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

We had a need to have a Cucumber example that tested several different steps in one pass. We then needed to make several different passes across the tests with different data elements. We had been using Examples before, but this took it to a whole new level. We defined a datatable for each step with variables that then were retrieved from a main examples datatable that had all of the data for all of the steps for this run.

The feature files looks like:

Feature: Logging in to play for real and fun money and retrieve player wallet

  @2015r16.3 @US5064
  Scenario Outline: Full register player can launch a casino game to play for real or fun money. In this scenario in the
  back end the player launch a game for real or fun (demo) the we auth the player and retrieve the wallet

    Given I am a fully registered user
    And I am authenticated
    Then I want to create an ACH account at the time of deposit with following details:
      | Routing Number             | <routing_number>   |
      | Account Nickname           | <account_nickname> |
      | Deposit Amount             | <deposit_amount>   |
      | Account Type               | <account_type>     |
      | Agree Terms And Conditions | <agree_t_and_c>    |
    Then my account balance is correct
      | Cash Balance | <deposit_amount> |
    When I get a game launch Url
      | External Game ID | <game_id_external> |
      | Aggregator ID    | <id_aggregator>    |
      | Game Mode        | <game_mode>        |
    And I am authenticated via the remote game server
      | Authorization Status | <auth_status> |
    Then the game should retrieve the wallet and verify the cash balance
      | Cash Balance | <deposit_amount> |
    Then I play the game
      | First Wager Amount        | <firstWagerAmount>       |
      | First Win Amount          | <firstWinAmount>         |
      | First Ending Cash Balance | <firstEndingCashBalance> |
    Then I play the game
      | Second Wager Amount        | <secondWagerAmount>       |
      | Second Win Amount          | <secondWinAmount>         |
      | Second Ending Cash Balance | <secondEndingCashBalance> |
    Then I cleanup the gaming records

    Examples:
      | routing_number | account_nickname | deposit_amount | account_type | agree_t_and_c | game_id_external | id_aggregator | game_mode | auth_status | firstWagerAmount | firstWinAmount | firstEndingCashBalance |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Dragons    | gsi           | DEMO      | SUCCESS     | 10               | 0              | 85                     |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Dragons    | gsi           | REAL      | SUCCESS     | 10               | 0              | 85                     |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Lions      | gsi           | REAL      | SUCCESS     | 10               | 0              | 85                     |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Lions      | gsi           | DEMO      | SUCCESS     | 10               | 0              | 85                     |

Let’s look at the step

Then I want to create an ACH account at the time of deposit with following details:

The datatable contains the following data. Think of the elements on the left as the keys in a map and the elements on the right as the corresponding values.

      | Routing Number             | <routing_number>   |
      | Account Nickname           | <account_nickname> |
      | Deposit Amount             | <deposit_amount>   |
      | Account Type               | <account_type>     |
      | Agree Terms And Conditions | <agree_t_and_c>    |

In this case, the corresponding values are within < and >. This tells Cucumber to look up the actual value in the Examples: datatable.

    Examples:
      | routing_number | account_nickname | deposit_amount | account_type | agree_t_and_c | game_id_external | id_aggregator | game_mode | auth_status | firstWagerAmount | firstWinAmount | firstEndingCashBalance |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Dragons    | gsi           | DEMO      | SUCCESS     | 10               | 0              | 85                     |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Dragons    | gsi           | REAL      | SUCCESS     | 10               | 0              | 85                     |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Lions      | gsi           | REAL      | SUCCESS     | 10               | 0              | 85                     |
      | 011000015      | MyNewACHAccount  | 95             | chk          | true          | aris50Lions      | gsi           | DEMO      | SUCCESS     | 10               | 0              | 85                     |

For our examples test, we are going to send a map containing the following key/value data:

  • Routing Number -> 011000015
  • Account Nickname -> MyNewACHAccount
  • Deposit Amount -> 95
  • Account Type -> chk
  • Agree Terms and Conditions -> true

Now for the nitty gritty. This is what the step definition looks like:

    @Given("^I want to create an ACH account at the time of deposit with following details:$")
    public void I_want_to_create_an_ACH_account_at_the_time_of_deposit_with_following_details(Map<String, String> tableData) throws Throwable {
        assertTrue(tableData.containsKey("Routing Number"));
        assertTrue(tableData.containsKey("Account Nickname"));
        assertTrue(tableData.containsKey("Deposit Amount"));
        assertTrue(tableData.containsKey("Account Type"));
        assertTrue(tableData.containsKey("Agree Terms And Conditions"));


        achCashierModel.setRoute(tableData.get("Routing Number"));
        achCashierModel.setLabel(tableData.get("Account Nickname"));
        achCashierModel.setAcceptedTerms("true".equals(tableData.get("Agree Terms And Conditions")));
        achCashierModel.setIdAchType(tableData.get("Account Type"));
        achCashierModel.setTransactionAmountString(tableData.get("Deposit Amount"));

        // do some testing stuff
    }

The method takes Map tableData as the method parameter. From here on, you can access it like a regular map. In this case, the first thing the step does is verify that the correct input values were specified. To use them, a normal map.get() is called.

That’s for a single pass through the tests. Notice, that in our Examples: table, we have four rows of data. What this means is that there are 4 whole tests of data. In my feature file in my IDE, the rows of data are on lines 37, 38, 39 and 40. Here is the kind of data is produced.

Feature: CasinoGame: 28 total, 28 passed 51.51 s
    Feature: Logging in to play for real and fun money and retrieve player wallet
        Scenario Outline: Full register player can launch a casino game to play for real or fun money. In this scenario in the
            Examples:
                Scenario: Line: 37
                    Given I am a fully registered user -- passed
                    And I am authenticated -- passed
                    Then I want to create an ACH account at the time of deposit with the following details: -- passed
                    Then my account balance is correct -- passed
                    When I get a game launch Url -- passed
                    And I am authenticated via the remote game server -- passed
                    Then the game should retrieve the wallet and verify the cash balance -- passed
                Scenario: Line: 38
                    Given I am a fully registered user -- passed
                    And I am authenticated -- passed
                    Then I want to create an ACH account at the time of deposit with the following details: -- passed
                    Then my account balance is correct -- passed
                    When I get a game launch Url -- passed
                    And I am authenticated via the remote game server -- passed
                    Then the game should retrieve the wallet and verify the cash balance -- passed
                Scenario: Line: 39
                    Given I am a fully registered user -- passed
                    And I am authenticated -- passed
                    Then I want to create an ACH account at the time of deposit with the following details: -- passed
                    Then my account balance is correct -- passed
                    When I get a game launch Url -- passed
                    And I am authenticated via the remote game server -- passed
                    Then the game should retrieve the wallet and verify the cash balance -- passed
                Scenario: Line: 40
                    Given I am a fully registered user -- passed
                    And I am authenticated -- passed
                    Then I want to create an ACH account at the time of deposit with the following details: -- passed
                    Then my account balance is correct -- passed
                    When I get a game launch Url -- passed
                    And I am authenticated via the remote game server -- passed
                    Then the game should retrieve the wallet and verify the cash balance -- passed


August 21st, 2015

Posted In: Cucumber, Java, java ninja, Javaninja

Tags:

2 Comments

  • Yogiraj says:

    Hi,
    i’m trying the same thing as explained here but i’m getting following error,
    initializationError(test_runner.runCukesTest) Time elapsed: 0.015 sec <<< ERROR!
    java.lang.IndexOutOfBoundsException: Index: 8, Size: 8
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at cucumber.runtime.model.CucumberScenarioOutline.replaceTokens(CucumberScenarioOutline.java:117)
    at cucumber.runtime.model.CucumberScenarioOutline.createExampleScenario(CucumberScenarioOutline.java:57)

  • Aman says:

    Hello
    Any idea how can we have nested data.
    Example
    I have a class cabinet, and it can have List of TShirts, List of Trousers
    class Cabinet{
    List tshirts;
    List trousers;
    }
    class Tshirt{
    String color; String size etc….}

    how do I specify multiple values for TShirt in example, apart from giving TShirtColor1, TShirtColor2 etc

Leave a Reply

Your email address will not be published. Required fields are marked *

LinkedIn Auto Publish Powered By : XYZScripts.com