{"id":550,"date":"2014-09-21T11:47:44","date_gmt":"2014-09-21T16:47:44","guid":{"rendered":"http:\/\/tiemensfamily.com\/TimOnCS\/?p=550"},"modified":"2014-09-21T11:47:44","modified_gmt":"2014-09-21T16:47:44","slug":"use-a-dsa-to-implement-your-dsl-insipired-by-cucumber","status":"publish","type":"post","link":"https:\/\/tiemensfamily.com\/timoncs\/2014\/09\/21\/use-a-dsa-to-implement-your-dsl-insipired-by-cucumber\/","title":{"rendered":"Use a DSA to implement your DSL (insipired by Cucumber)"},"content":{"rendered":"<p>This post was inspired by <a href=\"http:\/\/aslakhellesoy.com\/post\/11055981222\/the-training-wheels-came-off\">The Training Wheels Came Off<\/a> by Aslak Helles\u00f8y, author of <a href=\"http:\/\/www.amazon.com\/The-Cucumber-Book-Behaviour-Driven-Development\/dp\/1934356808\/\">The Cucumber Book<\/a>.  <\/p>\n<p>TL;DR &#8211; Use a Domain Specific (testing) API to implement your Domain Specific Language<\/p>\n<p>That article describes the motivation behind removing <a href=\"http:\/\/github.com\/cucumber\/cucumber-rails-training-wheels\">web_steps.rb<\/a> &#8212; 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: &#8220;Cucumber was designed to help developers with TDD at a higher level&#8221;.  <\/p>\n<p>The basic idea is that your .feature file should <b>not<\/b> be written like this:<\/p>\n<pre>\nScenario: Successful login\n  Given a user \"Aslak\" with password \"xyz\"\n  And I am on the login page\n  And I fill in \"User name\" with \"Aslak\"\n  And I fill in \"Password\" with \"xyz\"\n  When I press \"Log in\"\n  Then the http status should be 200\n  Then the http session cookie should not be empty\n<\/pre>\n<p>Instead, your .feature file should look like this:<\/p>\n<pre>\nScenario: Successful login\n  Given log in succeeds with a user \"Aslak\" with password \"xyz\"\n<\/pre>\n<p>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.<\/p>\n<p>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:<\/p>\n<pre>\n  @Given(\"^log in succeeds with a user \\\"([^\\\"]*)\\\" with password \\\"([^\\\"]*)\\\"$\")\n  public void log_in_succeeds(String user, String password) {\n     dsa.actionLogin(user, password);\n     dsa.checkStatus(200);\n     dsa.checkLoginCookieSet();\n  }\n<\/pre>\n<p>In essence, the approach leads to four levels of test: <\/p>\n<ol>\n<li>.feature file<\/li>\n<li>step definitions implementations<\/li>\n<li>DSA implementations<\/li>\n<li>technology library (e.g. HttpClient)<\/li>\n<\/ol>\n<p>The extra &#8220;Domain Specific Api&#8221; layer allows you to dive into the implementation-specific details without &#8220;polluting&#8221; your main .feature files with too many details.<\/p>\n<p>Reference Links:<br \/>\nFor Java, see <a href=\"https:\/\/github.com\/cucumber\/cucumber-jvm\">Cucumber-JVM<\/a>.<br \/>\nFor Ruby, see <a href=\"https:\/\/github.com\/jnicklas\/capybara\">Capybara<\/a>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post was inspired by The Training Wheels Came Off by Aslak Helles\u00f8y, author of The Cucumber Book. TL;DR &#8211; Use a Domain Specific (testing) API to implement your Domain Specific Language That article describes the motivation behind removing web_steps.rb &hellip; <a href=\"https:\/\/tiemensfamily.com\/timoncs\/2014\/09\/21\/use-a-dsa-to-implement-your-dsl-insipired-by-cucumber\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/posts\/550"}],"collection":[{"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/comments?post=550"}],"version-history":[{"count":0,"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/posts\/550\/revisions"}],"wp:attachment":[{"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/media?parent=550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/categories?post=550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tiemensfamily.com\/timoncs\/wp-json\/wp\/v2\/tags?post=550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}