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:
- .feature file
- step definitions implementations
- DSA implementations
- 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.