<?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>DEV Community: Zhimin Zhan</title>
    <description>The latest articles on DEV Community by Zhimin Zhan (@zhiminzhan).</description>
    <link>https://dev.to/zhiminzhan</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%2Fuser%2Fprofile_image%2F926659%2F43e3cc0c-cf38-4abe-b72b-8392a89c60a3.jpg</url>
      <title>DEV Community: Zhimin Zhan</title>
      <link>https://dev.to/zhiminzhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhiminzhan"/>
    <language>en</language>
    <item>
      <title>Cypress vs Selenium WebDriver Comparison by Example</title>
      <dc:creator>Zhimin Zhan</dc:creator>
      <pubDate>Fri, 16 Sep 2022 21:17:08 +0000</pubDate>
      <link>https://dev.to/zhiminzhan/cypress-vs-selenium-webdriver-comparison-by-example-2ee4</link>
      <guid>https://dev.to/zhiminzhan/cypress-vs-selenium-webdriver-comparison-by-example-2ee4</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is one of the “Bad Test Automation Frameworks/Tools” series.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I started this article 10 months ago, it was sitting in my drafts and just noticed it today. After my three articles on Cypress,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://zhiminzhan.medium.com/why-cypress-sucks-for-real-test-automation-f79525ea5844"&gt;Why Cypress Sucks for Real Test Automation?&lt;/a&gt; and &lt;a href="https://zhiminzhan.medium.com/why-cypress-sucks-for-real-test-automation-part-2-limitations-53c1914acd0d"&gt;Part 2: Limitations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/why-javascript-is-not-a-suitable-language-for-real-web-test-automation-3a87eb4b0b50"&gt;Why JavaScript Is Not a Suitable Language for Real Web Test Automation?”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I thought there is no need to talk about Cypress, which, IMO, is doomed to fail (for reasons, read the above). So far, every Cypress test automation (that I am aware of) failed badly, often embarrassingly. I noticed a trend though, after failures, &lt;a href="https://zhiminzhan.medium.com/fake-end-to-end-test-automation-clarified-1269ca704a0"&gt;fake automated testers&lt;/a&gt; blamed Cypress and then switched to another JS framework Playwright, just like earlier some of them switched to Cypress from the hyped (&lt;em&gt;and now deprecated&lt;/em&gt;) &lt;a href="https://zhiminzhan.medium.com/protractor-another-automation-framework-i-rightly-avoided-is-being-deprecated-aaf702241f43"&gt;Protractor&lt;/a&gt;. Playwright is not good either, maybe slightly better than Cypress, then failed again. The best is still raw Selenium WebDriver in Ruby.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The article &lt;a href="https://zhiminzhan.medium.com/an-it-graduates-frustration-with-a-fake-senior-test-automation-engineer-8b0075954394"&gt;An IT Graduate’s frustration with a Fake ‘Senior Test Automation Engineer’&lt;/a&gt; tells an interesting and real story of an intern (my mentee, freshly out of Uni) who silenced one fake senior test automation engineer with indisputable results, implemented automated UI tests in both Selenium and Playwright at the productivity this large company have never seen. (Reason: this intern developed tests in raw Selenium WebDriver first, then converted to Playwright). Eventually, this fake senior Playwright tester did dirty tricks to sabotage. A good read.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Today, I saw a LinkedIn feed to recommend using Cypress for test automation, and it was posted in a Selenium Group. So I decide to complete and publish this article.&lt;/p&gt;

&lt;p&gt;Anyway, the aim of this article is about an objective comparison of Cypress and Selenium syntax, using a very simple example, from a tester’s perspective. To be fair, I used the Cypress test script example posted by Gleb Bahmutov (known as the authority on Cypress). So, the comparison is as objective as it can be.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  “Test Scripts are the core of test automation, naturally. Ignore others who tell you otherwise” — Zhimin Zhan
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cypress vs Selenium WebDriver (Ruby)
&lt;/h2&gt;

&lt;p&gt;I will use &lt;a href="https://glebbahmutov.com/blog/avoid-cypress-pyramid-of-doom/"&gt;a simple example by Gleb Bahmutov&lt;/a&gt; (“Avoid Cypress Pyramid of Doom” posted on 2021–07–28): a simple calculator on a web page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ecxzHcg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tq9tb3zq1chg4eb704a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ecxzHcg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tq9tb3zq1chg4eb704a.png" alt="" width="880" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The HTML (&lt;em&gt;from Gleb’s post&lt;/em&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Calculator&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;a = &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;b = &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;a + b = &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;6&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is Gleb’s ‘&lt;strong&gt;good version&lt;/strong&gt;’ (there were a couple of not-so-good versions shown) Cypress test script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adds numbers via aliases&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name=a]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;val&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name=b]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;val&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My version in raw Selenium (RSpec):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"adds numbers"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"public/index.html"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt; 
  &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a lot better, isn’t it? Please take a stand from an independent testing perspective.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  “Users do not care how the website was coded in Java, JS, C#, PHP or Ruby. The same applies when end-to-end testing a website from a user perspective” — Zhimin Zhan
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Comparative Analysis
&lt;/h2&gt;

