Use a DSA to implement your DSL (insipired by Cucumber)

This post was inspired by The Training Wheels Came Off by Aslak Hellesøy, author of The Cucumber Book.

TL;DR – Use a Domain Specific (testing) API to implement your Domain Specific Language

That article describes the motivation behind removing web_steps.rb — in a nutshell, they were removed because these step definitions are not at the correct level of abstraction for a properly defined Cucumber .feature file. The direct quote on the subject: “Cucumber was designed to help developers with TDD at a higher level”.

The basic idea is that your .feature file should not be written like this:

Scenario: Successful login
  Given a user "Aslak" with password "xyz"
  And I am on the login page
  And I fill in "User name" with "Aslak"
  And I fill in "Password" with "xyz"
  When I press "Log in"
  Then the http status should be 200
  Then the http session cookie should not be empty

Instead, your .feature file should look like this:

Scenario: Successful login
  Given log in succeeds with a user "Aslak" with password "xyz"

Notice at this level, there is no mention of http, http status 200, cookies, buttons or button names, etc. It describes only the high-level test.

In his article, he codes to the idea in this post, but never names explicitly says it. The idea: keep your .feature definitions high-level, and implement your step definitions using a set of intermediate helper methods. This intermediate level is what I call the Domain Specific API (DSA) from my title. It looks like this:

  @Given("^log in succeeds with a user \"([^\"]*)\" with password \"([^\"]*)\"$")
  public void log_in_succeeds(String user, String password) {
     dsa.actionLogin(user, password);
     dsa.checkStatus(200);
     dsa.checkLoginCookieSet();
  }

In essence, the approach leads to four levels of test:

  1. .feature file
  2. step definitions implementations
  3. DSA implementations
  4. technology library (e.g. HttpClient)

The extra “Domain Specific Api” layer allows you to dive into the implementation-specific details without “polluting” your main .feature files with too many details.

Reference Links:
For Java, see Cucumber-JVM.
For Ruby, see Capybara.

This entry was posted in Software Engineering. Bookmark the permalink.