{"id":149,"date":"2020-10-27T21:15:59","date_gmt":"2020-10-27T21:15:59","guid":{"rendered":"https:\/\/kenpugh.com\/blog\/?p=149"},"modified":"2021-04-26T18:44:41","modified_gmt":"2021-04-26T18:44:41","slug":"a-few-shades-of-gherkin-for-business-rules","status":"publish","type":"post","link":"https:\/\/kenpugh.com\/blog\/a-few-shades-of-gherkin-for-business-rules\/","title":{"rendered":"\u00a0 A Few Shades of Gherkin For Business Rules"},"content":{"rendered":"<p>A blog on <a href=\"https:\/\/specflow.org\/blog\/how-to-balance-coverage-precision-and-clarity-givenwhenthenwithstyle\">specflow.org<\/a> talked about ways to document scenarios for a business rule.\u00a0 \u00a0It reminded me about some aspects of blog wrote a few years ago called <a href=\"https:\/\/kenpugh.com\/blog\/six-shades-of-gherkin\/\">Six Shades of Gherkin<\/a>.\u00a0 \u00a0\u00a0Here\u2019s the business rule that was used as the example in specflow.org blog:<\/p>\n<p style=\"padding-left: 40px;\">A volume discount rule provides 10% off for purchases between 5 and 10 items, 15% for purchases between 10 and 20; and 20% above that.<\/p>\n<p>One of the issues with business rules is making sure they are understood by the entire triad (customer, developer, tester).\u00a0 \u00a0\u00a0In this example, \u00a0what is the discount for 10 items?\u00a0\u00a0 \u00a0One way to document is to use a scenario outline that gives the results for each side of each breakpoint.\u00a0 \u00a0Another important value is documenting the results at the limits and beyond.<!--more--><\/p>\n<pre>Scenario Outline: Compute discount based on number of items # Shade 1\nGiven the purchase order contains &lt;items&gt;\nWhen the user checks out\nThen the discount offered should be &lt;discount&gt;\nExamples:\n|items | discount |\n|1\u00a0\u00a0\u00a0\u00a0 |\u00a0 0%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|5\u00a0\u00a0\u00a0\u00a0 |\u00a0 0%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|6\u00a0\u00a0\u00a0\u00a0 | 10%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|9 \u00a0\u00a0\u00a0\u00a0| 10%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|10\u00a0\u00a0\u00a0 | 15%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|19\u00a0\u00a0\u00a0 | 15%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|20\u00a0\u00a0\u00a0 | 20%\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|1000\u00a0 | 20%\u00a0\u00a0\u00a0\u00a0\u00a0 |<\/pre>\n<p>I usually suggest using a separate column to give more information as to why the particular values were chosen as shown in Shade 2. \u00a0It ties the values into the business rule.\u00a0 So the scenario outline looks like the following.\u00a0\u00a0 The name \u201cnotes\u201d could be whatever you decide \u2013 \u201cdescription\u201d, etc.\u00a0\u00a0\u00a0 This column is not used by the scenario, but it could be passed to a step definition and used in an error message.<\/p>\n<pre>Scenario Outline: Compute discount based on number of items #Shade 2\nGiven the purchase order contains &lt;items&gt;When the user checks outThen the discount offered should be &lt;discount&gt;\nExamples:\n|items | discount |\u00a0 notes\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|1\u00a0\u00a0\u00a0\u00a0 |\u00a0 0%\u00a0\u00a0\u00a0\u00a0\u00a0 | less than 6\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|5\u00a0\u00a0\u00a0\u00a0 |\u00a0 0%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|6\u00a0\u00a0\u00a0\u00a0 | 10%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0 6 to 9\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | \n|9\u00a0\u00a0\u00a0\u00a0 | 10%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\n|10\u00a0\u00a0\u00a0 | 15%\u00a0\u00a0\u00a0\u00a0\u00a0 | 10 to 19\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0 \n|19\u00a0\u00a0\u00a0 | 15%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|20\u00a0\u00a0\u00a0 | 20%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0 20 +\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\n|1000\u00a0 | 20%\u00a0\u00a0\u00a0\u00a0\u00a0 | Maximum number of items | \n\n<\/pre>\n<p>Using a Scenario Outline is a common way of specifying Gherkin.\u00a0 The Given\/When\/Then statements often appear as boilerplate, particularly when there are multiple values.\u00a0 For example the steps often read \u201cGiven something is &lt;something&gt;\u201d, where the name of the header is just repeated.<\/p>\n<p>There can be efficiency issues.\u00a0 With three step definitions and each definition called for each of the eight rows in the Examples, \u00a0there are 24 calls to step definitions.<\/p>\n<p>There is another alternative shade &#8211; #3. The table with the headers is the same as for the Examples in #2.\u00a0\u00a0 However, the table now is a step table.\u00a0\u00a0 The scenario name reflects the business rule.\u00a0\u00a0\u00a0 The step text describes the inputs and the output (or outputs).\u00a0 I\u2019d like to have a Gherkin keyword called Business Rule, but that\u2019s not available. \u00a0Using the * keyword emphasizes that this is just a calculation.<\/p>\n<pre>Scenario: Compute discount for purchase order \u00a0\u00a0# Shade 3\n* Discount based on number of items in purchase order\n|items | discount |\u00a0 notes\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|1\u00a0\u00a0\u00a0\u00a0 |\u00a0 0%\u00a0\u00a0\u00a0\u00a0\u00a0 | less than 6\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|5\u00a0\u00a0\u00a0\u00a0 |\u00a0 0%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|6\u00a0\u00a0\u00a0\u00a0 | 10%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0 6 to 9\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | \n|9\u00a0\u00a0\u00a0\u00a0 | 10%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|10\u00a0\u00a0\u00a0 | 15%\u00a0\u00a0\u00a0\u00a0\u00a0 | 10 to 19\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0 \n|19\u00a0\u00a0\u00a0 | 15%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |\n|20\u00a0\u00a0\u00a0 | 20%\u00a0\u00a0\u00a0\u00a0\u00a0 |\u00a0 20 +\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\n|1000\u00a0 | 20%\u00a0\u00a0\u00a0\u00a0\u00a0 | Maximum number of items |<\/pre>\n<p>Now there is only one call to a step definition, regardless of the number of lines in the table.\u00a0 This will dramatically decrease the execution time.\u00a0\u00a0 That\u2019s important as the number of business rules grows.\u00a0\u00a0\u00a0 The developer needs to write a class with attributes whose names match the column headers.\u00a0\u00a0 The step definition will have a for loop to go through each of the rows.<\/p>\n<p>The business rule test will fail if the method does not meet all the expectations.\u00a0 You just fix the first reported failure and then continue on until all failures are fixed.\u00a0 Alternatively, you could capture the failures in the loop and do a single assert at the end.<\/p>\n<p>You can do Red-Green-Refactor by commenting out all rows except one and making it pass.\u00a0 Then uncommenting one line at a time and making all the uncommented rows pass.<\/p>\n<p>In most reporting systems, this version only counts as a single test, but don\u2019t all those values just comprise a test of a business rule?<\/p>\n<p>Here are a couple of other thoughts.\u00a0 The business rule, as provided by the business should be in the feature file. \u00a0It should be re-written if it\u2019s ambiguous. \u00a0\u00a0It could be included as a comment. For example:<\/p>\n<pre># Volume discount for purchase order rule:\u00a0\n# Provide 10% off for purchases between 5 and 9 items,\n# 15% for purchases between 10 and 19; and 20% above that.<\/pre>\n<p>In many places, business rules are given an identifier (such as BR5120).\u00a0 That could be included in the comment or the identifier, so scenarios for a particular business rule can easily be located.\u00a0\u00a0e.g.:<\/p>\n<pre>Scenario: BR5120 Volume discount purchase order<\/pre>\n<p>Try out a few of these shades and see which one you prefere.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A blog on specflow.org talked about ways to document scenarios for a business rule.\u00a0 \u00a0It reminded me about some aspects of blog wrote a few years ago called Six Shades of Gherkin.\u00a0 \u00a0\u00a0Here\u2019s the business rule that was used as the example in specflow.org blog: A volume discount rule provides 10% off for purchases between &hellip; <a href=\"https:\/\/kenpugh.com\/blog\/a-few-shades-of-gherkin-for-business-rules\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">\u00a0 A Few Shades of Gherkin For Business Rules<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-149","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/posts\/149","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/comments?post=149"}],"version-history":[{"count":4,"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/posts\/149\/revisions"}],"predecessor-version":[{"id":189,"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/posts\/149\/revisions\/189"}],"wp:attachment":[{"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/media?parent=149"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/categories?post=149"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kenpugh.com\/blog\/wp-json\/wp\/v2\/tags?post=149"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}