&lt;p&gt;Let’s see some differences. If you are using Cypress or other JS framework, pause, and think objectively as a team member (e.g. Business Analyst or Manual Tester) who might want to use your automated tests:&lt;/p&gt;

&lt;h3&gt;
  
  
  Get the value of an input text field
&lt;/h3&gt;

&lt;p&gt;Cypress: &lt;code&gt;invoke('val')&lt;/code&gt;&lt;br&gt;
Selenium: &lt;code&gt;["value"]&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Verdict&lt;/strong&gt;: Selenium WebDriver is more natural, as it gets the value attribute in HTML tag: &lt;code&gt;&amp;lt;input name="a" type="number" value="1"/&amp;gt;&lt;/code&gt; . The invoke and 'val' in Cypress make the simple things complex. The keyword invoke, in particular, is bad. Where is 'val' in the HTML fragment? (&lt;em&gt;I know as I programmed JS professionally before, again, consider for others who don’t know JS at all&lt;/em&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Convert string to an integer
&lt;/h3&gt;

&lt;p&gt;Cypress (JavaScript): &lt;code&gt;parseInt&lt;/code&gt;&lt;br&gt;
Selenium (Ruby): &lt;code&gt;to_i&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Verdict&lt;/strong&gt;: the Ruby syntax is better as it is concise and more readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Promise
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(unneeded in software testing, if thinking outside JS)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cypress: &lt;code&gt;then&lt;/code&gt;&lt;br&gt;
Selenium: no such concept. (Please note, achieving the same testing result).&lt;br&gt;
&lt;strong&gt;Verdict&lt;/strong&gt;: Selenium is better. JavaScript’s Promise is confusing and totally unnecessary from the testing perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alias
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(unneeded as well)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cypress: &lt;code&gt;as('a')&lt;/code&gt;, also, later &lt;code&gt;this.a&lt;/code&gt;&lt;br&gt;
Selenium: no such concept, just naturally assign a variable, &lt;code&gt;a =&lt;/code&gt; .&lt;br&gt;
&lt;strong&gt;Verdict&lt;/strong&gt;: Selenium is a lot better, the alias usage in Cypress is totally unnecessary from the testing perspective.&lt;/p&gt;

&lt;p&gt;The winner, clearly, is raw Selenium with Ruby.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xDoEg2EG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gyra19r524fgentt53fq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xDoEg2EG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gyra19r524fgentt53fq.png" alt="Agile Testing book recommends Ruby" width="880" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“&lt;strong&gt;Ruby is the best for scripting automated tests&lt;/strong&gt;” is not news or secret, why on earth do people fail test automation again and again in Java/C#/JavaScript?&lt;/p&gt;

&lt;h2&gt;
  
  
  Human Factors
&lt;/h2&gt;

&lt;p&gt;Besides tech comparison, Selenium WebDriver’s version is more concise and consistent, which are important for maintenance. &lt;a href="https://medium.com/geekculture/is-your-test-automation-on-track-maintenance-is-the-key-267ddb94b525"&gt;The effort for test script maintenance far exceeds that of test creation&lt;/a&gt;. That’s why most JS test automation attempts started OK (&lt;em&gt;and excitedly&lt;/em&gt;), then failed badly (&lt;em&gt;and quietly&lt;/em&gt;): unable to maintain the tests.&lt;/p&gt;

&lt;p&gt;There are other factors too, such as Gleb’s article showing several different (worse) versions, which may cause problems in a team environment. With Selenium WebDriver, if the team stays with the raw Selenium, it is quite easy for the team to reach a convention.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Selenium WebDriver, syntax-wise, is much better than all others for a simple reason: it was created by W3C experts after many rounds of reviews and refinement. — Zhimin Zhan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More importantly, real test automation engineers know that the audience of automated test scripts is the whole team, not limited to programmers. Even the simple syntax that JS programmers take for granted, such as &lt;code&gt;() =&amp;gt; {&lt;/code&gt;, &lt;code&gt;this.a&lt;/code&gt;, and &lt;code&gt;})&lt;/code&gt; may confuse the business analysts and manual testers.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;I think some Cypress/Playwright/JS testers disagree with my recommendation of raw Selenium WebDriver with Ruby. Before raising your questions, watch the below 37-second video, which is extracted from this great presentation: “&lt;a href="https://zhiminzhan.medium.com/recommend-a-great-ci-presentation-continuous-integration-at-facebook-6369323da084"&gt;Continuous Integration at Facebook&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;Video on YouTube: &lt;a href="https://youtu.be/D5Zk5ylPrGk"&gt;https://youtu.be/D5Zk5ylPrGk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YsRMxO7_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvh1md0ibpbo5fd4ug1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YsRMxO7_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvh1md0ibpbo5fd4ug1g.png" alt="Facebook’s Testing Pyramid image credit" width="880" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Facebook’s &lt;a href="https://zhiminzhan.medium.com/testing-pyramid-clarified-af45535bed8b"&gt;Testing Pyramid&lt;/a&gt; image credit: “Continuous Integration at Facebook”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I added two more references.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Facebook is &lt;strong&gt;released twice a day&lt;/strong&gt;, and keeping up this pace is at the heart of our culture. With this release pace, automated testing with &lt;strong&gt;Selenium is crucial&lt;/strong&gt; to making sure everything works before being released.” — DAMIEN SERENI, Engineering Director at Facebook, at &lt;a href="https://2014.seleniumconf.in/2013/speakers/index.html"&gt;Selenium 2013 conference&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---8FKV6Pz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3r15rzc2p72juwu6mug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---8FKV6Pz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3r15rzc2p72juwu6mug.png" alt="Microsoft recommends Selenium" width="828" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Microsoft dumped its “Coded UI Test” and &lt;a href="https://docs.microsoft.com/en-us/visualstudio/test/use-ui-automation-to-test-your-code?view=vs-2017"&gt;recommended Selenium WebDriver&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, Selenium WebDriver works, and works very well! Accept this, first. This does not mean excluding others. But if someone wants to promote a new framework/tool X, people shall know the free, open-source, W3C-standard compliant Selenium WebDriver is excellent already for web test automation, when used by real test automation engineers, with &lt;a href="https://www.linkedin.com/pulse/400000-test-executions-clinicwise-buildwise-ci-server-zhimin-zhan/"&gt;extremely high productivity&lt;/a&gt;. Also, under proper guidance, &lt;a href="https://zhiminzhan.medium.com/step-by-step-showing-why-selenium-webdriver-is-the-easiest-to-learn-web-test-automation-framework-fa2b5904c08"&gt;raw Selenium WebDriver is the easiest to learn&lt;/a&gt;, only takes a few hours.&lt;/p&gt;

