{"id":9949,"date":"2023-04-02T11:17:09","date_gmt":"2023-04-02T11:17:09","guid":{"rendered":"https:\/\/putridparrot.com\/blog\/?p=9949"},"modified":"2023-04-02T11:17:09","modified_gmt":"2023-04-02T11:17:09","slug":"generic-steps-using-regular-expressions-within-specflow","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/generic-steps-using-regular-expressions-within-specflow\/","title":{"rendered":"Generic steps using regular expressions within SpecFlow"},"content":{"rendered":"<p>The use case I have is as follows. <\/p>\n<p>Using SpecFlow for running UI automation tests, we have lots of views off of the main application Window, we might write out scenarios specific to each view, such as <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nGiven Trader view, set fields\r\nGiven Middle Office view, set fields\r\nGiven Sales view, set fields\r\n<\/pre>\n<p>and these in turn are written as the following steps<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;Trader view, set fields&quot;)]\r\npublic void GivenTraderViewSetFields()\r\n{\r\n  \/\/ set the fields on the trader view\r\n}\r\n\r\n&#x5B;Given(@&quot;Middle Office view, set fields&quot;)]\r\npublic void GivenMiddleOfficeViewSetFields()\r\n{\r\n  \/\/ set the fields on the middle office view\r\n}\r\n\r\n&#x5B;Given(@&quot;Sales view, set fields&quot;)]\r\npublic void GivenSalesViewSetFields()\r\n{\r\n  \/\/ set the fields on the sales view\r\n}\r\n<\/pre>\n<p>obviously this fine, but if all our views had the same automation steps to set fields, then the code within will be almost exactly the same, so we might prefer to rewrite the step code to be more generic<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;(.*) view, set fields&quot;)]\r\npublic void GivenViewSetFields(string viewName)\r\n{\r\n  \/\/ find the view and set the fields using same automation steps\r\n}\r\n<\/pre>\n<p>This is great, we&#8217;ve reduced our step code, but the (.*) accepts any value which means that if we have a view which doesn&#8217;t support the same steps to set fields, then this might confuse the person writing the test code. So we can change the (.*) to restrict the view names like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;(Trader|Middle Office|Sales) view, set fields&quot;)]\r\npublic void GivenViewSetFields(string viewName)\r\n{\r\n  \/\/ find the view and set the fields using same automation steps\r\n}\r\n<\/pre>\n<p>Now if you add a new view like the step below, your SpecFlow plugin will highlight it as not having a matching step and if you run the test you&#8217;ll get the &#8220;No matching step definition found for one or more steps.&#8221; error.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nGiven Admin view, set fields\r\n<\/pre>\n<p>We can ofcourse write a step like the following code, and now the test works<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;Admin view, set fields&quot;)]\r\npublic void GivenAdminViewSetFields()\r\n{\r\n}\r\n<\/pre>\n<p>But this looks different in the code highlighting via the SpecFlow extension to our IDE but also, what if Admin and Settings views both can use the same automation steps, then we&#8217;re again back to creating steps per view. <\/p>\n<p>Yes, we could reuse the actual UI automation code, but I want to reduce the number of steps also to a minimum. SpecFlow allows, what we might think of as regular expression overrides, so let&#8217;s change the above to now look like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;(Admin|Settings) view, set fields&quot;)]\r\npublic void GivenAdminViewSetFields(string viewName)\r\n{\r\n}\r\n<\/pre>\n<p>Obviously we cannot have the same method name with the same arguments in the same class, but from the Feature\/Scenario design perspective it now appears that we&#8217;re writing steps for the same method whereas in fact each step is routed to the method that understands how to automate that specific view. <\/p>\n<p>This form of regular expression override also means we might have the method for Trader, Middle Office and Sales in one step definition file and the Admin, Settings method in another step definition file making the separation more obvious (and ofcourse allowing us to then use the same method name).<\/p>\n<p>What&#8217;s also very cool about using this type of expression is the the SpecFlow IDE plugins, will show via autocomplete, that you have a &#8220;Admin view, set fields&#8221;, &#8220;Trader view, set fields&#8221; etc. steps .<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The use case I have is as follows. Using SpecFlow for running UI automation tests, we have lots of views off of the main application Window, we might write out scenarios specific to each view, such as Given Trader view, set fields Given Middle Office view, set fields Given Sales view, set fields and these [&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":[33],"tags":[],"class_list":["post-9949","post","type-post","status-publish","format-standard","hentry","category-specflow"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9949","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=9949"}],"version-history":[{"count":2,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9949\/revisions"}],"predecessor-version":[{"id":9951,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9949\/revisions\/9951"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=9949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=9949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=9949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}