<?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: David🦉</title>
    <description>The latest articles on DEV Community by David🦉 (@davidz).</description>
    <link>https://dev.to/davidz</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%2F75591%2F9ccc4f87-549e-4618-a8b8-e1d4bca98a28.jpg</url>
      <title>DEV Community: David🦉</title>
      <link>https://dev.to/davidz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/davidz"/>
    <language>en</language>
    <item>
      <title>How we do automated testing on our backend</title>
      <dc:creator>David🦉</dc:creator>
      <pubDate>Thu, 26 Mar 2020 11:11:15 +0000</pubDate>
      <link>https://dev.to/davidz/how-we-do-automated-testing-on-our-backend-3cbj</link>
      <guid>https://dev.to/davidz/how-we-do-automated-testing-on-our-backend-3cbj</guid>
      <description>&lt;p&gt;After sharing how we do automated testing on our fronted &lt;a href="https://dev.to/davidz/how-we-do-automated-testing-on-our-frontend-b10"&gt;in my previous post&lt;/a&gt; I wanted to share too how we test our backend services using our API. You can find the extended version of this post &lt;a href="https://product.spotahome.com/qa-spotahome-part-2-testing-our-backend-platform-907687c42fcf" rel="noopener noreferrer"&gt;in our blog&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;API/Integration tests must be faster to develop and run since they do not require any user interface to interact with since they directly hit the endpoints designed in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  The platform behind
&lt;/h2&gt;

&lt;p&gt;Our backend platform follows the micro-service pattern, decomposing the application in small services that take care of one isolated piece of the whole business. We follow a hexagonal architecture (aka ports and adapters) to avoid having them highly coupled and facilitating testing activities. To expose all the endpoints we make use of APIs which are consumed by our BFFs using GraphQL.&lt;/p&gt;

&lt;p&gt;Regarding the base code, it is written in PHP and it follows the Domain driven design (DDD) pattern. With all this what we have in the end are different bounded contexts (BCs) that completely isolate each side of the business.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test tool
&lt;/h2&gt;

&lt;p&gt;To test this we opted for Gauge which is an open source tool to write and run tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fav9gw5py5gree3418pn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fav9gw5py5gree3418pn0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gauge was created by ThoughtWorks and it is supported by a wide community. It can be used in any platform and it supports many languages for writing your test code. Two key features that we liked are that it’s BDD and it supports data-driven executions, making your tests more escalable.&lt;/p&gt;

&lt;p&gt;For writing the tests scenarios themselves Gauge uses specification and concept files. Basically, specification files are those containing the scenarios written in a set of steps and concept files are just a collection of steps that you can reuse in the scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  A spec file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Booking Request
======================
Tags: booking

Create booking request and charge (OK)
- - - - - - - - - - - - - - - - - - - - - - 
* Login with "test-user"
* Create a booking lead for listing id "999999" with move in "2021–01–01" and move out "2021–01–31"
* Create a booking request from booking lead
* Charge booking
* Wait until the booking request is converted into booking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one above is an example of a specification file with one scenario written in Markdown language. The scenario just describes what they do in different steps. Each one of these steps has test code behind, but they can also relate to a concept file since they can be a set of steps themselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  A concept file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Charge booking
* JSON from file "./bookings/chargeBookingRequest.json" is set as variable "chargeJson"
* Set path "/payment/booking-requests/{id}/chargeNow" as name "charge" replacing path variable "{id}" with variable "bookingRequest"
* An HttpSampler with name "chargeBR" and path in variable "charge" and type "PUT" and port "xxx" and json "chargeJson"
* Response code is equal to "204"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we show an example for the step “Charge booking” that we presented in our spec file. You see all the steps behind that one, meaning that every time we call “Charge booking” from a spec file, all these steps will run.&lt;br&gt;
We usually do that when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are a lot of small steps required for just one high level task&lt;/li&gt;
&lt;li&gt;We do not want to show so much logic at the spec file level&lt;/li&gt;
&lt;li&gt;We are going to reuse such step in many test scenarios&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step implementation
&lt;/h3&gt;