&lt;p&gt;By the way, my continuous testing process (running automated end-to-end UI tests regression) &lt;a href="https://medium.com/nerd-for-tech/did-you-push-software-updates-into-production-yesterday-96bf5898d854"&gt;enables me to deploy all my apps on a daily basis&lt;/a&gt;, like Facebook, since 2012. I am NOT interested in debating specific features of a framework or tool, rather than the fundamental, whether your test automation is useful for the team (&lt;em&gt;check out &lt;a href="https://zhiminzhan.medium.com/definition-of-end-to-end-test-automation-success-c668d914a87e"&gt;Definition of End-to-End Test Automation Success&lt;/a&gt;&lt;/em&gt;). My Q&amp;amp;As below are for the engineers who are motivated for real test automation.&lt;/p&gt;

&lt;p&gt;(1). &lt;em&gt;I acknowledge Selenium WebDriver (Ruby) syntax is better, however, Cypress is more than a framework, its tool makes creating tests easier?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wrong. The tool is after the framework, and always should be, in the context of software development. We talk about here are the test scripts (what really matters).&lt;/p&gt;

&lt;p&gt;(2). &lt;em&gt;Cypress seems easier to use, compared to Selenium.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wrong. Cypress is a combination of a framework and tool. You cannot compare a framework with a vendor-provided tool demo. HP’s QTP and IBM’s RFT had good demos too, further, some top magazines or consulting companies (such as Gartner) sang for them. The result: complete failures.&lt;/p&gt;

&lt;p&gt;I think Selenium is much easier, TestWise help real automated testers be more productive and fun. Check out my daughter’s “&lt;a href="https://zhiminzhan.medium.com/set-up-develop-automated-ui-tests-and-run-them-in-a-ct-server-on-your-first-day-at-work-bd7110c9f677"&gt;Set up, Develop Automated UI tests and Run them in a CT server on your First day at work&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;(3). &lt;em&gt;People tell me that Selenium is hard to learn&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Wrong. My daughter started writing raw Selenium test scripts at the age of 12, with the right mentoring, your child could do that too. Check out my article: “&lt;a href="http://why%20selenium%20webdriver%20is%20so%20easy%20to%20learn/?"&gt;Why Selenium WebDriver is So Easy to Learn?&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;As a matter of fact, some people hesitated for signing up for my &lt;a href="http://agileway.com.au/training/automation-selenium"&gt;one-day “Web Test Automation with Selenium WebDriver” training&lt;/a&gt; because it was too short. My reply: “ learning Selenium WebDriver is just that easy, in fact, during that 8 hours, I spent over 50% on &lt;a href="https://medium.com/geekculture/maintainable-automated-test-design-d325dd13b868"&gt;Maintainable Automated Test Design&lt;/a&gt; and &lt;a href="https://zhiminzhan.medium.com/functional-test-refactoring-598872af9d51"&gt;Functional Test Refactoring&lt;/a&gt;”. By the way, no prior test automation/programming experience is required. Again, that’s because raw Selenium WebDriver is that simple and easy to learn. Many so-called ‘better’ frameworks such as &lt;a href="https://zhiminzhan.medium.com/protractor-another-automation-framework-i-rightly-avoided-is-being-deprecated-aaf702241f43"&gt;failed Protractor&lt;/a&gt; actually made it harder.&lt;/p&gt;

