{"id":5631,"date":"2017-12-14T20:20:22","date_gmt":"2017-12-14T20:20:22","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=5631"},"modified":"2017-12-14T20:20:22","modified_gmt":"2017-12-14T20:20:22","slug":"the-gherkin-language","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/the-gherkin-language\/","title":{"rendered":"The Gherkin language"},"content":{"rendered":"<p>Gherkin is a DSL used within BDD development. It&#8217;s used along with Cucumber which processes the DSL or in the case of .NET we can use tools such as SpecFlow (which I posted about a long time back, see <a href=\"http:\/\/putridparrot.com\/blog\/starting-out-with-specflow\/\" rel=\"noopener\" target=\"_blank\">Starting out with SpecFlow<\/a>) to help generate files and code.<\/p>\n<p>Gherkin allows us to create the equivalent of use cases in a human readable form, using a simple set of keywords and syntax which can then be use to generate a series of method calls to undertake some action and assertion. <\/p>\n<p><strong>Getting started<\/strong><\/p>\n<p>We can use a standard text editor to create Gherkin&#8217;s feature files, but if you prefer syntax highlighting and intellisense (although this language we&#8217;re using is pretty simple) then install SpecFlow into Visual Studio or add a Gherkin syntax highlighter into VSCode (for example) or just use your preferred text editor.<\/p>\n<p>I&#8217;m going to create a feature file (with the .feature extension) using the SpecFlow item template, so we have a starting point which we can then work through. Here&#8217;s the file generated code<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nFeature: Add a project\r\n\tIn order to avoid silly mistakes\r\n\tAs a math idiot\r\n\tI want to be told the sum of two numbers\r\n\r\n@mytag\r\nScenario: Add two numbers\r\n\tGiven I have entered 50 into the calculator\r\n\tAnd I have entered 70 into the calculator\r\n\tWhen I press add\r\n\tThen the result should be 120 on the screen\r\n<\/pre>\n<p>What we have here is a <em>Feature<\/em> which is meant to describe a single piece of functionality within an application. The feature name should be on the same line as the <em>Feature:<\/em> keyword.<\/p>\n<p>In this example, we&#8217;ve defined a feature which indicates our application will have some way to add a project within our application. We can now add an optional description, which is exactly what the SpecFlow template did for us. The Description may span multiple lines (as can be seen above with the lines under the <em>Feature<\/em> line being the description) and should be a brief explanation of the specific feature or use case. Whilst the aim is to be brief, it should include acceptance criteria and any relevant information such as user permissions, roles or rules around the feature. <\/p>\n<p>Let&#8217;s change our feature text to be a little meaningful to our use case.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nFeature: Add a project\r\n\r\n\tAny user should be able to create\/add a new project\r\n\tas long as the following rules are met\r\n\r\n\t1. No duplicate project names can exist\r\n\t2. No empty project names should be allowed\r\n<\/pre>\n<p>I&#8217;m sure with a little thought I can come up with more rules, but you get the idea. <\/p>\n<p>The description of the feature is a useful piece of documentation and can be used as a specification\/acceptance criteria.<\/p>\n<p>Looking at the generated feature code, we can see that SpecFlow also added <em>@mytag<\/em>. Tags allow us to group scenarios. In terms of our end tests, this can be seen as a way of grouping features, scenarios etc. Multiple tags may be applied to a single feature or scenario etc. for example<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n@project @mvp\r\nFeature: Add a project\r\n<\/pre>\n<p><em>I don&#8217;t need any tags for the feature I&#8217;m implementing here, so I&#8217;ll delete that line of code.<\/em><\/p>\n<p>The <em>Scenario<\/em> is where we define each specific scenario of a feature and the steps to be taken\/expected. The <em>Scenario<\/em> takes a similar form to a <em>Feature<\/em>, i.e. Scenario: and then a description of the context. <\/p>\n<p>Following the <em>Scenario<\/em> line, we then begin to define the steps that make up our scenario, using the keywords <em>Given<\/em>, <em>When<\/em>, <em>Then<\/em>, <em>And<\/em> and <em>But<\/em>. <\/p>\n<p>In unit testing usage, we can view <em>Given<\/em> as a precondition or setup. <em>When<\/em>, <em>And<\/em> and <em>But<\/em> as actions (where <em>But<\/em> is seen as a negation) and this leaves <em>Then<\/em> as an assertion.<\/p>\n<p>Let&#8217;s just change to use some of these steps in a more meaningful manner within the context of our <em>Scenario<\/em><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario: Add a project to the project list\r\n\tGiven I have added a valid project name\r\n\tWhen I press the OK button\r\n\tThen the list of projects should now include my newly added project\r\n<\/pre>\n<p>Eventually, if we generate code from this feature file, each of these steps would get turned into a set of methods which could be used as follows<\/p>\n<ul>\n<li>Given becomes an action to initialize the code to the expected context<\/li>\n<li>When becomes an action to set-up any variables, etc.<\/li>\n<li>Then becomes an assertion or validate any expectations<\/li>\n<\/ul>\n<p>Multiple <em>When<\/em>&#8216;s can be defined using the <em>And<\/em> keyword, for example imagine our <em>Scenario<\/em> looked like this<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario: Add a project to the project list\r\n\tGiven I have added a valid project name\r\n\tWhen I press the OK button\r\n\tAnd I checked the Allow checkbox\r\n\tThen the list of projects should now include my newly added project\r\n<\/pre>\n<p>Now in addition to the <em>When I press the OK button<\/em> step I would also get another <em>When<\/em> created, as the <em>And<\/em> keyword simply becomes another <em>When<\/em> action. In essence the <em>And<\/em> duplicates the previous keyword.<\/p>\n<p>We can also include the <em>But<\/em> keyword. As we&#8217;ve seen <em>And<\/em>, this is really another way of defining a additional <em>When<\/em> steps but in a more human readable way, <em>But<\/em> works in the same way as the <em>And<\/em> keyword by simply creating another <em>When<\/em> step in generated code, however <em>But<\/em> should be viewed as a negation step, for example<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario: Add a project to the project list\r\n\tGiven I have added a valid project name\r\n\tWhen I press the OK button\r\n\tBut the Do Not Allow checkbox is unchecked\r\n\tThen the list of projects should now include my newly added project\r\n<\/pre>\n<p>Finally, as stated earlier, <em>Then<\/em> can be viewed as a place to write our assertions or simply check if the results matches our expectations. We can again use <em>And<\/em> after the <em>Then<\/em> to create multiple then steps and thus assert multiple expectations, for example<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario: Add a project to the project list\r\n\tGiven I have added a valid project name\r\n\tWhen I press the OK button\r\n\tBut the Do Not Allow checkbox is unchecked\r\n\tThen the list of projects should now include my newly added project\r\n        And the list of project should increase by 1\r\n<\/pre>\n<p><strong>More keywords<\/strong><\/p>\n<p>In the previous section we covered the core keywords of Gherkin for defining our features and scenarios. But Gherkin also includes the following<\/p>\n<p>Background, Scenario Outline and Examples. <\/p>\n<p>The Background keyword is used to define reusable <em>Given<\/em> steps, i.e. if all our scenarios end up requiring the application to be in edit mode we might declare a background before any scenarios, such as this<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nBackground:\r\n\tGiven the projects list is in edit mode\r\n\tAnd the user clicks the Add button\r\n<\/pre>\n<p>we&#8217;ve now created a sort of, top level scenario which is run before each <em>Scenario<\/em>.<\/p>\n<p>The <em>Scenario Outline<\/em> keywords allow us to define a sort of scenario function or template. So, if we have multiple scenarios which only differ in terms of data being used, then we can create a <em>Scenario Outline<\/em> and replace the specific data points with variables. <\/p>\n<p>For example let&#8217;s assume we have scenarios which actually define multiple project names to fulfil the feature&#8217;s two rules (we outlined in the feature). Let&#8217;s assume we always have a project named &#8220;Default&#8221; within the application and therefore we cannot duplicate this project name. We also cannot enter a &#8220;&#8221; project name. <\/p>\n<p>If we write these as two scenarios, then we might end up with the following <\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario: Add a project to the project list with an empty name\r\n\tGiven the project name &quot;&quot;\r\n\tWhen I press the OK button\r\n\tThen the project should not be added\r\n\r\nScenario: Add a project to the project list with a duplicate name\r\n\tGiven the project name &quot;Default&quot;\r\n\tWhen I press the OK button\r\n\tThen the project should not be added\r\n<\/pre>\n<p><em>If we include values within quotation marks or include numbers within our steps, then these will become arguments to the methods generated for these steps. This obviously offers us a way to reuse such steps or use example data etc.<\/em><\/p>\n<p>Using a <em>Scenario Outline<\/em> these could be instead defined as<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario Outline: Add a project to the project list with an invalid name\r\n\tGiven the project name &lt;project-name&gt;\r\n\tWhen I press the OK button\r\n\tThen the project should not be added\r\n\r\n\tExamples: \r\n\t| project-name |\r\n\t| &quot;&quot;           |\r\n\t| &quot;Default&quot;    |\r\n<\/pre>\n<p>The &lt;&gt; acts as placeholders and the string within can be viewed as a variable name. We then define <em>Examples<\/em> which becomes our data inputs to the scenario. <\/p>\n<p>Gherkin also includes the # for use to start a new line and mark it as a comment, multiple lines may be commented out using triple quotation marks, such as &#8220;&#8221;&#8221;. Here&#8217;s a example of usage<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n# This is a comment\r\n\t\r\nScenario Outline: Add a project to the project list  with an invalid name\r\n\tGiven the project name &lt;project-name&gt;\r\n\t&quot;&quot;&quot;\r\n\tGiven the project name &lt;project-id&gt;\r\n\t&quot;&quot;&quot;\r\n\tWhen I press the OK button\r\n\tThen the project should not be added\r\n\r\n\tExamples: \r\n\t| project-name |\r\n\t| &quot;&quot;           |\r\n\t| &quot;Default&quot;    |\r\n<\/pre>\n<p>It should be noted that after listing these different keywords and their uses you can also create a scenario that&#8217;s a <em>Given<\/em> followed by a <em>Then<\/em>, in other words a setup step followed by an assertion, if this is all you need. <\/p>\n<p>For example<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nScenario: Add a project\r\n\tGiven A valid project name\r\n        Then the project list should increase by 1\r\n<\/pre>\n<p><strong>SpecFlow specifics<\/strong><\/p>\n<p>On top of the standard Gherkin keywords, SpecFlow adds a few bits.<\/p>\n<p>The @ignore tag is used by SpecFlow to generate ignored test methods.<\/p>\n<p>SpecFlow has also add Scenario Template as a synonym to Scenario Outline. Like wise Scenarios is a alternate to Examples.<\/p>\n<p><strong>Code generation<\/strong><\/p>\n<p>We&#8217;re not going to delve into Cucumber or the SpecFlow generated code except to point out that if you define more than one step within a scenario with the same text, this will generate a call to the same method in code. So whilst you might read a scenario as if it&#8217;s a new context or the likes, ultimately the code generated will execute the same method.<\/p>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"https:\/\/cucumber.io\/docs\/reference\" rel=\"noopener\" target=\"_blank\">Gherkin Reference<\/a><br \/>\n<a href=\"https:\/\/specflow.org\/documentation\/Using-Gherkin-Language-in-SpecFlow\/\" rel=\"noopener\" target=\"_blank\">Using Gherkin Language In SpecFlow<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Gherkin is a DSL used within BDD development. It&#8217;s used along with Cucumber which processes the DSL or in the case of .NET we can use tools such as SpecFlow (which I posted about a long time back, see Starting out with SpecFlow) to help generate files and code. Gherkin allows us to create the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[194,33],"tags":[],"class_list":["post-5631","post","type-post","status-publish","format-standard","hentry","category-gherkin","category-specflow"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5631","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=5631"}],"version-history":[{"count":16,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5631\/revisions"}],"predecessor-version":[{"id":5647,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5631\/revisions\/5647"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=5631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=5631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=5631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}