&lt;p&gt;Let’s show as an example the implementation for the step “An HttpSampler with name “chargeBR” and path in variable “charge” and type “PUT” and port “xxx” and JSON “chargeJson””&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Step("An httpSampler with name &amp;lt;name&amp;gt; and path &amp;lt;path&amp;gt; and type &amp;lt;type&amp;gt; and port &amp;lt;port&amp;gt; and json &amp;lt;json&amp;gt;")
public void setHttpSamplerNameTypePortBodyGiven(String name, String path, String type, Integer port, String json) {

// Java code to send an http request with the passed on parameters

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;@Step&lt;/code&gt; annotation. It denotes that the function is a step used in the spec files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build
&lt;/h2&gt;

&lt;p&gt;To manage and build the project we use Maven. Maven is an extensively used build automation tool from Apache used in Java projects, although it can also be used for other languages. We’ve been working with it from the very beginning and it’s been useful to us given the big tree of dependencies that we have to maintain, both in-house and external ones.&lt;/p&gt;

&lt;p&gt;Since we’ve got all our API tests in the same place, they are all placed in the same repository. So after updating our test collection, be it adding new tests or refactoring, the build is triggered just after pushing the changes to master branch to make sure all is fine. With that, we make available the latest version of the tests for the BCs to grab and run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fynho8d9q3o88n10h9pwl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fynho8d9q3o88n10h9pwl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the CI
&lt;/h2&gt;

&lt;p&gt;If you remember from our first post, we use Brigade as our CI system and our BCs use it in the same way. For every BC, we’ve got a Brigade file to indicate the events that must run in such pipeline.&lt;br&gt;
With that, GitItNow (in-house developed tool), makes quite easy to interact with the pipeline and brings visibility to the whole process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbxvq6tx16vfrt8aotcc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbxvq6tx16vfrt8aotcc6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above there’s one example of a pipeline for one of our BCs.&lt;br&gt;
For the api-tests event it gets the latest successful build from the test repository and runs it.&lt;/p&gt;

&lt;p&gt;Worth mentioning too that we have enabled parallelization in our Ci runs to be able to run them faster and react soon in case anything goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;With all commented here, we ended up with a robust framework that enables us to track the quality of the backend code we deploy and react soon in case a red flag shows up. Is it perfect? Nope (I'd say nothing is). We still deal with collateral issues such as stuck queues or false positives due to misleading data or other kind of human errors. But there are also some other aspects such as the escalability that a BDD approach gives us, getting to a point where there are so many steps developed that we almost don't need to develop more but use what exists.&lt;/p&gt;

&lt;p&gt;Hope you enjoyed the post 🚀&lt;/p&gt;

</description>
      <category>testing</category>
      <category>backend</category>
      <category>java</category>
      <category>gauge</category>
    </item>
    <item>
      <title>How we do automated testing on our frontend</title>
      <dc:creator>David🦉</dc:creator>
      <pubDate>Wed, 12 Feb 2020 10:38:06 +0000</pubDate>
      <link>https://dev.to/davidz/how-we-do-automated-testing-on-our-frontend-b10</link>
      <guid>https://dev.to/davidz/how-we-do-automated-testing-on-our-frontend-b10</guid>
      <description>&lt;p&gt;And here comes my first post ⭐&lt;/p&gt;

&lt;p&gt;In this post I'll share our learnings for testing our frontend platform at &lt;a href="https://spotahome.com"&gt;Spotahome&lt;/a&gt; and how we moved from Selenium to Cypress. You can find the complete post &lt;a href="https://product.spotahome.com/qa-at-spotahome-part-1-testing-our-frontend-platform-ef3d3af28238"&gt;in our blog&lt;/a&gt; in case you want to read further.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C3_mXd2W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ftqu2g1tjye1oavcb0ue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C3_mXd2W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ftqu2g1tjye1oavcb0ue.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our front-end architecture is built up based on the BFF approach using Node + React, that combines the speed of JavaScript and uses new ways of rendering websites, making them highly dynamic and responsive to the users. For it, we make use of GraphQL to request data to the backend. GraphQL was developed to cope with the need for more flexibility and efficiency that developers experience when interacting with REST APIs, making the workflow much more efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lg2LV5R7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i529tkflpi8uqze0u8ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lg2LV5R7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i529tkflpi8uqze0u8ik.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The test tool
&lt;/h2&gt;

&lt;p&gt;A while ago we decided to start using Cypress, a tool that intends to overtake Selenium (or to make you forget about it right away), by ripping off all its setbacks such as the set up and debugging. If you want to dive deeper into this comparison, &lt;a href="https://crossbrowsertesting.com/blog/test-automation/selenium-vs-cypress/"&gt;here&lt;/a&gt; you can read further.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxlTCYJA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dxyak590wds6ptj32v3f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxlTCYJA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dxyak590wds6ptj32v3f.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cypress is a testing tool built for the modern web. One can see lots of similarities among them, but the benefits and constraints you will face are quite different depending on which one you use. If what you’re seeking for is easiness of setting up and debugging, Cypress can be a pretty good match.&lt;/p&gt;

&lt;p&gt;Cypress is an open source test runner that lets you write tests in JavaScript code. You can checkout their repository and contribute to their mission if you feel so.&lt;/p&gt;

&lt;p&gt;In our case, we made the shift from Selenium to Cypress for several reasons. The most important one, it seemed to be pretty easy to set up and work with, and that enabled us from QA to scale testing efforts by spreading its use among QAs and devs. Since it uses JavaScript, our dev team welcomed it and started to use it almost friction-less. &lt;/p&gt;

&lt;h2&gt;
  
  
  The technology underneath
&lt;/h2&gt;

&lt;p&gt;Cypress is written in JavaScript and lets you write tests in JavaScript. One thing to keep in mind is that Cypress is built up on top of Mocha, so if you are already used to write test scripts using Mocha as your test framework, you are likely to find some old friends here.&lt;/p&gt;

&lt;p&gt;From Mocha, Cypress adopts its BDD syntax which fits nicely with both integration and unit testing. Another bundled technologies that Cypress comes with are Chai, Chai-jQuery, Sinon, and Sinon-Chai.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the tests
&lt;/h2&gt;

&lt;p&gt;When running the test in GUI mode, we see the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GH_j89L9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uk6s7g8adhksgibqiu8r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GH_j89L9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uk6s7g8adhksgibqiu8r.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What Cypress does is open a browser, then on the left you see the ‘live log’ which reflects everything the browser does during the test, and on the right you have the application under test&lt;/p&gt;

&lt;p&gt;Worth to mention here that Cypress is not an outsider tool that communicates with the browser through an API, but that it runs directly in the browser, and this makes it to be so close to the web application under test that you can do things that you can’t do in Selenium, such as stubbing DOM APIs.&lt;/p&gt;

&lt;p&gt;One of the key features here is the &lt;strong&gt;debuggability&lt;/strong&gt;. When the test finishes or fails, the state is not reset, meaning that you can hover around the ‘live log’ to see what or where was Cypress actually doing at that moment in time -a screenshot is displayed for that moment in time for every action. You can even open the browser console and get a full description of the steps you select on the log. This feature has boosted the whole process of test development so much that we can’t go without it now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the CI
&lt;/h2&gt;

&lt;p&gt;For our CI system we use Brigade, which is an event-based tool for running automated tasks on the cloud. Our colleagues from the DevOps team wrote a series of posts about how this works, so in case you are interested you can take a deep dive here.&lt;/p&gt;

&lt;p&gt;As commented at the beginning of the post, we split our application in different BFFs, which lets us to build and deploy them independently, making the release process swifter and more easy to scale.&lt;/p&gt;

&lt;p&gt;All of these BFFs have at least one e2e test repository attached, that will be triggered as a different event every time a pull request is merged.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zOgLs5ov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bqqiot3rqtoy1i1trc30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zOgLs5ov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bqqiot3rqtoy1i1trc30.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This case above illustrates the typical series of events that happen when merging a new Pull Request into our staging environment -BFF pipeline. First comes the push event (including unit tests 😍), then the deployment to the staging environment, and finally a post_deploy_hook triggers the configured e2e tests. We’ve got Slack integrated into this loop to notify us of every step and warn us in case anything went wrong.&lt;/p&gt;

&lt;p&gt;The e2e tests are stored in a repository of their own (accounting to more than 15 repositories). We commit every change on e2e test code to those repositories to create a new Docker image that will be grabbed and executed by the BFF whenever the event comes.&lt;/p&gt;

&lt;p&gt;Focusing on the e2e test event, the command we use to run the tests is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cypress run --record --group 4x-electron --parallel --ci-build-id ${buildId}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Briefly analyzing the params:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;record: Sends the video recordings to Cypress Dashboard to keep track of the runs&lt;/li&gt;
&lt;li&gt;group : Group recorded tests together under a single run&lt;/li&gt;
&lt;li&gt;parallel: Enables parallelization of the tests&lt;/li&gt;
&lt;li&gt;buildId: Necessary to defining a unique build or run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wait what? Sends the video recordings to a dashboard?&lt;/p&gt;

&lt;h2&gt;
  
  
  Cypress Dashboard
&lt;/h2&gt;

&lt;p&gt;The last part of the journey. Cypress Dashboard is a service that allows us to access to recorded tests, being pretty useful when we run them on the CI. It gives us information about all the test runs triggered, including logs, screenshots and videos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j94YfuFq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uxums1qz43mqa9up7bbx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j94YfuFq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uxums1qz43mqa9up7bbx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even though we could go without the Dashboard, we found it pretty helpful and use it widely -we are on a paid plan that allows several of our engineers to have access to it and work in a more efficient way.&lt;/p&gt;

&lt;p&gt;The big win here is that we can be aware of the state of the application quite fast, and we can address any issue right away whenever anything fails. Once the failure is revealed and the potential impact calculated, we either fix the issue and test it again ASAP or we snooze the failing assertion until it gets fixed, so that we don’t introduce noise in the pipeline.&lt;/p&gt;

&lt;p&gt;This is all, I hope you find it useful! In case you had any question or suggestions they are more than welcome 💚 &lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
      <category>selenium</category>
      <category>firstpost</category>
    </item>
  </channel>
</rss>