&lt;p&gt;(4). &lt;em&gt;I think developing Cypress scripts (with the Cypress tool) is more productive than that of Selenium.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wrong. I am at least &lt;strong&gt;10X&lt;/strong&gt; more productive than any Cypress and Playwright testers I met. I often completed a planned 3-month Test Automation Proof of Concept (POC) in a matter of days, typically ~ 3 days. The staff at those companies were shocked by my productivity. The reason: I am developing raw Selenium WebDriver test scripts in &lt;a href="https://agileway.com.au/testwise"&gt;TestWise&lt;/a&gt;, following good test-automation practices such as &lt;a href="https://medium.com/geekculture/maintainable-automated-test-design-d325dd13b868"&gt;Maintainable Automated Test Design&lt;/a&gt;, &lt;a href="https://zhiminzhan.medium.com/my-innovative-solution-to-test-automation-keep-the-browser-open-after-executing-an-individual-test-b858c0a29a77"&gt;Keep browser open&lt;/a&gt;, &lt;a href="https://zhiminzhan.medium.com/functional-test-refactoring-598872af9d51"&gt;Functional Test Refactoring&lt;/a&gt;, .., etc. Special mention: &lt;a href="https://zhiminzhan.medium.com/which-selenium-webdriver-language-binding-is-best-683442e05796"&gt;Ruby is great for scripting automated tests&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Not convinced? Check out the screencast in this article: “&lt;a href="https://zhiminzhan.medium.com/step-by-step-showing-why-selenium-webdriver-is-the-easiest-to-learn-web-test-automation-framework-fa2b5904c08"&gt;Step by Step showing how to learn to write raw Selenium WebDriver test scripts in minutes&lt;/a&gt;”, and &lt;a href="https://zhiminzhan.medium.com/agileway-continuous-testing-grading-f483a870d2e2"&gt;some of the test suites&lt;/a&gt; I have been maintaining over the years.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ClinicWise, &lt;a href="https://www.linkedin.com/pulse/500000-selenium-ui-test-executions-clinicwise-buildwise-zhimin-zhan/"&gt;611 raw Selenium WebDriver tests&lt;/a&gt; (since 2012). &lt;/li&gt;
&lt;li&gt;TestWise, &lt;a href="https://zhiminzhan.medium.com/appium-desktop-test-automation-milestone-60-000-test-executions-over-2-years-for-300-test-3d0ceb5b84b4"&gt;307 raw Appium + WinAppDriver tests&lt;/a&gt; (since 2019)&lt;/li&gt;
&lt;li&gt;WhenWise, &lt;a href="https://zhiminzhan.medium.com/whenwise-regression-test-suite-reaches-500-selenium-tests-and-300k-test-executions-84279ae0ed35"&gt;551 raw Selenium WebDriver tests&lt;/a&gt; (since 2018)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;all in my spare time.&lt;/p&gt;

&lt;p&gt;Any motivated manual tester can achieve high productivity (might take a while to match mine, but shall be much much higher than the so-called best JS automated tester) quite quickly. Many manual testers I mentored became the test automation authority in their companies.&lt;/p&gt;

&lt;p&gt;(5). &lt;em&gt;I read the above articles and watched the tutoring, it did look very simple and easy. How come automated testers generally are associated with “difficult” to Selenium?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are many reasons and I covered those in other articles, such as “&lt;a href="https://zhiminzhan.medium.com/evil-mudslinging-against-selenium-webdriver-5a0ba4df07b2"&gt;Evil Mudslingings against Selenium WebDriver&lt;/a&gt;”. Here, I want to just point out key ones concisely.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vendors &lt;a href="https://zhiminzhan.medium.com/evil-mudslinging-against-selenium-webdriver-5a0ba4df07b2"&gt;defame Selenium&lt;/a&gt; (free, open-source) for commercial interests&lt;/li&gt;
&lt;li&gt;Test automation is often started by programmers who don’t really understand (but pretend), they often chose the &lt;a href="https://zhiminzhan.medium.com/which-selenium-webdriver-language-binding-is-best-683442e05796"&gt;wrong language&lt;/a&gt; such as Java, C# or JavaScript.&lt;/li&gt;
&lt;li&gt;Not aware of a good Selenium tool, such as &lt;a href="https://agileway.com.au/testwise"&gt;TestWise&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Never experienced a successful &lt;a href="https://zhiminzhan.medium.com/continuous-testing-clarified-52c90e9a6825#:~:text=The%20purpose%20of%20CI%20is,next%20ruined%20%27talker%20term%27."&gt;Continuous Testing&lt;/a&gt;, often using CI servers such as Jenkins to run UI tests. Instead, they should use a CT server such as &lt;a href="https://zhiminzhan.medium.com/recommend-a-great-ci-presentation-continuous-integration-at-facebook-6369323da084"&gt;Facebook’s Sandcastle&lt;/a&gt; or &lt;a href="https://agileway.com.au/buildwise"&gt;BuildWise&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(6). &lt;em&gt;I have used Selenium-based frameworks (created by our test architects), but it was not as easy as you showed us. Why?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s because those people did not understand test automation, making Selenium harder. Check out my article “&lt;a href="https://zhiminzhan.medium.com/please-not-another-web-test-automation-framework-just-use-selenium-webdriver-86693045d5af"&gt;Please, Not Another Web Test Automation Framework, Just Use Raw Selenium WebDriver&lt;/a&gt;”. Often they used the &lt;a href="https://zhiminzhan.medium.com/automated-test-scripts-shall-be-in-the-syntax-of-a-scripting-language-naturally-8b6218812314"&gt;wrong languages such as Java/C#&lt;/a&gt;, or the &lt;a href="https://medium.com/swlh/why-gerkin-cucumber-specflow-always-failed-with-ui-test-automation-c85a8030c07d"&gt;wrong test syntax frameworks such as Gherkin&lt;/a&gt;. Just use raw Selenium WebDriver + RSpec first and most popular &lt;a href="https://zhiminzhan.medium.com/bdd-clarified-bdd-given-when-then-gherkin-773b52b45eb3"&gt;BDD framework&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;(7). &lt;em&gt;Cypress’s new version has better ….?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is exactly what the problem is. I have been using Selenium WebDriver exactly the same way since 2011 (&lt;a href="https://zhiminzhan.medium.com/selenium-4-new-features-by-examples-in-ruby-4b1e100b2ad7"&gt;Selenium v4 has some new features&lt;/a&gt;). Don’t you want this stability, or rather being dependent on others? Furthermore, it is really important to have consistent test script syntax when working in a team. As you have seen Gleb’s “&lt;a href="https://glebbahmutov.com/blog/avoid-cypress-pyramid-of-doom/"&gt;Avoid Cypress Pyramid of Doom&lt;/a&gt;”, there are so many ways, a recipe for chaos.&lt;/p&gt;

