<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ministry of Testing</title>
    <description>The latest articles on Forem by Ministry of Testing (@ministryoftesting).</description>
    <link>https://forem.com/ministryoftesting</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F9385%2F6c711a5f-bda6-486e-b316-9808fb2d4d28.jpeg</url>
      <title>Forem: Ministry of Testing</title>
      <link>https://forem.com/ministryoftesting</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ministryoftesting"/>
    <language>en</language>
    <item>
      <title>Strategies to simplify your BDD step definitions</title>
      <dc:creator>Rosie Sherry</dc:creator>
      <pubDate>Fri, 08 Nov 2024 17:14:47 +0000</pubDate>
      <link>https://forem.com/ministryoftesting/strategies-to-simplify-your-bdd-step-definitions-28ch</link>
      <guid>https://forem.com/ministryoftesting/strategies-to-simplify-your-bdd-step-definitions-28ch</guid>
      <description>&lt;p&gt;Techniques to boost your efficiency for implementation, writing BDD steps definitions and glue code&lt;/p&gt;

&lt;p&gt;by Tamás Balog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fkbto9m1buv2jk30b7pthabjxachp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fkbto9m1buv2jk30b7pthabjxachp" alt=" An orange cartoon character with three eyes, dressed in a space helmet, raises its arms joyfully against a backdrop of a purple labyrinth and a starry sky. " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are a tester, you have probably heard about &lt;a href="https://cucumber.io/docs/bdd/" rel="noopener noreferrer"&gt;Behaviour-Driven Development&lt;/a&gt;, or BDD in short, and the debates around what it is, and how and what it should be used for. Regardless of what we think about the subject, we cannot deny that test automation tools built to support BDD are with us. They are adopted and used widely in the industry, and they will be with us for some time.&lt;/p&gt;

&lt;p&gt;Throughout my testing career, a great portion of my test automation activities involved using some kind of BDD test automation framework. Tools like Cucumber, JBehave and other alternatives. As someone who does coding, I’ve always been interested in refactoring to lessen the amount of boilerplate and duplicate code. This results in improved comprehension and minimising the amount of code. This includes reducing boilerplate code in step definition methods and in glue code overall. Simplifying them. Or getting rid of them entirely if possible.&lt;/p&gt;

&lt;p&gt;You may be wondering, “What is glue code?” On one hand, it consists of step definition methods. Ones that tell the BDD automation framework what to execute when it encounters a Given, When or Then step in a Gherkin feature file. Essentially glueing parts of Gherkin plain text files to executable test automation code. On the other hand, it can be hooks. Methods that execute before or after Gherkin Features or Scenarios.&lt;/p&gt;

&lt;p&gt;In this article, I’ll present various ways of simplifying glue code and integrating them closer to the language of your automated tests. In the code examples below I’ll use Cucumber and Java code snippets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard Cucumber step definitions
&lt;/h2&gt;

&lt;p&gt;First, to put you into context, let me demonstrate how a regular Cucumber step definition may look like in Java.&lt;/p&gt;

