rubycucumberbddacceptance-testinggherkin

What Is the correct syntax for writing test definitions in Cucumber?


What is the actual syntax for writing step definitions in Cucumber? I have seen it being written in different ways. Is there no definite syntax? I know the anchors are not compulsory, but is there a basic rule?

I am new to Cucumber and will appreciate baby step information to help me understand the basics. Thanks guys!


Solution

  • I was planning to point you to online documentation, but the online documentation I know about (at cucumber.io and at relishapp.com) doesn't actually answer your question well. (It does contain many examples, though, and is well worth reading.)

    In the Ruby implementation of Cucumber, step definition files are .rb files in the features/step_definition directory. They contain a series of calls to methods that each define an implementation of a Gherkin step. Here's an example:

    Given /^there is a user named "(.*)"$/ do |username|
      # code that creates a user with the given username
    end
    

    There are several methods that define steps: Given, When, Then, And and But. They all do exactly the same thing, and you can use any one to define any step. The best practice is to use the one that reads best with the step you're defining (never And or But).

    The argument passed to the step-defining method is a regular expression intended to match one or more steps in Gherkin .feature files. The above example matches the following step:

    Given there is a user named "Ade Tester"
    

    ("Ade Tester" could be anything).

    The block passed to the step-defining method is run when Cucumber executes a step which the regular expression matches. It can contain any Ruby code you like.

    Matching groups (enclosed in parentheses) in the regular expression are passed to the block as block parameters. The number of matching groups must match the number of block parameters, or you'll get an error. A common convention is to enclose matching groups that match strings in quotes to visually separate them from the fixed part of the step, as I did above, but this is purely convention and you can choose not to do it.

    The regexp need not match the entire step by default. If you want a definition to match only the entire step you must enforce that in the regular expression, as I did in the example above with ^ and $. Do that unless you have a good reason not to. This step definition (without $)

    Given /^there is a user named "(.*)"/ do |username|
      create :user, username: username
    end
    

    would match

    Given there is a user named "Ade Tester" on weekdays but "Dave Schweisguth" on weekends
    

    which would probably be a bad idea. Worse, if you had definitions for both steps, Cucumber would not be able to tell which definition to use and you'd get an error.


    In features/step_definitions/documentation.rb:

    When /^I go to the "([^"]+)" documentation$/ do |section|
      path_part =
        case section
          when "Documentation"
            "documentation"
          else
            raise "Unknown documentation section: #{section}"
        end
      visit "/documentation/#{path_part}/topics"
    end
    
    Then /^I should see the "([^"]+) documentation"$/ do |section|
      expect(page).to have_css('h2.doctag_title a', text: section)
    end
    

    These steps exercise a web application. They are about as simple as they can be while still being practical.