&lt;p&gt;(8). &lt;em&gt;How come so many testers claimed doing Cypress well? Are they all fake?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I only can comment on people I met. Yes, &lt;a href="https://zhiminzhan.medium.com/an-it-graduates-frustration-with-a-fake-senior-test-automation-engineer-8b0075954394"&gt;every Cypress/Playwright testers I met was a fake&lt;/a&gt;. This is not belittling them, automated end-to-end testing is difficult (&lt;em&gt;except HelloWorld level demos&lt;/em&gt;), even for Microsoft (see below). Using Cypress/Playwright makes it even much harder, unnecessarily.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“95% of the time, 95% of test engineers will write bad GUI automation just because it’s a very difficult thing to do correctly”.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://testguild.com/alan-page-principles-lessons-learned-at-microsoft/"&gt;this interview from Microsoft Test Guru Alan Page&lt;/a&gt; (2015)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;p&gt;Related articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My eBook: “&lt;a href="https://leanpub.com/practical-web-test-automation"&gt;Practical Web Test Automation with Selenium WebDriver&lt;/a&gt;”&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/why-do-most-ui-test-automation-fail-part-2-wrong-choice-of-test-syntax-framework-2289aff0d81e"&gt;Why Do Most UI Test Automation Fail? (Part 2: Wrong Choice of Test Syntax Framework)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/testing-pyramid-clarified-af45535bed8b"&gt;Testing Pyramid Clarified&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/user-story-card-clarified-c10df3f1229a"&gt;User Story Card Clarified&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/continuous-testing-clarified-52c90e9a6825"&gt;Continuous Testing Clarified&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/done-done-in-agile-8cd95f077411"&gt;“Done, Done” in Agile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/geekculture/agileway-test-automation-formula-bcf550616d32"&gt;AgileWay Test Automation Formula&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/selenium-vs-x-y-z-all-these-years-979b8aa34125"&gt;Selenium vs X, Y, Z, …, all these years&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>selenium</category>
      <category>cypress</category>
      <category>javascript</category>
      <category>automation</category>
    </item>
    <item>
      <title>Why Gherkin (Cucumber, SpecFlow,…) Always Failed with UI Test Automation?</title>
      <dc:creator>Zhimin Zhan</dc:creator>
      <pubDate>Thu, 15 Sep 2022 22:48:32 +0000</pubDate>
      <link>https://dev.to/zhiminzhan/why-gherkin-cucumber-specflow-always-failed-with-ui-test-automation-29jc</link>
      <guid>https://dev.to/zhiminzhan/why-gherkin-cucumber-specflow-always-failed-with-ui-test-automation-29jc</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://medium.com/swlh/why-gerkin-cucumber-specflow-always-failed-with-ui-test-automation-c85a8030c07d"&gt;Medium&lt;/a&gt; (2021-01), and featured in Medium's largest publication 'The Startup' and some software testing newsletters. This is also included in &lt;a href="https://zhiminzhan.medium.com/my-article-series-5f1a551d8796#93ba"&gt;“Be aware of Fake Test Automation/DevOps Engineers” series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Many software projects tried or are trying to use Cucumber for test automation, commonly with Selenium Driver for testing web apps. Some might wonder whether my title is just a personal and radical view for attention. No, I just reworded the view from Aslak Hellesøy, the creator of Cucumber:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“So really, what is Cucumber? As a test tool it sucks. There far better automated test tools” (&lt;a href="https://news.ycombinator.com/item?id=10194242"&gt;source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some Gherkin fans may say: “this might be one mis-comment”. Oh well, here is another one on Aslak’s home age.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If all you need is a testing tool for driving a mouse and a keyboard, don’t use Cucumber. There are other tools that are designed to do this with far less abstraction and typing overhead than Cucumber.” (&lt;a href="https://www.aslakhellesoy.com/post/11055981222/the-training-wheels-came-off"&gt;source&lt;/a&gt;):&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With my 10+ years of test automation and continuous testing consultation, every test automation attempt with Gherkin-style syntax (Cucumber, SpecFlow, JBehave, Concordion, Gauge, Spinach…) failed, with no expectations! The biggest failure I heard, “&lt;em&gt;The project spent 3 times of development efforts (measured time and money) trying to maintain those cucumber tests, eventually, dumped to the bin!&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;Why does Cucumber fail in test automation? Let’s hear from DHH (Creator of Ruby on Rails, Founder &amp;amp; CTO at Basecamp &amp;amp; HEY, NYT best-selling author):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XgBi6eYo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrc83ja7aezxyoh01iqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XgBi6eYo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrc83ja7aezxyoh01iqi.png" alt="DHH’s tweet in March 2011" width="880" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DHH is correct, as usual. I have never met one business customer who actually read (or even run) cucumber tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vYqyTPN0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8ecrk921zdii7wpdb20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vYqyTPN0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8ecrk921zdii7wpdb20.png" alt="Image description" width="880" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we established that, it is clear that Cucumber tests have little value for customers (and, therefore, business analysts). From the technical perspective, the effort to support the extra layer of test-specific parser for English is going to cost the team a lot. (&lt;em&gt;please note, again, there are no or little business values of doing that&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Some might still argue: “&lt;em&gt;I disagree. The creator of Cucumber and DHH were wrong, I implemented Cucumber successfully on the last project&lt;/em&gt;”. For every person who said this to me, and when I had the chance to assess their work, just all plain lies. Think about it, “the last project”, how about this project? Show us. For web test automation, the knowledge is pretty much fully transferable. For every new project, I created at least one working core test (given the environment is ready) and mostly ran in a Continuous Testing server (e.g. &lt;a href="https://agileway.com.au/buildwise"&gt;BuildWise&lt;/a&gt;), &lt;a href="https://zhiminzhan.medium.com/set-up-develop-automated-ui-tests-and-run-them-in-a-ct-server-on-your-first-day-at-work-bd7110c9f677"&gt;on the first day&lt;/a&gt; &lt;em&gt;yes, you read right&lt;/em&gt;, on Day 1.&lt;/p&gt;