&lt;p&gt;Using regular expression as the step pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@When("^user attempts to log in with (.*) username and (.*) password$") void userAttemptsToLogInWith(String username, String password) { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or using Cucumber expression as the step pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@When("user attempts to log in with {string} username and {string} password") void userAttemptsToLogInWith(String username, String password) { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The essential parts of this method are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  one of the &lt;code&gt;@Given&lt;/code&gt;, &lt;code&gt;@When&lt;/code&gt;, &lt;code&gt;@Then&lt;/code&gt;, &lt;code&gt;@And&lt;/code&gt;, &lt;code&gt;@But&lt;/code&gt; annotations placed on the method to signal the type of the step, and make the method be recognised as a step definition,&lt;/li&gt;
&lt;li&gt;  the step pattern specified in the annotation: this is how Cucumber maps the step in a Gherkin file to this method,&lt;/li&gt;
&lt;li&gt;  the method arguments that map to the arguments of the Gherkin step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s look into the ways of simplifications and alternate usages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java 8 lambda expression-based step definitions
&lt;/h3&gt;

&lt;p&gt;With the introduction of lambda expressions in Java 8, a lot has improved and become simpler. It has brought forth alternative ways of implementing applications. This includes Cucumber as well as introducing a new way of defining step definitions using lambda expressions.&lt;/p&gt;

&lt;p&gt;For that, you have to use a different dependency, namely cucumber-java8. Once you have this configured, you have to make the following changes in your step definition classes.&lt;/p&gt;

&lt;p&gt;The class must implement the &lt;code&gt;io.cucumber.java8&lt;/code&gt;.En interface (or one of its language specific variants). With this change, new step type specific methods (&lt;code&gt;Given()&lt;/code&gt;, &lt;code&gt;When(),&lt;/code&gt; etc.) become available in your step definition class.&lt;/p&gt;

&lt;p&gt;Your current step definition methods (or at least the ones that you want to simplify) have to be converted and moved to the class constructor. So, the following method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LoginStepDefs { @When("user attempts to log in with {string} username and {string} password") void userAttemptsToLogInWith(String username, String password) { //login actions } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would become&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LoginStepDefs implements En { LoginStepDefs() { When("user attempts to log in with {string} username and {string} password", (String username, String password) -&amp;gt; { //login actions }); } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From a readability point of view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  This form eliminates the &lt;code&gt;void&lt;/code&gt; keyword and the entire method name, making the definition more concise, and quicker to implement.&lt;/li&gt;
&lt;li&gt;  However, although the code is more concise, having several step definitions shoved into the constructor can feel overcrowded and sometimes even more noisy than having them in the old-school method form.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is some debate on whether the regular method form or the lambda one is better. There are both personal preferences and practical arguments (e.g. dependency injection) put on the table, and there has even been &lt;a href="https://github.com/cucumber/cucumber-jvm/issues/2279" rel="noopener noreferrer"&gt;some discussion on replacing Cucumber’s Java8 library with an alternative solution&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Patternless step annotations
&lt;/h2&gt;

&lt;p&gt;The following questions can be made for the step annotations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Do you actually need to explicitly specify a step pattern?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Is there an alternative to still have it specified?&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Years ago, on a previous project, we had a custom test automation solution and test runner that worked somewhat differently from Cucumber and other BDD frameworks. That solution used its own &lt;code&gt;@Given&lt;/code&gt;, &lt;code&gt;@When&lt;/code&gt;, etc. annotations with one main difference: you didn’t have to specify the pattern in them. Instead you had to phrase the name of the step definition method in the way it would be used in the Gherkin files. &lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Given void userAttemptsToLogInWithXUsernameAndYPasswordOnZ(String username, String password, Server server) { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may have noticed the uppercase letters X, Y and Z. They allowed users to parameterise these methods, and it worked as the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  a regular expression was generated from the method name, where X, Y and Z would be replaced with the (&lt;code&gt;.*&lt;/code&gt;) capturing group, like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^user attempts to log in with (.*) username and (.*) password on (.*)$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  then in a follow-up step, the framework would go through the list of supported parameter type resolvers and perform the following:

&lt;ul&gt;
&lt;li&gt;  it parsed each argument (the content of each (&lt;code&gt;.*&lt;/code&gt;) group) into the corresponding type specified in the method’s argument list,&lt;/li&gt;
&lt;li&gt;  then, it injected the resolved values.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is sort of the opposite way to how Cucumber step definitions work. There, you specify the actual pattern without the method name, while here you specify the method name as a sort of pattern without specifying the actual pattern.&lt;/p&gt;

&lt;p&gt;The advantage of this was that you did not have to specify the pattern in the annotation, only in the method name. This resulted in less coding and less noisy code. But, the step annotations still provided an attribute to specify a custom pattern if the default, generated one was not sufficient.&lt;/p&gt;

&lt;p&gt;This also made engineers phrase the names of step definition methods in a way they would be used in the Gherkin files, resulting in clearer steps. It also prevented confusion regarding having a step pattern used with a different method name for no proper reason. Like something like the one below would have caused:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@When("user attempts to log in with {string} username and {string} password") void authenticate(String username, String password) { //login actions }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Leverage custom IDE integration
&lt;/h2&gt;

&lt;p&gt;Although, using a custom-developed IDE plugin does not necessarily reduce the amount of test code you have, it can at least help increase the level and easiness of code comprehension.&lt;/p&gt;

&lt;p&gt;The idea I’ll demonstrate involves a feature called code folding that is a standard one in many IDEs and text editors. Code folding is when an arbitrary range of text in a document becomes hidden (i.e. collapsible and expandable), and is replaced with a custom placeholder text that lets you know a summary of what is under that folded section.&lt;/p&gt;

&lt;p&gt;Such a placeholder text may be as simple as an ellipsis (the … symbol). This is used mostly when the content, for example a method body, is not relevant at the moment, and it just needs to be hidden.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fz02di7h7045uinb403gozjs3zf94" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fz02di7h7045uinb403gozjs3zf94" alt="A Cucumber Java step definition method whose method body is collapsed and hidden, and replaced with an ellipsis. It reads as @When(" width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or, it can be actual contextual information that provides the same or almost the same information that the actual unfolded code provides, but in a simpler way. A good example for this is folding anonymous object instantiation in Java to lambda expression style. So, given the following method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CredentialsProvider getCredentialsFor(String userType) { return new CredentialsProvider() { @Override public Credentials get() { return credentialsService.get(userType); } }; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the folded code will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fno4eejcgxtp8ccxyp2hzajbnkld1" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fno4eejcgxtp8ccxyp2hzajbnkld1" alt="It shows the previous Java method but the return statement is folded and reads like CredentialsProvider getCredentialsFor(String userType) { return () -&amp;gt; { return credentialsService.get(userType); }; }" width="646" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you’ve seen a few simple examples of code folding, let’s see some ideas on how certain parts of step definition methods may be folded to achieve a better comprehension of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a step pattern in place of the step definition method’s name
&lt;/h2&gt;

&lt;p&gt;In my experience, when it comes to reading and comprehending a step definition method, people focus on understanding it by reading the step pattern instead of the method name. So why not improve this aspect? Since the method name may be a duplicate of the step pattern, and it cannot be omitted if one uses actual methods, let’s try to make it appear in a more concise way.&lt;/p&gt;

&lt;p&gt;This involves two steps. First, fold the step pattern in the step annotation into an ellipsis like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Ft83qv74vb0uf7n6mu2rlr5fw1rkn" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Ft83qv74vb0uf7n6mu2rlr5fw1rkn" alt="Shows a version of the original login step definition where the step pattern in the @When annotation is folded, and results in the following displayed in the editor: @When(...) void userAttemptsToLogInAs(UserType userType) { }" width="420" height="102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This results in a less noisy code, and you still have the information of what type of step (Given, When or Then) this method is for.&lt;/p&gt;

&lt;p&gt;Then, if you prefer reading the step pattern, and the step pattern provides more context for the step than the method’s name, you can go one step further. Fold the method name using as placeholder text the step pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2F8y2536yw86p4yo2yiiqsgoaz73og" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2F8y2536yw86p4yo2yiiqsgoaz73og" alt="Shows a version of the original login step definition where the step pattern in the @When annotation is folded, and results in the following displayed in the editor: @When(...) void " width="548" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have the option, you can fold the public and void keywords as well, so you end up with the following method “signature”:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fw8mpklbmqogm1n4ondz3qgrenkhv" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2Fw8mpklbmqogm1n4ondz3qgrenkhv" alt="Shows a version of the original login step definition where the step pattern in the @When annotation is folded, and results in the following displayed in the editor: @When(...) void " width="534" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, if you want to, you can go further, or in a completely different direction, with the customization of this folding. This is up to your personal or project preferences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic resolution of steps
&lt;/h2&gt;

&lt;p&gt;Let’s say you have steps that have a clear formalisable format. You don’t want to deal with implementing separate step definitions for each of them because it would be an unnecessary duplication.&lt;/p&gt;

&lt;p&gt;One thing you can do in this situation, and what we did on a previous project, is using dynamic parsing and resolution of steps. This eliminated the need to implement actual step definition methods for them. We mostly used it to build validation steps for web UI test automation, like the ones below. (Screaming snake case parts reference Selenium &lt;code&gt;WebElements&lt;/code&gt; and &lt;code&gt;Bys&lt;/code&gt;.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;**Then** the TITLE of the RECOMMENDED_BOOKS module should be "Recommended books"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;**Then** the TITLE of the first item of the RECOMMENDED_BOOKS module should be "Atomic Habits"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;**Then** the second AUTHOR of the first item of the RECOMMENDED_BOOKS module should be “Noone”&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you may see, it kind of works in a backwards order. If you take the last example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  It locates the &lt;strong&gt;Recommended Books&lt;/strong&gt; module on the page the scenario is currently on. &lt;code&gt;RECOMMENDED_BOOKS&lt;/code&gt; here is mapped to a list of &lt;code&gt;WebElements&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  It gets the &lt;code&gt;first item&lt;/code&gt; from that list, which is the element of an actual book.&lt;/li&gt;
&lt;li&gt;  It gets the list of &lt;code&gt;AUTHOR&lt;/code&gt;s as strings. &lt;code&gt;AUTHOR&lt;/code&gt; here is mapped to a By object.&lt;/li&gt;
&lt;li&gt;  Then, it gets the second item from the list of authors.&lt;/li&gt;
&lt;li&gt;  Finally, it compares the found value to the expected one specified in the ‘&lt;code&gt;should be “Noone&lt;/code&gt;”’ part.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this was made possible by the implementation of a common parser logic. Once it was put in place, no coding was required to explicitly implement this kind of Gherkin steps. The only coding involved in this area were either bug fixes, improvements to the parser logic or extending the corresponding page objects.&lt;/p&gt;

&lt;p&gt;Now, of course one could argue how readable these steps are, or whether they could be replaced with visual testing. But, at that time, it provided a clear structure and format. Customisation of underlying page elements, choosing elements by index, and other goodies too. For us it was a nice way of implementing validation with a minimal amount of coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use frameworks with pre-implemented step libraries
&lt;/h2&gt;

&lt;p&gt;One way of minimising the amount of glue code is getting rid of them entirely. This may be achieved for example by using libraries that provide pre-implemented steps for many common or not so common tasks.&lt;/p&gt;

&lt;p&gt;They may also have different templating solutions and expression languages to customise steps and actions with dynamic input data, like various types of request bodies and headers for sending HTTP requests in API tests.&lt;/p&gt;

&lt;p&gt;I’m only including brief introductions of some libraries below, just to give you an idea where to begin, then I’ll let you delve into them if you are interested.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;strong&gt;Framework&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;strong&gt;Summary from the framework’s documentation&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;strong&gt;Scenarios are implemented as ...&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer nofollow" href="https://github.com/karatelabs/karate?tab=readme-ov-file#script-structure"&gt;Karate&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;“Karate is the only open-source tool to combine API test-automation, mocks, performance-testing and even UI automation into a single, unified framework. The syntax is language-neutral … in a simple, readable syntax - carefully designed for HTTP, JSON, GraphQL and XML. And you can mix API and UI test-automation within the same test script.”&lt;/td&gt;
&lt;td&gt;Gherkin Features with Karate’s own language parser (instead of Cucumbers)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer nofollow" href="https://docs.vividus.dev/vividus/latest/index.html"&gt;Vividus&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;“VIVIDUS is a test automation tool that offers already implemented solution for testing of the most popular application types.” &lt;/p&gt;
&lt;p&gt;This includes database, API (Application Programming Interface) and UI (User Interface) testing as well.&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;JBehave Stories&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer nofollow" href="https://citrusframework.org/yaks/reference/html/index.html"&gt;Citrus YAKS&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;“YAKS is a framework to enable Cloud Native BDD testing on Kubernetes! Cloud Native here means that your tests execute as Kubernetes PODs.&lt;/p&gt;
&lt;p&gt;As a framework YAKS provides a set of predefined Cucumber steps which help you to connect with different messaging transports (Http REST, JMS, Kafka, Knative eventing) and verify message data with assertions on the header and body content.”&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;Cucumber Gherkin Features&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Take scenario development to the code level
&lt;/h2&gt;

&lt;p&gt;Although this approach doesn’t get rid of step definition methods, it simplifies tests from a different, sort of the opposite, perspective of what I introduced in the previous section. Instead of implementing your tests in Gherkin or similar files, and having to bother with step definition implementations, you implement tests as actual code in a Gherkin-like DSL (Domain Specific Language). This way you don’t have to touch any actual Gherkin file. That is what the &lt;a href="https://github.com/TNG/JGiven" rel="noopener noreferrer"&gt;JGiven framework&lt;/a&gt; aims to achieve, or at least how it fits into the topic of this article.&lt;/p&gt;

&lt;p&gt;With applying some basic test configuration, and extending some base classes, you can implement “Gherkin” steps and scenarios in regular JUnit, TestNG or Spock test methods. Thus, you also have proper and direct access to the assertion, mocking, etc. libraries that you use, and your test methods would read close to actual Gherkin scenarios with test reports generated accordingly.&lt;/p&gt;

&lt;p&gt;The following one is a Given step with a more granular implementation (&lt;a href="https://jgiven.org/userguide/#_filler_words" rel="noopener noreferrer"&gt;see the corresponding section in the JGiven documentation&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test public void validate_recipe() { given().the().ingredients() .an().egg() .some().milk() .and().the().ingredient("flour"); //other steps… }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you take a more advanced scenario, the JUnit 5 test method below, it executes a parameterised test with multiple different input data. It essentially simulates the execution of a &lt;code&gt;Gherkin Scenario Outline&lt;/code&gt; with a set of input data its Examples table would receive.&lt;/p&gt;

&lt;p&gt;This example is from the &lt;a href="https://jgiven.org/userguide/#_junit_dataprovider_runner" rel="noopener noreferrer"&gt;Parameterized Scenarios section of the JGiven documentation&lt;/a&gt;, altered for conciseness and to use the more commonly used JUnit 5 parameterised test approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ParameterizedTest @CsvSource({ "1, 1", "0, 2", "1, 0" }) public void coffee_is_not_served(int coffees, int euros) { given().a_coffee_machine() .and().the_coffee_costs_$_euros(2) .and().there_are_$_coffees_left_in_the_machine(coffees); when().I_insert_$_one_euro_coins(euros) .and().I_press_the_coffee_button(); then().I_should_not_be_served_a_coffee(); }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test method would generate the following report, so you would still have proper test reports and living documentation that you can share with various stakeholders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2F3dnq4cpqe4nl2q68dem25gtl9068" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2F3dnq4cpqe4nl2q68dem25gtl9068" alt="Shows JGiven's HTML test report for the previous test method with a collapsible header called " width="800" height="362"&gt;&lt;/a&gt; coffees left in the machine When I insert  one euor coins And I press the coffee button Then I should nt be served a coffee  Underneath it shows a table with the various input data and the status of the test under a header called Cases. The first column shows the ids of the tests as 1, 2 and 3. The rest of the columns read as coffees, euros, Status. The test case rows read: 1 coffees, 1 euros, passed 0 coffees, 2 euros, passed 1 coffees, 0 euros, passed"/&amp;gt;&lt;/p&gt;

&lt;p&gt;We can take this example one step further by applying some IDE plugin magic on it. Using custom-developed code to fold in this case, you could bring your test code even closer to how an actual Gherkin scenario would read. Something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2F8l4wmebwjmy1l7tibi9t9ziyb53p" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd8iqbmvu05s9c.cloudfront.net%2F8l4wmebwjmy1l7tibi9t9ziyb53p" alt="Shows the previous test method called coffee_is_not_served but with its body folded as  @ParameterizedTest @CsvSource({ " width="511" height="286"&gt;&lt;/a&gt; coffees left in the machine;  When I insert  one euro coins And I press the coffee button;  Then I should not be served a coffee; }"/&amp;gt;&lt;/p&gt;

&lt;p&gt;Please note that this code folding is not from an existing IDE plugin. It was made specifically for this article for demonstration purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t use BDD frameworks at all
&lt;/h2&gt;

&lt;p&gt;Whether you should implement your tests as BDD scenarios and use a test framework that supports that, depends on the project domain and resources, application type and other aspects.&lt;/p&gt;

&lt;p&gt;One argument I have heard many times is the fact that glue code adds an unnecessary layer of abstraction, since it has to be thin, and, in an ideal case, should only delegate test execution to the actual underlying test code.&lt;/p&gt;

&lt;p&gt;It is simply worth keeping in mind that you can always opt to implement your tests as regular JUnit or TestNG ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  A couple of options to choose from
&lt;/h2&gt;

&lt;p&gt;I have described a couple of options that you can utilise in your test suites and during your test automation. They have different learning curves and require different sets of knowledge to apply, so I’m not advocating for any specific solution above. I’m simply hoping I could show you some interesting ways and alternatives to spark your imagination about how you could simplify your or your team’s life when you are using BDD based test automation.&lt;/p&gt;

&lt;p&gt;If you think I missed any other ways of simplification, please let me know on The Club (link required).&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.baeldung.com/cucumber-java-8-support" rel="noopener noreferrer"&gt;Baeldung - Cucumber with Lambda Expressions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://codingcraftsman.wordpress.com/2019/05/01/some-cucumber-best-practices/" rel="noopener noreferrer"&gt;The Coding Craftsman - Some Cucumber Best Practices by Ashley Frieze&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.jetbrains.com/help/idea/working-with-source-code.html#fold-or-unfold-nested-fragments" rel="noopener noreferrer"&gt;IntelliJ IDEA documentation - Code Folding in IntelliJ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dzone.com/articles/acceptance-tests-in-java-with-jgiven" rel="noopener noreferrer"&gt;DZone - Acceptance Tests in Java With JGiven by Elmar Dott&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.ontestautomation.com/to-bdd-or-not-to-bdd/" rel="noopener noreferrer"&gt;OnTestAutomation - To BDD or not to BDD? by Bas Dijkstra&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  For more information
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/activities/to-bdd-or-not-to-bdd-that-is-the-question" rel="noopener noreferrer"&gt;To BDD or Not to BDD That is The Question - Thomas Shipley&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/testbash-sessions/behavior-driven-pragmatism-andrew-knight" rel="noopener noreferrer"&gt;Behaviour-Driven Pragmatism - Andrew Knight&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/testbash-sessions/the-power-of-example-mapping" rel="noopener noreferrer"&gt;The Power of Example Mapping! - Kiruthika Ganesan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>bdd</category>
      <category>qa</category>
      <category>testing</category>
    </item>
    <item>
      <title>Beating The Odds In A Competitive Job Market: Top Tips For New Software Testers</title>
      <dc:creator>Rosie Sherry</dc:creator>
      <pubDate>Sun, 18 Aug 2024 09:46:11 +0000</pubDate>
      <link>https://forem.com/ministryoftesting/beating-the-odds-in-a-competitive-job-market-top-tips-for-new-software-testers-2860</link>
      <guid>https://forem.com/ministryoftesting/beating-the-odds-in-a-competitive-job-market-top-tips-for-new-software-testers-2860</guid>
      <description>&lt;p&gt;Land that elusive first software testing job with these simple tips!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  by Mirza Sisic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Job hunting is never easy, but it's especially challenging when you're a junior software tester. You're competing with an annual wave of new college graduates who are applying for the same junior roles you are. And then there are the people from other disciplines who are looking to get into IT by starting out with a junior role.&lt;/p&gt;

&lt;p&gt;To improve your chances, try to stand out among the competition. First of all, make sure your CV is concise and readable. If you're coming to software testing from another field, emphasize your soft skills as well as the skills from your previous profession that are transferable. &lt;/p&gt;

&lt;h2&gt;
  
  
  Build A Network, Build Relationships
&lt;/h2&gt;

&lt;p&gt;Join local software testing communities, like meetups. You'll be able to expand your network and make new friends by getting to know like-minded people. Some of these people are likely to work for local companies, and once you get to know them and they see you are eager to learn, they might just recommend you for hire at their place of work. Having someone vouch for you puts you ahead of the game when you apply for a job. &lt;/p&gt;

&lt;p&gt;Building quality, long-term relationships with people is arguably the best thing you can do for your career. Being active in the testing community says a lot about you: people who are involved in groups related to what they do for a living tend to be passionate about their craft.&lt;/p&gt;

&lt;p&gt;Having a solid network is great for job recommendations, but that's not all. It's great for support, too. The learning journey can be lonely, but in a community, sometimes you can find people who can be buddies along the way. We are heavily influenced by the company we keep, so if you socialize with smart, friendly people who are learning and trying to get into software testing, their good qualities and enthusiasm will have a positive effect on you. &lt;/p&gt;

&lt;h2&gt;
  
  
  Work The Social Media Angle
&lt;/h2&gt;

&lt;p&gt;Use social media to your advantage as much as possible. Make sure your LinkedIn profile is polished, connect with people (especially recruiters), follow industry leaders, comment on others' posts, engage in meaningful discussions, and show support to others by sharing content and leaving online reviews. LinkedIn's recommendation feature is a great way to vouch for someone's skills, and they often will be happy to do the same for you.&lt;/p&gt;

&lt;p&gt;You can use any other social media platform as well. You want your entire social media profile to support your claim of being an engaged, talented software tester. If you want to post or share "just for fun," that's OK sometimes, but consider opening a personal account for topics not related to software. &lt;/p&gt;

&lt;p&gt;Try to participate in hackathons and similar events, or get involved in open source software. Activities such as these will increase your chances of getting noticed by people and prove your dedication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write And Share About Your Learning Journey
&lt;/h2&gt;

&lt;p&gt;Consider creating a blog to recount your learning journey. You don’t need to be an expert at something to write about it, and it can give you some positive exposure. I once got a full-time job mainly because of my blog, and the blog resulted in a few freelance content writing gigs too. A blog is yet another way to show your passion and interest in the craft of software testing.&lt;/p&gt;

&lt;p&gt;To get started, you can treat it as a public journal or diary. As you learn new skills, consider writing tutorial blog posts, as the act of writing them will enhance your learning. We learn a lot by teaching others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take A Chance On "Cold Email"
&lt;/h2&gt;

&lt;p&gt;Don’t limit yourself to applying for jobs that specifically require juniors — apply to other jobs too. If a company likes you they might find a spot for you or contact you later on if you leave a good impression. Also, it can happen that the company is looking for a mid-level tester and the candidates they've seen so far do not impress them. They might just  give a chance to a promising junior like you.&lt;/p&gt;

&lt;p&gt;Not all open jobs are advertised. Research companies that you might like to work for, and send them your CV with a nice cover letter that mentions why they appeal to you: their values, their tech stack, their product, and so on. Ask specifically if they have any openings at the moment. Internal recruiters for many companies are available for messaging on LinkedIn. &lt;/p&gt;

&lt;p&gt;Sending cold emails can get you an interview or land you a role in the future. Being proactive is a highly sought-after trait that any organization worth working for will recognize.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Job Sites Specialized For Software Testers
&lt;/h2&gt;

&lt;p&gt;Some websites offer jobs primarily for software testers. &lt;a href="https://www.ministryoftesting.com/jobs" rel="noopener noreferrer"&gt;One such job board is available on the Ministry of Testing website&lt;/a&gt;. The jobs on the MoT site are curated and hand-picke, so you can rest assured that these are jobs in prominent companies, offering great working conditions for software testers. &lt;/p&gt;

&lt;p&gt;On many job websites, you can filter for testing jobs and save those filters for later use. &lt;a href="https://remote.co/remote-jobs/qa/" rel="noopener noreferrer"&gt;Remote.com&lt;/a&gt; and &lt;a href="https://testdevjobs.com/software-testing-jobs" rel="noopener noreferrer"&gt;TestDevJobs&lt;/a&gt; offer this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  To Wrap Up
&lt;/h2&gt;

&lt;p&gt;Be consistent in your efforts and understand that getting that first job is the hardest. It can take anywhere from a few months to a few years. &lt;/p&gt;

&lt;p&gt;If you get rejected, ask for concrete feedback so you know what knowledge gaps need to be addressed next. While it can be discouraging at times and hard to find the motivation, surrounding yourself with people who have similar goals can help you get more motivated and get you into a state of mind when you are constantly learning and applying for a new job. As you iterate, you'll get better at it, and eventually, that first job will come along.&lt;/p&gt;

&lt;h2&gt;
  
  
  For More Information
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/collections/getting-hired" rel="noopener noreferrer"&gt;Getting Hired&lt;/a&gt; - Ministry of Testing Collection&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/collections/a-community-s-guide-to-your-software-testing-career" rel="noopener noreferrer"&gt;A Community's Guide to Your Software Testing Career&lt;/a&gt; - Ministry of Testing Collection&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/software-testing-news" rel="noopener noreferrer"&gt;Read the Latest Software Testing News&lt;/a&gt; - Ministry of Testing News Blog feed &lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.ministryoftesting.com/meetups" rel="noopener noreferrer"&gt;Meet Fellow Software Testers IRL&lt;/a&gt; - Ministry of Testing Meetups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published at &lt;a href="https://www.ministryoftesting.com/articles/beating-the-odds-in-a-competitive-job-market-top-tips-for-new-software-testers" rel="noopener noreferrer"&gt;Ministry of Testing&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>softwaretesting</category>
      <category>qualityassurance</category>
      <category>qualityengineering</category>
    </item>
  </channel>
</rss>