&lt;p&gt;What is the main technical reason for Cucumber (i.e. Gherkin) failing on test automation? &lt;strong&gt;Test Script Maintenance&lt;/strong&gt;. The first few test cases are easy to do and relatively simple, and static (e.g. login, sign up). Some get excited, executable specifications that like English, woo-hoo! With more tests, as we know, test cases may get more complicated, and the maintenance effort (existing and new) will grow quickly (exponentially if lacking the tools and capability to meet the challenges). That’s the case for all UI test automation, even with good syntax frameworks such as RSpec.&lt;/p&gt;

&lt;p&gt;If someone thinks maintaining automated UI tests is easy, please read &lt;a href="https://testguild.com/alan-page-principles-lessons-learned-at-microsoft/"&gt;this interview from Microsoft Test Guru Alan Page&lt;/a&gt;: “&lt;em&gt;95% of the time, 95% of test engineers will write bad GUI automation just because it’s a very difficult thing to do correctly&lt;/em&gt;”. If you think GUI automation is easy, then you are at 1 out of 400 SET (software engineers in Test) level, according to Alan Page. Please note, this is judged by the Microsoft Engineer standard. How many test engineers in your city (or state) can meet the standard? Not many, right? Only 1/400 of them can do real GUI test automation well, and they probably won’t think it is easy. This is not just Microsoft’s view, &lt;a href="https://blog.utest.com/2010/02/23/testing-the-limits-with-patrick-copeland-part-ii/"&gt;Google VP Patrick Copeland said this&lt;/a&gt;: “&lt;em&gt;In my experience, great developers do not always make great testers, but great testers (who also have strong design skills) can make great developers. It’s a mindset and a passion. … &lt;strong&gt;They are gold&lt;/strong&gt;&lt;/em&gt;”.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some might feel intimidated, “if test automation is that hard, we probably shall give up, just do manual testing”. Please don’t, without a solid E2E test automation, there is no real Agile. Test Automation (and later Continuous Testing) is challenging, but not impossible. Face the challenge, and take proper actions such as seeking help from a qualified test automation coach (&lt;a href="https://zhiminzhan.medium.com/advice-on-self-learning-test-automation-with-selenium-webdriver-846278328a99"&gt;self-learning&lt;/a&gt; is possible, but will be more difficult), choosing correct frameworks (such as raw Selenium WebDriver + RSpec), highly-effective testing tool such as TestWise and dedicated Continuous Testing server such as BuildWise. (By the way, you can start with all the above frameworks/tools, FREE). It can be a very &lt;a href="https://zhiminzhan.medium.com/my-test-automation-journey-1e7901bcb1e5"&gt;rewarding journey&lt;/a&gt;, with positive results in a short time.&lt;/p&gt;

&lt;p&gt;However, it is very easy to make bad decisions along the way, choosing Gherkin syntax is one of them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cucumber tests will require &lt;strong&gt;more maintenance efforts&lt;/strong&gt;, with that extra useless (except for demos) layer, a lot more. That’s why, from my knowledge over 10 years, every Gherkin automation failed.&lt;/p&gt;

&lt;p&gt;A recent big failure was at a large finance organization (claiming Agile for over 12+ years) in my city. Its Gherkin solution (in Java) was so bad that about 3 times of all development effort (time and money) were spent on trying to maintain those ‘Gherkin BDD tests’. Of course, eventually, the tests were abandoned. The excuse the management used was “&lt;em&gt;the contractors worked on this left, so failed to maintain&lt;/em&gt;”. Of course, this was not the truth. The root problem was a bunch of mediocre programmers, who mistakenly over-estimated their knowledge of test automation, and made a bad choice based on a naive idea of executing “Given-When-Then” user stories that Business Analysts wrote. Sadly, these kinds of mistakes are keeping repeating.&lt;/p&gt;

&lt;p&gt;Besides the human factors, what are the technical reasons why DHH and the creator of Cucumber are against BDD with Gherkin tests? Below is a comparison of the test tiers (based on &lt;a href="https://medium.com/geekculture/maintainable-automated-test-design-d325dd13b868"&gt;Maintainable Automated Test Design&lt;/a&gt;) between a good test syntax framework RSpec and the bad Gherkin (when used for test automation).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dTJOnNJr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b0485ghrs6a1b04lc76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dTJOnNJr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7b0485ghrs6a1b04lc76.png" alt="test tiers" width="880" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The extra effort (right graph) comes from the ‘test-specific English parser’, the part DHH was referring to. Let’s look at an example Cucumber test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Test (Gherkin) Layer&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature: Select Flights 
  As a registered user
  I can select flights

  Scenario: Oneway Trip
    Given I am signed in as "agileway"
    When select oneway trip
    And depart from "Sydney" to "New York" on "07" of "May 2021"
    And click "Continue"
    Then I should see "2021-05-07", "New York" and "Sydney"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Step Definitions Layer!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Given&lt;/span&gt; &lt;span class="sr"&gt;/^I am signed in as "(.*?)"$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;sign_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"agileway"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"testwise"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;FlightPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;When&lt;/span&gt; &lt;span class="sr"&gt;/^select oneway trip$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_trip_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"oneway"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;When&lt;/span&gt; &lt;span class="sr"&gt;/^click "(.*?)"$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click_continue&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;When&lt;/span&gt; &lt;span class="sr"&gt;/^depart from "(.*?)" to "(.*?)" on "(.*?)" of "(.*?)"$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month_year&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_depart_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_arrive_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_depart_day&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_depart_month&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;month_year&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;Then&lt;/span&gt; &lt;span class="sr"&gt;/^I should see "(.*?)", "(.*?)" and "(.*?)"$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;the_page_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page_source&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;the_page_source&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="kp"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;the_page_source&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="kp"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;the_page_source&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="kp"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Helper and Pages Tier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Helper: &lt;em&gt;support/step_helper.rb&lt;/em&gt;, included in &lt;em&gt;support/env.rb&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:xpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"//input[@value=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Sign in&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Page class: pages/flight_page.rb&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"abstract_page.rb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FlightPage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;AbstractPage&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_trip_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trip_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:xpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"//input[@name='tripType' and @value='&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;trip_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;']"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="c1"&gt;# more functions ... &lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;click_continue&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:xpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"//input[@value='Continue']"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note the helper and page classes, if designed well, can be 100% reusable, regardless of what the top syntax framework you use, Cucumber, Capybara or RSpec.&lt;/p&gt;

&lt;p&gt;As a comparison, below is the test (top) layer for RSpec.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;sign_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"agileway"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"testwise"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
 &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"One-way trip"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;flight_page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;FlightPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_trip_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"oneway"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_depart_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sydney"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_arrive_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"New York"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      
   &lt;span class="n"&gt;flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_depart_day&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"07"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_depart_month&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"May 2021"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;flight_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click_continue&lt;/span&gt;
   &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="kp"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2021-05-07 Sydney to New York"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no middle tier (&lt;em&gt;helper/page class tier is the same&lt;/em&gt;), therefore, the test script is much easier to maintain. You can get the above test scripts from &lt;a href="https://github.com/testwisely/agiletravel-ui-tests"&gt;Github&lt;/a&gt;. For a more comprehensive example, see this article: &lt;a href="https://zhiminzhan.medium.com/whenwise-regression-test-suite-reaches-500-selenium-tests-and-300k-test-executions-84279ae0ed35"&gt;WhenWise Regression Test Suite Reaches 500 Selenium tests and ~300K Test Executions&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;RSpec is the most popular “Behaviour Driven Development for Ruby”. &lt;a href="https://rubygems.org/gems/rspec/versions/3.8.0"&gt;RSpec v3.8.0&lt;/a&gt; alone has over 193 million downloads on RubyGems. While RSpec may also be used for unit or integration tests, its download count is quite impressive. As a comparison, the most-downloaded &lt;a href="https://rubygems.org/gems/cucumber/versions/3.1.2"&gt;Cucumber v3.1.2&lt;/a&gt; is merely 8.8 million.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cucumber is not the first failed test framework that uses English-like syntax for automated testing (it may be for other uses, but definitely not real test automation). Do you still remember &lt;a href="http://fitnesse.org/"&gt;FitNesse&lt;/a&gt; (it was quite big about 10 years ago, an example &lt;a href="http://fitnesse.org/FitNesse.SuiteAcceptanceTests.SuiteEditResponderTests.TestEditNewPage"&gt;here&lt;/a&gt;)? Now it is hardly mentioned.&lt;/p&gt;

&lt;p&gt;Some frustrating Gherkin ‘test engineers’ might grudge: “&lt;em&gt;Maybe you just don’t understand Cucumber&lt;/em&gt;”. Sorry, I do know Cucumber well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cucumber was developed in Ruby; I am a &lt;a href="http://testwisely.com/blog/posts/buildwise-won-runner-up-prize-at-10th-ruby-award"&gt;winner of the 10th Ruby Award&lt;/a&gt;. I also worked for many years as a senior software engineer (contractor) using Java, C# and JavaScript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://agileway.com.au/testwise"&gt;TestWise&lt;/a&gt;, a next-gen functional testing IDE I created, supports Cucumber. (Kent Beck, the father of Agile, once said: ‘&lt;em&gt;&lt;a href="https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864"&gt;I hated the idea so I had to try it&lt;/a&gt;.&lt;/em&gt;’)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://agileway.com.au/buildwise"&gt;BuildWise&lt;/a&gt;, an international award-winning Continuous Testing server I created, supports executing Cucumber tests too.&lt;br&gt;
It shall be fair to say that my Cucumber/Gherkin knowledge is better than most ‘cucumber automation engineers’.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real functional test automation is far more than a fancy demo. If you truly believe Gherkin automation tests are the way to go, please do it well, don’t ruin the reputation of test automation. Make test automation visible and relevant to the team daily, enabling the team to &lt;a href="https://medium.com/nerd-for-tech/did-you-push-software-updates-into-production-yesterday-96bf5898d854"&gt;release to production multiple times a day&lt;/a&gt;. That’s what I can do with raw Selenium WebDriver tests in RSpec for my web apps: ClinicWise, SiteWise, and &lt;a href="https://whenwise.com"&gt;WhenWise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are an architect/manager of an organization doing Cucumber Test automation (usually fooled by fake agile coaches), I suggest you write a concerned email but not too direct and save it (that’s important) or even start preparing your scapegoat. When the shit hits the fan, you can say: “&lt;em&gt;I told you so&lt;/em&gt;” or “&lt;em&gt;that fake agile coach’s fault&lt;/em&gt;’.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NrViSH4I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efxiwq0h7m3la495jkyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NrViSH4I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efxiwq0h7m3la495jkyq.png" alt="Background image credit: Futurama S2E4" width="880" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Do you mean BDD is just hype?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, Check out &lt;a href="https://zhiminzhan.medium.com/a-practical-advice-on-rejecting-gherkin-for-test-automation-c429ce9457cd"&gt;BDD Clarified: BDD ≠ “Given-When-Then” (Gherkin)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. My team is trying to introduce Gherkin, what can I do to stop that?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://zhiminzhan.medium.com/a-practical-advice-on-rejecting-gherkin-for-test-automation-c429ce9457cd"&gt;A Practical Advice on Rejecting Gherkin for Test Automation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Related articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My eBook: “&lt;a href="https://leanpub.com/practical-web-test-automation"&gt;Practical Web Test Automation with Selenium WebDriver&lt;/a&gt;”&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/why-do-most-ui-test-automation-fail-part-2-wrong-choice-of-test-syntax-framework-2289aff0d81e"&gt;Why Do Most UI Test Automation Fail? (Part 2: Wrong Choice of Test Syntax Framework)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/testing-pyramid-clarified-af45535bed8b"&gt;Testing Pyramid Clarified&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/user-story-card-clarified-c10df3f1229a"&gt;User Story Card Clarified&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/continuous-testing-clarified-52c90e9a6825"&gt;Continuous Testing Clarified&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/done-done-in-agile-8cd95f077411"&gt;“Done, Done” in Agile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/geekculture/agileway-test-automation-formula-bcf550616d32"&gt;AgileWay Test Automation Formula&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhiminzhan.medium.com/selenium-vs-x-y-z-all-these-years-979b8aa34125"&gt;Selenium vs X, Y, Z, …, all these years&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>selenium</category>
      <category>cucumber</category>
      <category>gherkin</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
