<?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: Rodrigo Matola</title>
    <description>The latest articles on DEV Community by Rodrigo Matola (@rodmatola).</description>
    <link>https://dev.to/rodmatola</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%2F578710%2F5c2316b4-80b3-40cf-b8f3-20fba327e173.JPG</url>
      <title>DEV Community: Rodrigo Matola</title>
      <link>https://dev.to/rodmatola</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rodmatola"/>
    <language>en</language>
    <item>
      <title>Stop using Appium (if you have access to the source code)</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Fri, 27 Oct 2023 04:06:41 +0000</pubDate>
      <link>https://dev.to/rodmatola/stop-using-appium-if-you-have-access-to-the-source-code-1bk4</link>
      <guid>https://dev.to/rodmatola/stop-using-appium-if-you-have-access-to-the-source-code-1bk4</guid>
      <description>&lt;p&gt;This text is to tell one reason that, if you have access to the source code of your mobile app, you should stop using Appium and use the native testing framework instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Most of the mobile projects I worked on did not have a complete mobile CI pipeline due to the costs involved in building/renting a device farm. Only in 2 projects the mobile tests ran on CI: one the CI already existed and the other we built during the project, both running on a Mac Mini, and not in an automatic way.&lt;/p&gt;

&lt;p&gt;What usually happened is that I coded my tests, using Appium with Ruby, and ran them on my own machine. The problem is that putting an Android emulator and an iOS simulator running at the same time practically means you can't use your computer for anything else.&lt;/p&gt;

&lt;p&gt;In this situation, the tests only ran if I ran the tests.&lt;/p&gt;

&lt;p&gt;In the project that gave the idea to write this text, the Devs did not do unit tests and the “it's ready, we just need to test it” was often said. So all responsibility for testing relied on me and the other QA.&lt;/p&gt;

&lt;p&gt;As running the tests on the emulator and simulator at the same time “locks” the machine, it ended up that there was only automation code, but the tests were done manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;One day, while writing testing code, I wasn't able to make Appium click or validate a field on iOS at all. Then I thought: “enough! This responsibility cannot be only mine!” That happened during the morning.&lt;/p&gt;

&lt;p&gt;In the afternoon I began to look for how to automate UI with Swift and &lt;a href="https://testautomationu.applitools.com/introduction-to-ios-test-automation-with-xcuitest/"&gt;found this course from Test Automation University (TAU)&lt;/a&gt;, from Aplitools. I spent this afternoon learning XCUITest. The course has 1h30min. I must have taken about 3 hours to finish.&lt;/p&gt;

&lt;p&gt;The next day I automated a feature as an example and called the dev to talk. Since everything was already done in Ruby, it was just a matter of “translating” it into Swift.&lt;/p&gt;

&lt;p&gt;What would be the idea: the idea is, since the tests will be at the same project, in the same repository, when the developer finishes the code, play the tests before push the code. If a test broke, we could look together at what was happening and fix the problem.&lt;/p&gt;

&lt;p&gt;Even though I was still responsible for coding the tests, at least the tests would run, even with manual triggering. And I wouldn't be the only one responsible for that. I would no longer need to worry about automated scenarios.&lt;/p&gt;

&lt;p&gt;After a while I was already being asked when it took me a while to merge a test PR! We achieved 73% coverage on iOS practically overnight!&lt;/p&gt;

&lt;p&gt;Of course, I also looked for &lt;a href="https://testautomationu.applitools.com/espresso-mobile-testing-tutorial/"&gt;Espresso courses for Android&lt;/a&gt;. And I also found it at TAU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appium X Native Automation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Advantages of Appium
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Several languages (Ruby, Java, Python…)&lt;/li&gt;
&lt;li&gt;1 code, 2 platforms (or 3, if we consider web)&lt;/li&gt;
&lt;li&gt;Test on the apk/app, which is what the customer will receive&lt;/li&gt;
&lt;li&gt;Automation of “the entire device”, for example camera, gallery…&lt;/li&gt;
&lt;li&gt;Easier to get material about E2E testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was reading that if you put a security tool, which I don't remember the name of, in the application, it is mandatory to test it on the apk/app, because directly in the code it is not reliable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantages of Appium
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;“Segregated” QA&lt;/li&gt;
&lt;li&gt;One responsible person&lt;/li&gt;
&lt;li&gt;Additional integration required, as the code is in another repository&lt;/li&gt;
&lt;li&gt;Slower (up to 8x)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages in my context
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It is necessary to build the apk/app on the QA machine&lt;/li&gt;
&lt;li&gt;Run automation manually and locally, since we didn't have a CI&lt;/li&gt;
&lt;li&gt;Free CIs do not include the diversity needed for mobile testing&lt;/li&gt;
&lt;li&gt;“Impossible” to use the computer while running mobile tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remembering that these lists are based on my experience. For you it may be different.&lt;/p&gt;

&lt;h3&gt;
  
  
  Native automation advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;“Dev” language&lt;/li&gt;
&lt;li&gt;You “guarantee” that the tests will be run (we have to trust our team mates)&lt;/li&gt;
&lt;li&gt;Split testing responsibility&lt;/li&gt;
&lt;li&gt;More interaction and exchange between Devs and QAs&lt;/li&gt;
&lt;li&gt;“Easier” to run locally&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages native automation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learning and dealing with two (or three) different languages at the same time&lt;/li&gt;
&lt;li&gt;Maintenance in two (or three) codes&lt;/li&gt;
&lt;li&gt;Automation only in the context of the application. Camera and other interactions need to use UIAutomator, in case of Android.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Talking to other QAs who use this approach and reading some articles on the internet, the advantages outweigh the disadvantages. And I'm seeing it.&lt;/p&gt;

&lt;p&gt;Getting started with native automation is just the beginning. In the near future I want to go deeper in the test pyramid and help with instrumented and unit testing.&lt;/p&gt;

&lt;p&gt;And you, what do you think of the idea of migrating your tests to the development language? Comment here!&lt;/p&gt;

&lt;p&gt;And share this post so more QAs see that it's cool to be closer to development.&lt;/p&gt;

&lt;p&gt;And keep Testing Softly!&lt;/p&gt;

</description>
      <category>qa</category>
      <category>espresso</category>
      <category>xcuitest</category>
      <category>appium</category>
    </item>
    <item>
      <title>Who writes the BDD?</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Sat, 11 Mar 2023 04:36:39 +0000</pubDate>
      <link>https://dev.to/rodmatola/who-writes-the-bdd-14f4</link>
      <guid>https://dev.to/rodmatola/who-writes-the-bdd-14f4</guid>
      <description>&lt;p&gt;Being short and sweet, except for Dan North, who created BDD, I’d say&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nobody writes the BDD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What you write are stories, scenarios, cases, scripts, screenplays or any other name you like but BDD. If we translate the meaning of the abbreviation, Behavior Driven Development, you will see that it makes no sense to say “I will write the behavior-driven development”.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“BDD uses a story as the basic unit of functionality”*.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;BDD is a practice. What you can do is describe this practice, not write it down. Making a comparison, it is the same as asking “who writes Scrum”? In this case we have two responsible, Jeff Sutherland and Ken Schwaber, who write the Scrum Guide. The rest practice Scrum just like they practice BDD.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"BDD is as much about the interactions between the various people in the project as it is about the outputs of the development process"*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;*Quotes from Dan North’s article “&lt;a href="https://dannorth.net/whats-in-a-story/"&gt;What’s in a Story&lt;/a&gt;”.&lt;/p&gt;

&lt;h2&gt;
  
  
  BDD, Cucumber, Gherkin
&lt;/h2&gt;

&lt;p&gt;It is very common to treat these three terms as if they were the same thing. Despite being closely linked, each term is independent and have “its own life”.&lt;/p&gt;

&lt;h3&gt;
  
  
  BDD
&lt;/h3&gt;

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

&lt;p&gt;It is a software development practice that consists of writing application behavior before testing and development. I put tests first because BDD was a response to TDD (Test Driven Development).&lt;/p&gt;

&lt;p&gt;BDD would be another version of TDD, with behavior-based tests written before development. Like TDD, BDD consists of 3 phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We start by collaboratively discovering the scope of behavior required by the story.&lt;/li&gt;
&lt;li&gt;Once we agree with this behavior, we write the specification in business-readable language.&lt;/li&gt;
&lt;li&gt;Finally, we automate the written specification to verify that the system actually behaves as expected.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cucumber
&lt;/h3&gt;

&lt;p&gt;"Cucumber is a tool that supports BDD.&lt;/p&gt;

&lt;p&gt;Cucumber reads executable specifications written in plain text and validates that the software does what those specifications say. The specifications consists of multiple examples, or scenarios.&lt;/p&gt;

&lt;p&gt;Each scenario is a list of steps for Cucumber to work through. Cucumber verifies that the software conforms with the specification and generates a report indicating success or failure for each scenario.&lt;/p&gt;

&lt;p&gt;In order for Cucumber to understand the scenarios, they must follow some basic syntax rules, called Gherkin". (Copy and paste from &lt;a href="https://cucumber.io/docs/guides/overview/"&gt;What is Cucumber?&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Gherkin
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vs-Ar-Ov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9f2hra94ykmvz0nstl3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vs-Ar-Ov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9f2hra94ykmvz0nstl3.jpeg" alt="Image description" width="300" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gherkin, or baby pickles, are tiny cucumbers… (just kidding!)&lt;/p&gt;

&lt;p&gt;"Gherkin is a set of grammar rules that makes plain text structured enough for Cucumber to understand". These rules involve keywords that allow Cucumber to transform written text in natural language into steps for automation. Given, When And Then are some of these keywords.&lt;/p&gt;

&lt;p&gt;Although Given, When And Then are officially part of the language used in BDD, Dan North says "This is not mandatory — you can use a different story format and still be doing BDD — but I am presenting it here because it has been proven to work on many projects of all shapes and sizes".&lt;/p&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BDD: software development practice&lt;/li&gt;
&lt;li&gt;Cucumber: tool that converts text into steps for automation&lt;/li&gt;
&lt;li&gt;Gherkin: language used by Cucumber.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As said at the beginning of this section, the three terms are most often used together, but they are completely independent entities.&lt;/p&gt;

&lt;p&gt;Some frameworks do not use Given, When And Then, such as Gauge, Robot Framework and even Cucumber itself! I can talk about this in another article.&lt;/p&gt;

&lt;h2&gt;
  
  
  You don't do BDD
&lt;/h2&gt;

&lt;p&gt;I’m sure many of you, like me, learned BDD together with Cucumber as a tool for automating tests. I just say that&lt;/p&gt;

&lt;p&gt;If you only use Cucumber to automate tests, you don’t do BDD&lt;/p&gt;

&lt;p&gt;There’s nothing wrong with this practice, we just can’t call it BDD. As the name implies, BDD is a development technique, not a testing technique. If you use it just for testing, you do &lt;a href="https://dzone.com/articles/behavior-driven-testing-in-automated-testing-2"&gt;BDT (Behaviour Driven Testing)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Until now, only in one team we almost did BDD…&lt;/p&gt;

&lt;p&gt;And you, do you do BDD or BDT?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;References&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dannorth.net/introducing-bdd/"&gt;Introducing BDD&lt;/a&gt;, Dan North&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dannorth.net/whats-in-a-story/"&gt;What’s in a Story?&lt;/a&gt;, Dan North&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jbehave.org/"&gt;What is JBehave?&lt;/a&gt;, JBehave.org&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cucumber.io/docs/bdd/"&gt;Behaviour-Driven Development&lt;/a&gt;, Cucumber Docs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cucumber.io/docs/bdd/myths/"&gt;Myths about BDD&lt;/a&gt;, Cucumber Docs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://school.cucumber.io/"&gt;BDD with Cucumber&lt;/a&gt;, Cucumber School&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://specflow.org/blog/why-is-bdd-one-of-the-most-misunderstood-concepts/"&gt;Why is BDD one of the most misunderstood concepts?&lt;/a&gt;, Specflow.org&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pt.slideshare.net/pnakhat/myths-and-challenges-of-behaviour-driven-development"&gt;Myths and Challenges of Behaviour Driven Development&lt;/a&gt;, Pankaj Nakhat (SlideShare)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dzone.com/articles/behavior-driven-testing-in-automated-testing-2"&gt;Behavior Driven Testing in Automated Testing&lt;/a&gt;, Alex Jones in Devops Zone&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>bdd</category>
      <category>qa</category>
      <category>testing</category>
    </item>
    <item>
      <title>Number of Devs X Number of QAs: Why do I think it's an ineffective measure?</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Mon, 21 Nov 2022 02:14:58 +0000</pubDate>
      <link>https://dev.to/rodmatola/number-of-devs-x-number-of-qas-why-do-i-think-its-an-ineffective-measure-3nmp</link>
      <guid>https://dev.to/rodmatola/number-of-devs-x-number-of-qas-why-do-i-think-its-an-ineffective-measure-3nmp</guid>
      <description>&lt;p&gt;Once, after saying that I had a lot of things to test, I was asked how many developers per QA were in my old job, since I always referred to it as having “ideal teams”.&lt;/p&gt;

&lt;p&gt;I replied that they were 4 to 6 devs. It was usually 2 Android and 2 iOS developers, and some teams had 2 more for the backend. I received a comment: “hey, it's the same amount we have here. Why do you complain about a lot of work here and there it was ideal?”. At the time I was asked this question, we had 5 devs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task team
&lt;/h2&gt;

&lt;p&gt;The difference was that in the reference teams, all members were working on the same functionality. For example a login. In planning, the designer presented the idea of a screen. If it was too complex, we would already adapt it to be able to deliver in a Sprint.&lt;/p&gt;

&lt;p&gt;Frontend developers were usually split with one person laying out the screens and the other doing the functions. Unit/instrumented tests were also split. In the planning, the contract with the API was also defined and mocks were delivered before the services, for the frontend devs to be able to start development. Each one was responsible for testing their code. If unit tests were covered, QA didn't have to worry about these tests.&lt;/p&gt;

&lt;p&gt;In the “current” team each dev takes an item from the backlog. Taking a bank app as an example, and 4 devs, login, transfer, pay and deposit will be developed in a Sprint. Also, the backend is developed by another team.&lt;/p&gt;

&lt;p&gt;To get worse, NO unit testing was done. The phrase “it's ready, test it” or “it's ready, just need to test” always happened. That is, all responsibility for the QA. It was common to receive a “done” where the main action button did not work. Or something that was working break with the merge of another functionality. It was practically impossible to make a decent regression and bugs always went into production. Same for the APIs.&lt;/p&gt;

&lt;p&gt;So, in addition to testing the front, it was necessary to test the back. Almost always the frontend devs had to do some workarounds to fit the backend's responses, which usually caused errors if the API responded differently.&lt;/p&gt;

&lt;p&gt;In this context, I've heard "you haven't tested this, why?" or “I'm sorry, but your tests are shallow”. My analogy was “it's impossible to deep dive into 4 or 5 pools at the same time. You can only take the leaves off the surface.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Correct metric: features / QA
&lt;/h2&gt;

&lt;p&gt;With that, the metric I consider correct is features per QA (or tasks/QA). So we have a measure of how much a QA is being “overloaded”. &lt;a href="https://www.planview.com/resources/articles/benefits-wip-limits/"&gt;The ideal number will vary for each QA, with the size/complexity of the functionality and for each team&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I would follow the “two is company, three is a crowd”, for a two-week Sprint. Before I want to make it clear that the quote is valid for “total QAs”, that is, those who care about the end-to-end quality in all layers, and not “only do tests”.&lt;/p&gt;

&lt;p&gt;Two is company when talking about completely new functionalities, where the backend and frontend are being developed from scratch. In this case, even though it's just one feature, you're looking at two different systems. And I'm not including automation. If we include automation, perhaps one functionality is enough.&lt;/p&gt;

&lt;p&gt;The team also has a big influence on metrics. If everyone cares about quality, QAs can play their role much better. On the other hand, task teams, like the one described above, have a high chance of bugs being produced, and not resolved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find your number
&lt;/h2&gt;

&lt;p&gt;Over time, in the sprint planning you will be able to measure the size of the task and its complexity. Align the priorities with the PO and choose the two most critical features for a “perfect delivery”, features that you will dive deep into and “clean up” everything possible.&lt;/p&gt;

&lt;p&gt;I recommend taking a look at &lt;a href="https://agilepearls.wordpress.com/tag/product-risk-management-prisma/#:~:text=PRISMA%20(Product%20RISk%20Management)%20is,a%20large%20number%20of%20years."&gt;PRISMA&lt;/a&gt; (Product RISk MAnagement) technique, from &lt;a href="http://www.erikvanveenendaal.nl/en/"&gt;Erik van Veenendaal's&lt;/a&gt;. And always try to &lt;a href="https://dev.to/rodmatola/how-i-automate-tests-or-try-to-inside-sprint-cio"&gt;include automation within the Sprint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, just because you chose two main features doesn't mean you'll ignore everything else. Unforeseen events happen, bugs in production arise, new requirements are discovered. Focus on the main features but also take a look at the application as a whole.&lt;/p&gt;

&lt;p&gt;And you, do you know leaders who use this Devs / QA metric? Tell me how it is working!&lt;/p&gt;

</description>
      <category>qa</category>
      <category>developmentprocess</category>
      <category>metrics</category>
    </item>
    <item>
      <title>NEVER trust in unattended data</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Sun, 13 Nov 2022 14:34:25 +0000</pubDate>
      <link>https://dev.to/rodmatola/never-trust-in-unattended-data-8nm</link>
      <guid>https://dev.to/rodmatola/never-trust-in-unattended-data-8nm</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image by Jen Theodore on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I will start with the phrase&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Against data there are no arguments"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and show in this text that there are arguments. And many…&lt;/p&gt;

&lt;p&gt;This text can be considered an addition to "&lt;a href="https://dev.to/rodmatola/automation-metrics-some-problems-3lc6"&gt;Automation Metrics: some problems&lt;/a&gt;".&lt;/p&gt;

&lt;h2&gt;
  
  
  Contextualizing
&lt;/h2&gt;

&lt;p&gt;Data and metrics, depending what company, are difficult information to have access. They are often in the hands of another area (which is not IT and development) and it may be bureaucratic to gain access to Google Analytics, for example. And you may not get it.&lt;/p&gt;

&lt;p&gt;This situation, for us QAs, is very bad, because we are left without foundations on what to prioritize in tests and automation, being totally in the "guess".&lt;/p&gt;

&lt;p&gt;However, sometimes (always?) loose data comes to your attention, such as average age of customers, operating systems and browsers used, average browsing time on the site/application etc.&lt;/p&gt;

&lt;p&gt;Since that's all you have, you end up making your testing strategy based on them. But is the information that came to you complete? Or worse, correct?&lt;/p&gt;

&lt;p&gt;The examples I will use are real, but with adaptations to fit the text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android or iOS?
&lt;/h2&gt;

&lt;p&gt;In a project that I worked on, we were doing very superficial tests on iOS, only happy paths. That's because the information we had was that about 70% of customers use Android. New features were prioritized for Android. Bugs on iOS, depending on the severity, would find a country house to vacation and not be disturbed.&lt;/p&gt;

&lt;p&gt;I think 30% is a very large number to ignore, but this strategy was agreed with the team and the business area.&lt;/p&gt;

&lt;p&gt;In a certain review, after me and some devs wanted more data, a dev brought some numbers he got from Firebase.&lt;/p&gt;

&lt;p&gt;We found that Android was used by 90% (not 70%), which gave me a relief to know that our strategy was even more right. Relief that only lasted until the next slide.&lt;/p&gt;

&lt;p&gt;This slide showed that Android customers spent an average time of 1.5 minutes on the app, while iOS customers spent around 7-10 minutes (I can't remember the exact time). This information immediately conflicted with the previous one in my head! A minute and a half could mean that people just installed the app to find out what it was about and never used it again! Or used it sporadically.&lt;/p&gt;

&lt;p&gt;The time of 7 to 10 minutes was the time it took to make a complete flow in the app, that is, our focus maybe should be iOS and not Android! Was our whole strategy wrong?&lt;/p&gt;

&lt;p&gt;I went to another team in the next Sprint as the apps were deprioritized for a while. I don't have any more information about the metrics...&lt;/p&gt;

&lt;h2&gt;
  
  
  Time of section
&lt;/h2&gt;

&lt;p&gt;Once we had to set a session time for the person to be logged into the application. This was an Information Security (IS) imposition.&lt;/p&gt;

&lt;p&gt;IS wanted us to set 3 minutes of session time. This time was enough for a query in the app. We had that same 3 minute value as an average time extracted from Analytics. We implement this value.&lt;/p&gt;

&lt;p&gt;Few days (or weeks) later we started to receive complaints that the app was logging off by itself while browsing. We noticed that for some flows, 3 minutes was the time the person would spend if they made the flow directly and without errors, that is, almost like an automation. Of course, ordinary people were taking longer than that.&lt;/p&gt;

&lt;p&gt;A large part of this complaint came when we launched a new paid functionality, previously restricted to a few customers, to basically the entire customer base. As new customers were unable to complete the registration process, they began to complain. Imagine the money lost during that time because of an incorrectly used metric.&lt;/p&gt;

&lt;h2&gt;
  
  
  Average alone means nothing
&lt;/h2&gt;

&lt;p&gt;The following example was adapted from &lt;a href="https://educacao.uol.com.br/disciplinas/matematica/media-desvio-padrao-e-variancia-nocoes-de-estatistica.htm" rel="noopener noreferrer"&gt;UOL Educação&lt;/a&gt; (in Portuguese).&lt;/p&gt;

&lt;p&gt;Your street has several children and you want to develop a product focused on these children. You go to the street houses to ask the age of the children and set up the following table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ages: [9, 9, 9, 1, 1, 1]; 
Average = 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you make your products aimed at 5 year olds. Do you agree that 1-year-olds and 9-year-olds are in very different stages of development than 5-year-olds? You do not sell even one unit of your product.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Average must be accompanied by at least the standard deviation"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you calculate the standard deviation of this sample, you will find the value of 4 for more or less, that is, despite the mean being 5, you can have children aged 5+4=9 and 5-4=1, exactly as in your sample!&lt;/p&gt;

&lt;p&gt;Another example, which is the time taken for a hospital discharge process, was taken from &lt;a href="https://support.minitab.com/pt-br/minitab/19/help-and-how-to/statistics/basic-statistics/supporting-topics/data-concepts/what-is-the-standard-deviation/" rel="noopener noreferrer"&gt;Minitab&lt;/a&gt;.&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%2Fuploads%2Farticles%2Frc2qwmrv2151nfai42ok.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%2Fuploads%2Farticles%2Frc2qwmrv2151nfai42ok.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the two graphs above, the average time is 35 minutes (dashed line), but the standard deviations are 6 and 20, respectively. That is, the average in the first case is more reliable than in the second.&lt;/p&gt;

&lt;p&gt;In the first case you would wait between 29 and 41 minutes (30-40 minutes, rounding up). But in the second, you would wait from 15 to 55 minutes! Imagine you asking "how long is the wait? From 15 to 55 minutes", would you consider it a reliable measure?&lt;/p&gt;

&lt;h2&gt;
  
  
  Use other central tendency measurements
&lt;/h2&gt;

&lt;p&gt;Measures of central tendency indicate a value that best represents the entire data set, that is, they give the tendency of concentration of observed values. (Ref. &lt;a href="http://repositorio.furg.br/bitstream/handle/1/10223/aula2.pdf" rel="noopener noreferrer"&gt;Introdução à Estatística Econômica&lt;/a&gt;, UAB/FURG. In Portuguese)&lt;/p&gt;

&lt;p&gt;In addition to the average, when doing a data analysis, also take a look at the&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;median: value that is in the middle of the sequence, when the data are arranged in ascending order;&lt;/li&gt;
&lt;li&gt;mode: value or values that occur most frequently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the dataset below, taken from &amp;lt;&lt;a href="https://matematicabasica.net/media-moda-e-mediana/" rel="noopener noreferrer"&gt;https://matematicabasica.net/media-moda-e-mediana/&lt;/a&gt;&amp;gt;&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%2Fuploads%2Farticles%2F2gk6rhbbv2ogi0l4zqhe.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%2Fuploads%2Farticles%2F2gk6rhbbv2ogi0l4zqhe.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that the values are much dispersed, and this is confirmed by the measurements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;average: 42.1&lt;/li&gt;
&lt;li&gt;deviation: 23.2&lt;/li&gt;
&lt;li&gt;median: 45.0&lt;/li&gt;
&lt;li&gt;mode: 20.0 and 50 (bimodal)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine that these were the ages of the people using your app and you need to focus your adds on an age group as your budget is low. What age would you focus on?&lt;/p&gt;

&lt;h2&gt;
  
  
  With that alone, can I make an assertive analysis?
&lt;/h2&gt;

&lt;p&gt;No! For example, do our customers use Android or iOS? This is a hypothesis to be tested, so it is necessary to do a &lt;a href="https://en.wikipedia.org/wiki/Statistical_hypothesis_testing" rel="noopener noreferrer"&gt;hypothesis test&lt;/a&gt;. It is also necessary to define the confidence interval.&lt;/p&gt;

&lt;p&gt;The data must be treated to verify its consistency, if it has outliers, which distribution the data obey (normal, chi-square, etc.)&lt;/p&gt;

&lt;p&gt;Anyway, did you realize that just an average is basically useless?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The purpose of this text is to warn that you cannot make decisions based on a single source of information, and not that you need to make fancy calculations (such as hypothesis testing) or have statistical training to do so.&lt;/p&gt;

&lt;p&gt;On the news, you should go after more information to confirm the veracity. The same with data. Not that you need to consult another data source, as you will often have only one source, but look for other interpretations and analysis for the same dataset before making a decision.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I automate tests (or try to) inside Sprint</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Sun, 13 Nov 2022 14:28:56 +0000</pubDate>
      <link>https://dev.to/rodmatola/how-i-automate-tests-or-try-to-inside-sprint-cio</link>
      <guid>https://dev.to/rodmatola/how-i-automate-tests-or-try-to-inside-sprint-cio</guid>
      <description>&lt;p&gt;This is an old post. I don't use Cucumber anymore, but the ideas still the same.&lt;/p&gt;

&lt;p&gt;Attending Meetups and talking to QAs from other companies, the difficulty of implementing test automation within Sprint always come as subject. So I decide to tell how was (and is going) my experience with test automation. Note that this is my recipe and worked for the projects that I passed. Consider if it fits in your case, ok?&lt;/p&gt;

&lt;p&gt;In order for the method work, some backgrounds are needed, based on conversations and readings about test automation and my experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Company
&lt;/h2&gt;

&lt;p&gt;The most successful cases cited in the conversations, the company (or at least some managements positions) take the struggle to run agility regardless of the framework (whether Scrum, Kanban or other). In these cases, if the team fail, they were encouraged to try again, and not punished for mistakes.&lt;/p&gt;

&lt;p&gt;This struggle also goes to the stakeholder that wants to “waterfall” the process. If your company complies with stakeholder’s decisions on how the team should work, to not lose the sale, the chances of failure are high.&lt;/p&gt;

&lt;h2&gt;
  
  
  Team
&lt;/h2&gt;

&lt;p&gt;We will consider here team as a group of people working to hit a common goal that adds value to the product, all together.&lt;/p&gt;

&lt;p&gt;The team must share information, ideas, concerns, success and failure, working as a single entity.&lt;/p&gt;

&lt;p&gt;A team differs from a work group the way people behave. In a work group, each one does their own job without thinking about how it can affect the others. Has the Sprint failed? “I deliver my work on time, I have nothing to do with it.” Or worse: “who did not get the job done was that person there,” pointing the finger.&lt;/p&gt;

&lt;p&gt;I’ll put one more category, the “team-ish”. The team-ish knows how to work in group, but only do what is written to do. They may even think of improvements, but if the goal was achieved, why do more?&lt;/p&gt;

&lt;p&gt;If you’re in a work group, you’ll hardly be able to automate during Sprint. In other cases, the likelihood is high. And if you’re in a team-ish, why not try to make it a team? Tell your ideas of integration in the retrospective or call the team to chat after a daily, since you will be together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Imagination
&lt;/h2&gt;

&lt;p&gt;To automate a feature that does not exist takes a little imagination. If you already have the drawing of the screens becomes easier, but if you haven't, imagine the flow. Your code, at first place, will automate features like filling a field or the click of a button regardless of its position on the screen, color or shape.&lt;/p&gt;

&lt;p&gt;“But I don't know IDs !!!”, you say. Two solutions I use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Leave the field blank or with some indication to complete later, or&lt;/li&gt;
&lt;li&gt;Create a variable that allows key-value construction (hash, hashmap, or dict, for example). Fill in the field with variable_name [key]. Then just complete the second member of the equality with the values ​​that you are discovering.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using this method I have already completed my code along with Dev! So, just map the IDs and make small adjustments that the functionality was already automated.&lt;/p&gt;

&lt;h2&gt;
  
  
  My flow
&lt;/h2&gt;

&lt;p&gt;It all starts at the planning meeting, where we decide the sprint backlog. Let’s assume that the purpose of the sprint is to perform the login (always login as example …).&lt;/p&gt;

&lt;p&gt;Write down all the possible scenarios for a login. Before starting to automate all, define which will be unit / instrumented, which will be services / APIs, and which will be the front.&lt;/p&gt;

&lt;p&gt;Divide the responsibilities and automate first all the “happy paths”, those in which everything will be done perfectly. There is no point in a feature that does not perform its function if the user does everything right.&lt;/p&gt;

&lt;p&gt;Going back, write all the possible login scenarios successfully, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="c"&gt;#login.feature&lt;/span&gt;

&lt;span class="kd"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Successfull login

&lt;span class="kn"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="nf"&gt;Given &lt;/span&gt;I am on the login screen

&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Successful login using username
   &lt;span class="nf"&gt;When &lt;/span&gt;I log in using &lt;span class="s"&gt;"username"&lt;/span&gt;
   &lt;span class="nf"&gt;Then &lt;/span&gt;I should be directed to the main page

&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Successful login using email
   &lt;span class="nf"&gt;When &lt;/span&gt;I log in using &lt;span class="s"&gt;"email"&lt;/span&gt;
   &lt;span class="nf"&gt;Then &lt;/span&gt;I should be directed to the main page

&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Successful login using ID
   &lt;span class="nf"&gt;When &lt;/span&gt;I log in using &lt;span class="s"&gt;"ID"&lt;/span&gt;
   &lt;span class="nf"&gt;Then &lt;/span&gt;I should be directed to the main page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write down all that your system will support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement the scenarios
&lt;/h2&gt;

&lt;p&gt;Here comes the imagination. Scenarios will be implemented only with login screen drawing.&lt;/p&gt;

&lt;p&gt;My steps file, without the implementation, looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="c"&gt;#login.steps.rb&lt;/span&gt;

&lt;span class="nf"&gt;Given &lt;/span&gt;("I am on the login screen") do
   &lt;span class="err"&gt;pending&lt;/span&gt; &lt;span class="c"&gt;# write code here that turns the phrase above into concrete actions&lt;/span&gt;
&lt;span class="err"&gt;end&lt;/span&gt;

&lt;span class="nf"&gt;When &lt;/span&gt;("I log in using {string}") do | string |
   &lt;span class="err"&gt;pending&lt;/span&gt; &lt;span class="c"&gt;# write code here that turns the phrase above into concrete actions&lt;/span&gt;
&lt;span class="err"&gt;end&lt;/span&gt;

&lt;span class="nf"&gt;Then &lt;/span&gt;("I should be directed to the main page") do
   &lt;span class="err"&gt;pending&lt;/span&gt; &lt;span class="c"&gt;# write code here that turns the phrase above into concrete actions&lt;/span&gt;
&lt;span class="err"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that even though my feature file has several scenarios, there is only three steps to implement. When writing anything in your code it is very important think about reuse. After implementing “with my imagination”, the steps will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="c"&gt;#login.steps.rb&lt;/span&gt;

&lt;span class="nf"&gt;Given &lt;/span&gt;("I am on the login screen") do
  &lt;span class="nt"&gt;@login_page&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;LoginPage.new&lt;/span&gt;
  &lt;span class="nt"&gt;@login_page.load&lt;/span&gt;
&lt;span class="err"&gt;end&lt;/span&gt;

&lt;span class="nf"&gt;When &lt;/span&gt;("I log in using {string}") do | user |
  &lt;span class="nt"&gt;@login_page.user_field.set&lt;/span&gt; &lt;span class="err"&gt;USER[user]&lt;/span&gt;
  &lt;span class="nt"&gt;@login_page.password_field.set&lt;/span&gt; &lt;span class="err"&gt;PASSWORD[user]&lt;/span&gt;
  &lt;span class="nt"&gt;@login_page.btn_login.click&lt;/span&gt;
&lt;span class="err"&gt;end&lt;/span&gt;

&lt;span class="nf"&gt;Then &lt;/span&gt;("I should be directed to the main page") do
  &lt;span class="err"&gt;current_page_is?(NAMES['current_page'])&lt;/span&gt;
&lt;span class="err"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the page objects, variables, and methods files, using SitePrism and Capybara:&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="c1"&gt;#login.po.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginPage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;SitePrism&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Page&lt;/span&gt;
  &lt;span class="n"&gt;set_url&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;

  &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="ss"&gt;:user_field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="ss"&gt;:password_field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="ss"&gt;:btn_login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#methods.rb&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;current_page_is?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_title?&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#variables.rb&lt;/span&gt;

&lt;span class="no"&gt;NAMES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'main_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="no"&gt;USERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'username'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'ID'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="no"&gt;PASSWORDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'username'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'ID'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just wait for the login screen be done, complete the code and the feature is already automated! Said no one ever …&lt;/p&gt;

&lt;p&gt;Even if you replace everything right, the chances that you make some mistake in the first (second, third …) run is huge. The above example serve only as a basis. Try to fix the errors as they appear in log. Even with these errors, it is easier and quicker to make adjustments than waiting for the functionality to be fully ready to write the code. Errors will decrease over time.&lt;/p&gt;

&lt;p&gt;Also, it’s not just because you’ve finished a feature that will sit and wait. In an agile team, there is always something to do. Talk with the responsible for DevOps and see how the CI / CD pipeline is going, see how is going the application development with the developers, talk about the backlog and usability. Interact with the team, give suggestions for improvements, point problems (already with solutions, if possible). You are responsible for product quality, not just automate testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't forget the exploratory manual test
&lt;/h2&gt;

&lt;p&gt;Always take a time to use your product. Only this way you will have the complete knowledge of how it is working. Don't automate only the requirements described in the stories. Many issues and even new automations will emerge as you use the application. Automated and manual tests are complementary, not exclusive.&lt;/p&gt;

&lt;p&gt;I would dare to say that today, with the great demand for automation, QAs should also “step back” a little and do manual testing.&lt;/p&gt;




&lt;p&gt;I hope you can get the general idea of ​​this text and apply in the context of your company.&lt;/p&gt;

&lt;p&gt;And don't forget to comment here how the experience is going! And if you have a question or want to share your experience, leave a comment below!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further readings:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Book &lt;a href="https://amzn.to/2wbGF55"&gt;Scrum: The Art of Doing Twice the Work in Half the Time&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Book &lt;a href="https://amzn.to/2JLLVGb"&gt;Agile Testing: A Practical Guide for Testers and Agile Teams&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Book &lt;a href="https://amzn.to/2JRY0FH"&gt;More Agile Testing: Learning Journeys for the Whole Team&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See ya!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Automation metrics: some problems</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Mon, 29 Aug 2022 04:26:40 +0000</pubDate>
      <link>https://dev.to/rodmatola/automation-metrics-some-problems-3lc6</link>
      <guid>https://dev.to/rodmatola/automation-metrics-some-problems-3lc6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“What is not measured is not managed”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This phrase is one of the most used when justifying the implementation of metrics in a project. another is&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Against data there are no arguments”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A big problem I see in these sentences is that metrics, without interpretation, are just numbers. And numbers alone have no obligation to reality.&lt;/p&gt;

&lt;p&gt;A great example to illustrate what I mean is the &lt;a href="https://www.tylervigen.com/spurious-correlations"&gt;Spurious Correlations&lt;/a&gt; website. This site comes to absurd conclusions, as the &lt;strong&gt;increase in consumption of mozzarella is correlated with Civil Engineering doctorates awarded&lt;/strong&gt;, or that &lt;strong&gt;decreasing the consumption of margarine, also decreases the number of divorces in Maine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What I want to say in this introduction is that numbers, metrics and even statistics can lead us to very wrong conclusions about our process/product.&lt;/p&gt;

&lt;p&gt;Now let's get to the main subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 3 numbers
&lt;/h2&gt;

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

&lt;p&gt;The 3 numbers are not a consolidated technique for quality metrics. The 3 numbers is a metric that, all of a sudden, a stakeholder asked all QAs to report. These 3 numbers were intended to inform managers about the evolution of test automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;number of mapped scenarios&lt;/li&gt;
&lt;li&gt;number of automated scenarios&lt;/li&gt;
&lt;li&gt;automated scenarios in the last week&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These numbers were a weekly report that we should send, as the company is "goal oriented" and each manager must achieve one.&lt;/p&gt;

&lt;p&gt;Let's now enumerate some problems I see in these numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only numbers don't mean anything
&lt;/h2&gt;

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

&lt;p&gt;Numbers are just collected data. What you look for when collecting data is &lt;strong&gt;information&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Information is the ordered and organized data so that it conveys a comprehensive message within a given context. A set of data that conveys knowledge is information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;information = data + context + interpretation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple example: I pay $2000 in rent. With this data alone, it is impossible to say whether I am paying too much or not.&lt;/p&gt;

&lt;p&gt;If I live in a studio in Osasco, a São Paulo nearby city, $2000 is an absurdly high value. If you go to a 3 bedroom apartment in Moema, it's basically for free.&lt;/p&gt;

&lt;p&gt;For QAs, especially if part of an agile team, the Sprint may have required tasks other than automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;make API mocks due to instability of the test environments or due to the difficulty of getting mass data;&lt;/li&gt;
&lt;li&gt;refactor the test code, because there were some modifications in a functionality or correcting flaky scenarios&lt;/li&gt;
&lt;li&gt;work on the continuous integration pipeline, or helping with it;&lt;/li&gt;
&lt;li&gt;it was a “manual” Sprint due to the urgency to launch a feature, to not miss the “time to market”, and automation would take more time than needed to launch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are just a few examples where the 3 numbers, without context, could lead to misinterpretations of why automation didn't progress or was slower in a Sprint.&lt;/p&gt;

&lt;h2&gt;
  
  
  It will never be 100% automated
&lt;/h2&gt;

&lt;p&gt;&lt;a href="" class="article-body-image-wrapper"&gt;&lt;img&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we talk about test scenarios, we usually mean Gherkin and BDD. I argue that, as the name is Behavior Driven Development, ALL behaviors in the software must be described, not just those that will be automated.&lt;/p&gt;

&lt;p&gt;As a result, scenarios that can only be done manually, or that the automation and maintenance effort is very high, will not be included in the statistics. An example is putting an iPhone simulator in airplane mode, to test how the application responds to lack of internet, or turning on bluetooth in an Android emulator.&lt;/p&gt;

&lt;p&gt;In addition, some scenarios, even containing automation code, will not run. For example a registration feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Enter the registration area
&lt;span class="nf"&gt;Given &lt;/span&gt;the user is on Home page
&lt;span class="nf"&gt;When &lt;/span&gt;access the registration area
&lt;span class="nf"&gt;Then &lt;/span&gt;the form should be on screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Successfully register
&lt;span class="nf"&gt;Given &lt;/span&gt;the user is on Home page
&lt;span class="nf"&gt;When &lt;/span&gt;the user make the registration
&lt;span class="nf"&gt;Then &lt;/span&gt;a success message should appear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first scenario can be discarded and the second needs to run, because in order to register it is necessary to display the form first.&lt;/p&gt;

&lt;p&gt;In this case, we will have two scenarios mapped, but the report will contain only one executed. If we extrapolate, we will only have 50% of the tests running automatically, but 100% of the scenarios covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  To achieve the goals, we will hire "automators"
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/fQZX2aoRC1Tqw/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/fQZX2aoRC1Tqw/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an agile team, having people to perform only one task is not "healthy". In this case, having QAs and "automators" can (will?) generate dysfunctions.&lt;/p&gt;

&lt;p&gt;For automators, a detachment from quality: “I'm here just to automate”. For the manual testers, a feeling “if you automate everything I could lose my job”, or “I also want to automate, why don't you teach us?”, causing demotivation.&lt;/p&gt;

&lt;p&gt;At some point, this will create cliques, decreasing interaction between people and even generating hard feelings between them. As a result, quality is no longer a priority.&lt;/p&gt;

&lt;p&gt;To put the above into context, the company, which only had manual QAs, hired an automation consultancy company to speed up the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;My objective with this article is to check if we are using only data, or if we are using information to make decisions.&lt;/p&gt;

&lt;p&gt;As we can't just consider the rental price for renting a house, we also shouldn't rely on just one or “three numbers” to measure an evolution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: managers, participate more in the development cycle. Get close to people, talk, find out what each person is doing and developing. They may have other even better numbers.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;"Tell me how you measure me and I'll tell you how I'll behave"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This sentence fits the situation very well. But that discussion is for another text!&lt;/p&gt;




&lt;p&gt;And you? Do you have a story of imposed metrics for your team? Comment here!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>automation</category>
      <category>qualityassurance</category>
      <category>metrics</category>
    </item>
    <item>
      <title>Ruby: "the best" language for general automation</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Thu, 12 May 2022 22:42:19 +0000</pubDate>
      <link>https://dev.to/rodmatola/ruby-the-best-language-for-general-automation-gh3</link>
      <guid>https://dev.to/rodmatola/ruby-the-best-language-for-general-automation-gh3</guid>
      <description>&lt;p&gt;Before you say "there is no better programming language, each one has its purpose", I know it. That's why "the best" is in quotes in the title.&lt;/p&gt;

&lt;p&gt;But in this text I want to show 3 situations in which Ruby was the best choice, even though I didn't want to use it in two. With Ruby, I did in hours what I couldn't do in days (2 to 3) in another language (Shell Script, in this case).&lt;/p&gt;

&lt;p&gt;The three situations that I will talk about here are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Continuous compliance&lt;/li&gt;
&lt;li&gt;GitHub Automations&lt;/li&gt;
&lt;li&gt;CLI Test Automation (Command Line Tools)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But before getting into these topics,&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Ruby?
&lt;/h2&gt;

&lt;p&gt;Its creator, Yukihiro “Matz” Matsumoto, combined parts of his favorite languages (Perl, Smalltalk, Eiffel, Ada, and Lisp) to form a new language that balanced functional programming with imperative programming. He said, "I wanted a scripting language that was more powerful than Perl and more object-oriented than Python." (From &lt;a href="https://www.ruby-lang.org/en/about/"&gt;https://www.ruby-lang.org/en/about/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Ruby is highly portable: it is primarily developed on GNU/Linux, but works on many types of UNIX, macOS, Windows, DOS, BeOS, OS/2, etc. It comes by default on many Linux distributions and on macOS.&lt;/p&gt;

&lt;p&gt;Ruby is not only completely free, but also free to use, copy, modify and distribute.&lt;/p&gt;

&lt;p&gt;It is considered one of the best languages for test automation and one of the pioneers in some frameworks, such as RSpec and Cucumber. But unfortunately its popularity is decreasing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where is Ruby used?
&lt;/h3&gt;

&lt;p&gt;Below, only 3 examples where Ruby is used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub&lt;/li&gt;
&lt;li&gt;homebrew&lt;/li&gt;
&lt;li&gt;cocoapods&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My experience with Ruby
&lt;/h3&gt;

&lt;p&gt;Basically my entire career as a QA was automating in Ruby. Only recently with the popularization of Cypress for web testing, I migrated to JavaScript as the main language.&lt;/p&gt;

&lt;p&gt;Now let's get to the main subject, which is where I'm using Ruby even though it wasn't my first choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous compliance
&lt;/h2&gt;

&lt;p&gt;I didn't even know it existed until I watched &lt;a href="https://testautomationu.applitools.com/inspec_compliance-testing-tutorial/"&gt;TAU's Continuous Compliance&lt;/a&gt; course. This course opened my mind to a sea of ​​possibilities for automating checks.&lt;/p&gt;

&lt;p&gt;The course uses &lt;a href="https://www.inspec.io/?azure-portal=true"&gt;Chef Inspec&lt;/a&gt;, an &lt;a href="https://github.com/inspec/inspec"&gt;open source&lt;/a&gt; Ruby DSL. I made a POC with this tool to automatically check repositories on GitHub, checks like if it contains a gitignore consistent with the language used, if node_modules is not present, etc.&lt;/p&gt;

&lt;p&gt;The problem is that Chef Inspec must be installed every time a workflow runs, in addition to having to run a specific command, the repository being in a specific folder, having to look in the documentation for the command to perform a check, which is sometimes limited …&lt;/p&gt;

&lt;p&gt;After reading the documentation and knowing the possibilities for use, I ended up abandoning the tool to use pure Ruby. If the tool made in Ruby does it, obviously pure Ruby will do it too, and much more, because there will be actions not implemented in the DSL (this is one of the reasons I'm a bit against DSLs, but that's for another text).&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Automations
&lt;/h2&gt;

&lt;p&gt;Probably everyone here has already created a repository on GitHub, but I'm sure if you don't use GitHub for work, you've never bothered to secure a branch, for example.&lt;/p&gt;

&lt;p&gt;Some settings are essential when working with GitHub, such as protecting the develop and main branches with some rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not accept direct push&lt;/li&gt;
&lt;li&gt;Merge with pull request only&lt;/li&gt;
&lt;li&gt;Require signed commits etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These settings are a little boring to make. When creating a repository, it can take some time clicking on (checking) checkboxes. This time can be reduced by &lt;a href="https://docs.github.com/en/rest/repos/repos#create-an-organization-repository"&gt;scripts for automating the creation of repositories&lt;/a&gt; through the &lt;a href="https://docs.github.com/en/rest/repos/repos"&gt;GitHub API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As I wanted these scripts to be able to run on both Linux and macOS (sorry Windows. Hi WSL), I started to develop them in Shell Script, since it is a native language of both systems.&lt;/p&gt;

&lt;p&gt;But when it came time to do some checks before an action, Shell Script became extremely complicated. And what is the other language that comes with Linux and macOS? That's right, Ruby.&lt;/p&gt;

&lt;p&gt;I used Ruby to do some checks like if the repository exists, list repositories and call existing sh files.&lt;/p&gt;

&lt;p&gt;I thought about using JavaScript, as we have more people who develop in that language on the team, but Ruby was accepted as the best choice.&lt;/p&gt;

&lt;p&gt;And to make it even more "system compatible", this is inside a VSCode devcontainer, with the Ruby Docker image, making everything configured with one click.&lt;/p&gt;

&lt;h2&gt;
  
  
  CLI Test Automation
&lt;/h2&gt;

&lt;p&gt;We were developing a command line application. I had never worked with this and had no idea how to automate CLI tests. Obviously I went to ask Google.&lt;/p&gt;

&lt;p&gt;One of the results was how to test CLI developed in Rust, just what I needed! Unfortunately, for lower-level testing, the code would need to be refactored to be testable. And I don't have the knowledge in Rust for that.&lt;/p&gt;

&lt;p&gt;Fortunately this and several other results told how to test, which is simply typing a command and checking what comes out in the terminal. So I would just do e2e for now.&lt;/p&gt;

&lt;p&gt;The tool that was most indicated was &lt;a href="https://github.com/bats-core/bats-core/"&gt;Bats&lt;/a&gt;, made in Shell Script. But I couldn't make some simple things work like assigning variables to use them within the tests. The documentation itself said that it was a little complicated to split the tests into different files. Imagine the mess that would be as the tests grew.&lt;/p&gt;

&lt;p&gt;Another tool I found was &lt;a href="https://github.com/cucumber/aruba"&gt;Aruba&lt;/a&gt;, written in Ruby, but the documentation is practically non-existent and it recommends using it with Cucumber. Even the examples inside are in a &lt;code&gt;features&lt;/code&gt; folder. I refuse to use Cucumber…&lt;/p&gt;

&lt;p&gt;Then came the same thought from Chef Inspec: if it's done in Ruby, I can do it in Ruby. And it's working beautifully with Ruby, RSpec and the Open3 module for handling terminal commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Whenever I go looking for a way to automate something, if there isn't a widely used framework like Cypress, Robot Framework, Skuli etc, and there is some mention of a framework made in Ruby, I won't even look at the others. Ruby is the choice!&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to learn Ruby?
&lt;/h2&gt;

&lt;p&gt;I learned from &lt;a href="https://www.codecademy.com/catalog/language/ruby"&gt;Codecademy&lt;/a&gt; and, of course, from Google too. I recommend Codecademy for any language. Online hands on and straight to the point! Basic courses are free.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.rubyguides.com/"&gt;RubyGuides&lt;/a&gt; also has a lot of material and helped me a lot. It also has a newsletter that you receive content about Ruby directly in your email. That's great for me!&lt;/p&gt;

&lt;p&gt;In the language &lt;a href="https://www.ruby-lang.org/en/documentation/"&gt;official documentation&lt;/a&gt;, there are other links to learn Ruby.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>automation</category>
    </item>
    <item>
      <title>Ready, Accepted, Done! Acceptance criteria and definitions of ready and done.</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Tue, 08 Mar 2022 21:55:25 +0000</pubDate>
      <link>https://dev.to/rodmatola/ready-accepted-done-acceptance-criteria-and-definitions-of-ready-and-done-2g4a</link>
      <guid>https://dev.to/rodmatola/ready-accepted-done-acceptance-criteria-and-definitions-of-ready-and-done-2g4a</guid>
      <description>&lt;p&gt;How to know if a task is ready to be started or done to be delivered? A chocolate cake for example, for it to be ready, does it need topping or not?&lt;/p&gt;

&lt;p&gt;To align expectations, there are three agreements you should make before starting to develop a product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acceptance or Acceptance Criteria (AC),&lt;/li&gt;
&lt;li&gt;Definition of Ready (DOR),&lt;/li&gt;
&lt;li&gt;Definition of Done (DOD).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this text I will talk about these three agreements using analogies outside of IT and also examples within software development.&lt;/p&gt;

&lt;p&gt;Using these three agreements within a development team is extremely important so that, when a task is delivered, you don't hear from stakeholders "but that's not how I asked you to do it", "&lt;em&gt;how is this ready if this is missing?&lt;/em&gt;", or the team "&lt;em&gt;you didn't give me what I asked for, so I couldn't finish it&lt;/em&gt;".&lt;/p&gt;

&lt;h2&gt;
  
  
  Acceptance Criteria (AC)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: I want a chocolate cake in two days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Right. With or without topping?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: With topping and filling, but I'm celiac so I need it with rice flour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Ok. What size?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: hmm... just for family. Me, another adult and two children.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: I need you to be more specific. Give me exact measurements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: I want the cake in a 20cm pudding mold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Topping with milk or dark chocolate&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: 70% dark chocolate&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Any specific brands?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: No. I just don't want with hydrogenated fat&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Anything else?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: No. That 's it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Check with me, please:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chocolate Cake&lt;/li&gt;
&lt;li&gt;Made with 20cm pudding mold&lt;/li&gt;
&lt;li&gt;70% dark chocolate, non-hydrogenated&lt;/li&gt;
&lt;li&gt;Rice flour instead of wheat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: Checked!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Let's define the payment?&lt;/p&gt;




&lt;p&gt;In this example, we define the acceptance criteria for exactly requested cake to be developed.&lt;/p&gt;

&lt;p&gt;In an IT context, this list contains the requirements for a feature to be developed as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definitions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Criteria required for a given task* to be considered completed&lt;/li&gt;
&lt;li&gt;Differ for each task&lt;/li&gt;
&lt;li&gt;Answer the questions:

&lt;ul&gt;
&lt;li&gt;Are we building the right thing?&lt;/li&gt;
&lt;li&gt;Did we build it right?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Must (need?) be written before start development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*task can be story, subtask, epic…&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;An endpoint must return the following status codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;200 success&lt;/li&gt;
&lt;li&gt;401 unauthorized&lt;/li&gt;
&lt;li&gt;404 not found&lt;/li&gt;
&lt;li&gt;408 timeout&lt;/li&gt;
&lt;li&gt;500 server error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the task cannot be given as completed if it doesn't return at least these statuses. Can it return other statuses besides these? Yes, it can, but it is not recommended to make increments without being aligned with the business party and the rest of the team. Modifications must be added/removed from the acceptance criteria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition of Ready (DOR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: To start development, I need you to transfer to my account the value of the ingredients or you can have them delivered directly here. Without the ingredients I can't start the development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: I will order now. Hmm… it says here that delivery will be in two days. Can you do it for the same day?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: I can't. I need at least one day. So the ingredients must be provided by 4 pm the day before you need the cake.&lt;/p&gt;




&lt;p&gt;In our story, the DOR for cake development is that the ingredients must be available by 4pm the day before the cake is delivered. Coming back to IT,&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition
&lt;/h3&gt;

&lt;p&gt;DOR are prerequisites for a backlog to be considered ready to start development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Do we have all the access we need?&lt;/li&gt;
&lt;li&gt;Do we have the hardware and software needed for development?&lt;/li&gt;
&lt;li&gt;Do we have written acceptance criteria?&lt;/li&gt;
&lt;li&gt;Do we have a wireframe, even hand-drawn? (for front end)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Explaining the examples:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;If the task is to configure Amazon's S3 bucket, is it worth including this task without the responsible person having the necessary access to perform it?&lt;/li&gt;
&lt;li&gt;Will you be able to start iOS development without having a Mac with XCode installed? It will be hard…&lt;/li&gt;
&lt;li&gt;Are you going to start developing without knowing what should be developed? You can, but definitely you'll have to rewrite somethings&lt;/li&gt;
&lt;li&gt;Same as item 3 for the frontend&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Definition of Done (DOD)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: Your cake is ready. You can come get it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stakeholder&lt;/strong&gt;: I thought you would deliver it here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev&lt;/strong&gt;: We forgot to define it…&lt;/p&gt;

&lt;p&gt;Although the cake is ready meeting all the acceptance criteria, can we close this task if the cake was not delivered? In this scenario, we have at least two possibilities for defining done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cake done with stakeholder going to get it&lt;/li&gt;
&lt;li&gt;cake done being delivered to a certain address&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Definition
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;DOD is the criteria required for ALL tasks to be considered completed&lt;/li&gt;
&lt;li&gt;Task done = AC + DOD&lt;/li&gt;
&lt;li&gt;It's the same for everything in a given context&lt;/li&gt;
&lt;li&gt;Context can be team, project and/or the entire company&lt;/li&gt;
&lt;li&gt;It is an agreement for all people to follow in a context&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Is it pushed (git push)?&lt;/li&gt;
&lt;li&gt;Is it on staging?&lt;/li&gt;
&lt;li&gt;Is there error treatment?&lt;/li&gt;
&lt;li&gt;Was it functionally tested?&lt;/li&gt;
&lt;li&gt;Was it security/pentested?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Explaining the examples:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Is a code that is only on your computer good for anything?&lt;/li&gt;
&lt;li&gt;If a site is not in an environment that can be validated by others outside the team, is it ready? (May be, depending on team lineup)&lt;/li&gt;
&lt;li&gt;Let's assume that a frontend consumes the API described in the acceptance criteria example, if the API returns "201 no content" or "206 partial content", how will the front behave? (I've seen infinite loadings on the web and apps crashing in cell phones)&lt;/li&gt;
&lt;li&gt;It's done, just need to test! (Really? No comments.)&lt;/li&gt;
&lt;li&gt;In this time when ransomware and data leak are happening a lot, isn't it worth having it in your DOD?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that done does not necessarily mean being in production. Done will mean different things in different teams.&lt;/p&gt;

&lt;p&gt;To think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a task/feature is not able to deliver value, is it done?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, does your team already practice these agreements? If not, shall you start?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Azure, CircleCI, GitHub, Gitlab: a POC</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Fri, 07 Jan 2022 03:01:38 +0000</pubDate>
      <link>https://dev.to/rodmatola/azure-circleci-github-gitlab-a-poc-3039</link>
      <guid>https://dev.to/rodmatola/azure-circleci-github-gitlab-a-poc-3039</guid>
      <description>&lt;p&gt;A limitation in GitHub Actions, despite being completely workable, made us question whether it would be better to change our CI tool.&lt;/p&gt;

&lt;p&gt;The tech lead was very experienced in Microsoft tools, so he suggested Azure DevOps. I also like Azure a lot, but I have* a crush on Gitlab. The team's "DevOps"** had experience with CircleCI and suggested it.&lt;/p&gt;

&lt;p&gt;In order not to have an unecessary discussion and not decide based only on documentation (we did this once and I don't know if it was the best choice, but it working very well), I offered to do a POC (Proof of Concept) with the CIs mentioned.&lt;/p&gt;

&lt;p&gt;As we were already running the website build and tests on GitHub Actions, it was just "translating" GitHub's yml to the yml of other CIs. Said no one ever…&lt;/p&gt;

&lt;p&gt;*had. I explain below&lt;/p&gt;

&lt;p&gt;**Just to give another name than developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  CircleCI
&lt;/h2&gt;

&lt;p&gt;I started with &lt;a href="https://circleci.com/" rel="noopener noreferrer"&gt;CircleCI&lt;/a&gt; because one of the things we talked about was to keep the code on GitHub. That way we wouldn't need to do migrations, although that's pretty easy.&lt;/p&gt;

&lt;p&gt;From the documentation, I was delighted with CircleCI. The "&lt;a href="https://circleci.com/orbs/" rel="noopener noreferrer"&gt;Orbs&lt;/a&gt;", which are like GitHub Actions, the possibility to choose machines with &lt;a href="https://circleci.com/docs/2.0/configuration-reference/#resourceclass" rel="noopener noreferrer"&gt;up to 128 GB of RAM&lt;/a&gt;, the possibility to choose graphics acceleration. I almost closed the deal with CircleCI here. But then came the construction of the pipeline…&lt;/p&gt;

&lt;p&gt;My experience with CircleCI is only from studies. So my pipelines in CircleCI are pretty simple.&lt;/p&gt;

&lt;p&gt;When I translated the GitHub Action to CircleCI yaml, it was the CI that took me the longest time to start. It took me a long time to understand the structure of the workflow, but that might have been a limitation of myself.&lt;/p&gt;

&lt;p&gt;One point I didn't like how were the examples in the documentation. They only show simple structures. To do what I had in mind, I had to search the internet. I wasted a lot of time.&lt;/p&gt;

&lt;p&gt;Another setback is that many of CircleCI's (all?) integrations need permission from the company, which is annoying and can delay development.&lt;/p&gt;

&lt;p&gt;But what was knockout for me on CircleCI was the difficulty of &lt;a href="https://discuss.circleci.com/t/cant-connect-to-node-http-server-running-on-localhost/19857/15" rel="noopener noreferrer"&gt;running a localhost&lt;/a&gt; on it. I searched on the internet and saw that this is really a problem. There were other solutions, but I found it very complicated for something that is straightforward in other CIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  CircleCI Pros*
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/docs/2.0/optimizations/#caching-dependencies" rel="noopener noreferrer"&gt;Caching dependencies&lt;/a&gt;: If your project uses Yarn, Bundler, or Pip, for example, the dependencies downloaded during a job can be cached for later use rather than being re-downloaded on every build. The other CIs have it as well.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/docs/2.0/docker-layer-caching/" rel="noopener noreferrer"&gt;Docker Layer Caching (paid)&lt;/a&gt;&lt;strong&gt;:&lt;/strong&gt; save Docker image layers created within your jobs rather than rebuilding the entire image every time, saving building time. Has no effect on Docker images used as build containers. Is only useful when creating your own Docker image&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/docs/2.0/configuration-reference/#resourceclass" rel="noopener noreferrer"&gt;Machines up to 128GB RAM&lt;/a&gt; (Windows), versus&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt; 7GB on GitHub&lt;/a&gt;. You can choose GPUs as well&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/docs/2.0/migrating-from-github/#actions-vs-orbs" rel="noopener noreferrer"&gt;Orbs vc Actions&lt;/a&gt;: orbs are just packaged, reusable YAML. Actions are written for execution inside a Docker container or coded as individual steps using JavaScript. So anyone can code Orbs, not just JS devs.&lt;/li&gt;
&lt;li&gt;Can run jobs locally using the&lt;a href="https://circleci.com/docs/2.0/local-cli/" rel="noopener noreferrer"&gt; CircleCI Local CLI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rerun from start or from failed job&lt;/li&gt;
&lt;li&gt;A YAML validator, on CI and locally with CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Need authorizations to connect with GitHub and to do some other tasks&lt;/li&gt;
&lt;li&gt;Need to config the virtual environment (this could be an advantage). GitHub Actions provides a&lt;a href="https://github.com/actions/virtual-environments" rel="noopener noreferrer"&gt; "ready-to-go” operational system&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://discuss.circleci.com/t/cant-connect-to-node-http-server-running-on-localhost/19857/15" rel="noopener noreferrer"&gt;Some issues running a localhost server&lt;/a&gt;. I considered it an eliminatory issue&lt;/li&gt;
&lt;li&gt;No built-in way to&lt;a href="https://support.circleci.com/hc/en-us/articles/360057590591-Ignoring-A-Failure-In-A-Step" rel="noopener noreferrer"&gt; continue after failing tests&lt;/a&gt;, but display the test failed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My opinion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;YAML a little complicated to configure.&lt;/li&gt;
&lt;li&gt;Lots of permissions to ask&lt;/li&gt;
&lt;li&gt;Doc examples too simple. Had to google to find more complex examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*The pros and cons were based in features that were useful at that time&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure DevOps
&lt;/h2&gt;

&lt;p&gt;Azure DevOps was the first CI I actually used, I mean, it was the first one that I built a pipeline from scratch (after Jenkins on a Mac Mini). This was possible because it has &lt;a href="https://docs.microsoft.com/pt-br/azure/devops/pipelines/?view=azure-devops" rel="noopener noreferrer"&gt;excellent documentation&lt;/a&gt;, with several examples.&lt;/p&gt;

&lt;p&gt;I was able to do everything I wanted on it, so it quickly became one of my favourites.&lt;/p&gt;

&lt;p&gt;A big advantage of Azure over the others (I don't remember if I needed to do this in Gitlab), is clone other repositories within the same domain into your pipeline. It was just a &lt;code&gt;git clone&lt;/code&gt; like you do on your computer. On GitHub, for example, you need a PAT (&lt;a href="https://docs.github.com/pt/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token" rel="noopener noreferrer"&gt;Personal Access Token&lt;/a&gt;) and use their &lt;a href="https://github.com/actions/checkout" rel="noopener noreferrer"&gt;action/checkout&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Azure native tool for test reporting, to me, is the prettiest of all these CIs.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4krkrpufwllqobwsk95.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4krkrpufwllqobwsk95.png" alt="Image description" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another very positive point for Azure DevOps is the &lt;a href="https://azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/" rel="noopener noreferrer"&gt;price&lt;/a&gt;. Free for teams smaller than 5 people and $6 per person for larger teams. Currently, it is necessary to ask for an authorization to use the pipeline, which can take a few days to be approved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure DevOps Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/javascript?view=azure-devops&amp;amp;tabs=code" rel="noopener noreferrer"&gt;Node JS&lt;/a&gt;: able to run &lt;code&gt;--only=dev&lt;/code&gt; or &lt;code&gt;--only=prod&lt;/code&gt; to speed up the dependencies install (don’t know in other package managers)&lt;/li&gt;
&lt;li&gt;Good documentation&lt;/li&gt;
&lt;li&gt;Easy to checkout other repositories from the same company&lt;/li&gt;
&lt;li&gt;Rerun failed jobs&lt;/li&gt;
&lt;li&gt;As GitHub, have a “whole” OS image, like &lt;code&gt;ubuntu-latest&lt;/code&gt; not just tools like &lt;code&gt;node:latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops" rel="noopener noreferrer"&gt;Allows caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pricing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/customize-pipeline?view=azure-devops" rel="noopener noreferrer"&gt;Just one YAML per pipeline&lt;/a&gt;. You can have more than one, but need to specify manually which one to run.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gitlab CI
&lt;/h2&gt;

&lt;p&gt;Gitlab has always been my favourite tool. I was enchanted with it from the first time I used it. I don't remember if at that time other tools had the same functionalities as Gitlab, but my first use and the team's choice to use Gitlab was because it already had a built-in Wiki.&lt;/p&gt;

&lt;p&gt;Other native Gitlab tools I used were &lt;a href="https://docs.gitlab.com/ee/user/project/pages/" rel="noopener noreferrer"&gt;Gitlab Pages&lt;/a&gt; and &lt;a href="https://docs.gitlab.com/runner/" rel="noopener noreferrer"&gt;Gitlab Runner&lt;/a&gt;, meaning Gitlab always had everything I needed. Also, it saves the files generated by the pipelines for quite long time, so I didn't need to add a step in yaml to save the test results somewhere else to have a test history.&lt;/p&gt;

&lt;p&gt;Not to mention that Gitlab also has excellent documentation, and since I already had experience with Azure DevOps, it was even easier to understand.&lt;/p&gt;

&lt;p&gt;The only bad thing about Gitlab, for me, is that it doesn't have the separation of jobs like other CIs. The entire log is on a single terminal. If your pipeline is big, it becomes a little confusing to find a broken test, for example.&lt;/p&gt;

&lt;p&gt;But what was a knockout for Gitlab was the site's build time. While we other CIs stayed in at most 20 seconds, in Gitlab it was a minute! And I have no idea why…&lt;/p&gt;

&lt;h3&gt;
  
  
  Gitlab CI Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.gitlab.com/ee/user/application_security/sast/index.html" rel="noopener noreferrer"&gt;Static Application Security Testing&lt;/a&gt; (SAST - Free): Analyze your source code for known security vulnerabilities.&lt;/li&gt;
&lt;li&gt;Some&lt;a href="https://docs.gitlab.com/ee/ci/unit_test_reports.html" rel="noopener noreferrer"&gt; built in tests&lt;/a&gt;, like SAST mentioned above&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.gitlab.com/ee/user/project/pages/index.html" rel="noopener noreferrer"&gt;Gitlab Pages&lt;/a&gt; (better than GitHub, to me)&lt;/li&gt;
&lt;li&gt;Good documentation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.gitlab.com/ee/ci/yaml/index.html#cache" rel="noopener noreferrer"&gt;Allow cache between pipelines and jobs&lt;/a&gt;. Specify a list of files and directories paths that are in the local working copy, e.g. &lt;code&gt;node_modules&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Only "raw images" like CircleCI&lt;/li&gt;
&lt;li&gt;Too slow to build the website&lt;/li&gt;
&lt;li&gt;No visual division between jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub Actions (GHA)
&lt;/h2&gt;

&lt;p&gt;Finally, I'm going to talk about the tool we were already using.&lt;/p&gt;

&lt;p&gt;One of the things I most liked about GHA is that it has &lt;a href="https://github.com/actions/virtual-environments" rel="noopener noreferrer"&gt;full operational systems&lt;/a&gt;, with several &lt;a href="https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md" rel="noopener noreferrer"&gt;tools already installed&lt;/a&gt;. This practically makes me program the pipeline as if I were on my own machine, with no additional configuration.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;Actions&lt;/a&gt;, most of them, are very well documented and simple to use, so there is no need to search the internet for examples, only in specific cases or if you want to see other examples of use.&lt;/p&gt;

&lt;p&gt;An advantage of GitHub over other CIs is that it allows you to have many different workflow files. This is great for organizing workflows. For example, you can have a file just to run the tests, another one just to deploy in staging, another one to deploy in production etc. Triggers are set up on each file and fired automatically if the condition is met. A disavantage is to call a workflow inside another workflow. Is not straightfoward and a little hard to do.&lt;/p&gt;

&lt;p&gt;Azure DevOps also allows you to have multiple yaml files, but you have to define only one for each pipeline. I didn't find this possibility in other CIs.&lt;/p&gt;

&lt;p&gt;Another thing that makes GitHub stand out are its &lt;a href="https://docs.github.com/en" rel="noopener noreferrer"&gt;APIs&lt;/a&gt;, &lt;a href="https://docs.github.com/en/rest" rel="noopener noreferrer"&gt;Rest&lt;/a&gt; and &lt;a href="https://docs.github.com/en/graphql" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt;, and its &lt;a href="https://docs.github.com/en/github-cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt; (Command Line Interface), which allow you to do almost everything from the command line and, consequently, automate it all!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;CircleCI was the one that took me more time to start the job. I liked the separation of jobs and workflows, but generated too many errors before the first green pipeline.&lt;/li&gt;
&lt;li&gt;Azure DevOps (together with GitHub Actions) was the most straightforward to begin&lt;/li&gt;
&lt;li&gt;Gitlab I had to do some workarounds to deal with the lag of website build, because the pipeline broke due to the delay. One disadvantage is that the job stays just in one terminal. Could be confusing to follow with large jobs. Besides, it was the slowest one to build the website.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The decision
&lt;/h2&gt;

&lt;p&gt;In the specific case of this POC, the best ones were GitHub Actions that we were already using, together with Azure DevOps. As we stopped using the process that was causing the limitation on GitHub, we continued using it.&lt;/p&gt;

&lt;p&gt;If you want to take a look at the configuration ymls, go to &lt;a href="https://github.com/rodmatola/poc-cis" rel="noopener noreferrer"&gt;my repository&lt;/a&gt;. Remember that it was just a POC and the ymls are very simple, but they can be a start point.&lt;/p&gt;

&lt;p&gt;Do you disagree with any point in this text or have other experience with one of these tools? Comment here!&lt;/p&gt;

</description>
      <category>ci</category>
      <category>pipeline</category>
      <category>testing</category>
    </item>
    <item>
      <title>Which one is the best test automation tool?</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Mon, 01 Nov 2021 18:20:50 +0000</pubDate>
      <link>https://dev.to/rodmatola/which-one-is-the-best-test-automation-tool-3cda</link>
      <guid>https://dev.to/rodmatola/which-one-is-the-best-test-automation-tool-3cda</guid>
      <description>&lt;p&gt;This post was inspired by a slightly naughty response (by the context) I received in a discussion on LinkedIn, when I said that Cypress alone is not by far the best tool for API testing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is no better tool, but the one that meets the Project's needs." (free translation)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, there is a better tool to solve your problem. And there's a better one to solve mine!&lt;/p&gt;

&lt;p&gt;Below, I will mention 3 tools that we decided to be the best for each case, and briefly explain how the decision process was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Puppeteer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: We were building a backend tool, but it needed a browser to authenticate. Yes, there was no API for this and even CLI authentication needed to login via browser to get the credentials, which were displayed on terminal.&lt;/p&gt;

&lt;p&gt;We were building a web application, and we needed to build a custom &lt;code&gt;window.fetch&lt;/code&gt; object to pass as a parameter for a third-party library that we needed to use.&lt;/p&gt;

&lt;p&gt;One week later, we still couldn't log in without using the browser. So we decided to test it from the browser anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;: The pre-conditions was to be JavaScript tool, so Cypress, Playwright, Puppeteer and Selenium were options.&lt;/p&gt;

&lt;p&gt;Selenium was the first to be discarded due to the need for a webdriver, unnecessary complexity and risk of incompatibilities just to log in and click a few buttons. Also, we will need to intercept requests, and Selenium does not do it natively.&lt;/p&gt;

&lt;p&gt;Cypress and Playwright are very complete solutions for the case. Both would fit perfect, especially Cypress, as I have a certain experience on it, but could be an overkill. So, Puppeteer left.&lt;/p&gt;

&lt;p&gt;I've never used Puppeteer before, but it's the "rawest" and lightest solution, also allows a greater flexibility. We can run it purely with Node or integrate it with any test runner we want. We chose Jest for the reason that will be explained later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best tool&lt;/strong&gt;: Puppeteer&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: QAs being the only ones responsible for test automation, because Selenium with Ruby and HTTParty was used  for web/API automations, in a separate repository, but both front and backend developed in JavaScript.&lt;/p&gt;

&lt;p&gt;We wanted more Devs-QAs integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;: Any JavaScript-based, like Cypress, Playwright, Nightwatch, WebdriverIO...&lt;/p&gt;

&lt;p&gt;Cypress was chosen as the company's new stack due to its popularity growth, which allows a greater exchange of knowledge and more easy to find answers, easy installation/configuration (one command and everything is ready to go), and for being extremely friendly to all seniority. Also, an increasing number of QAs are using Cypress, which would make it easier to hire.&lt;/p&gt;

&lt;p&gt;In addition, Cypress is an "all-in-one" tool: unit, API, component, E2E and many more built-in or via plugins functionalities.&lt;/p&gt;

&lt;p&gt;Test code together with development code, get help from (some) devs, ease of CI, ease of mocks. As Chrome browser had more than 80% of customers usage, Cypress responded perfectly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best tool&lt;/strong&gt;: Cypress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jest
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: even though Cypress was being used for front automation, we needed a tool just to do some GETs and check the response against JSON Schemas. We were building a static website and these requests were to get the content from the headless CMS.&lt;/p&gt;

&lt;p&gt;Cypress would be a heavy tool for the above work, as we wanted to run the contract tests as the first tests in the pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;: Cypress, Mocha, Axios, Supertest, Chai.http, Jest.&lt;/p&gt;

&lt;p&gt;Yes, there are plenty of other JavaScript tools to test API, but we've decided to limit the options a bit.&lt;/p&gt;

&lt;p&gt;I really wanted to use Supertest or Chai.http in conjunction (or not) with Mocha, as this is an extremely lightweight combination.&lt;/p&gt;

&lt;p&gt;The front was already using Axios to make requests to the CMS so a tool was already decided. Left to decide between Mocha and Jest.&lt;/p&gt;

&lt;p&gt;React had already been decided as the stack for the frontend development, so nothing better than using Jest. Also, another Dev was already using Jest (justifying the choice said in Puppeteer section). In order not to have each project with a different tool, let's go with Jest!&lt;/p&gt;

&lt;p&gt;And to confirm the choice, the Cypress initialization alone took longer than all the Jest contract tests...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best tool&lt;/strong&gt;: Jest (+ Axios and AJV)&lt;/p&gt;

&lt;p&gt;With these three cases, we see that there is always ONE better tool to solve your problem, even if it is not THE best tool.&lt;/p&gt;

&lt;p&gt;How do you choose your best test automation tool? Comment here!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>testingtools</category>
      <category>automation</category>
      <category>testautomation</category>
    </item>
    <item>
      <title>Cyclomatic complexity: Why QAs (and Devs) should worry about it</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Sun, 17 Oct 2021 22:43:19 +0000</pubDate>
      <link>https://dev.to/rodmatola/cyclomatic-complexity-why-qas-and-devs-should-worry-about-it-1j1j</link>
      <guid>https://dev.to/rodmatola/cyclomatic-complexity-why-qas-and-devs-should-worry-about-it-1j1j</guid>
      <description>&lt;p&gt;This text will be the first of 3 and was inspired by a LinkedIn post, where a poll was made to know wether a developer should have a college degree. 90% voted no.&lt;/p&gt;

&lt;p&gt;I agree with the results, but there are some contents you learn in college that can be useful at some point, and can make a difference in decision making. Three of these contents will be the subject of this series:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;cyclomatic complexity;&lt;/li&gt;
&lt;li&gt;asymptotic complexity;&lt;/li&gt;
&lt;li&gt;binary math (focus on float numbers).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The complexities I studied in Data Structure course, and binary math in Fundamentals of Digital Computing and Introduction to Informatics (I didn't complete my degree in Computer Science).&lt;/p&gt;

&lt;p&gt;In the texts, I'll give a straightforward and simplistic introduction to each subject, and how to use each to improve the quality of your application. At the end, I'll put links for those who want to go deeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is cyclomatic complexity?
&lt;/h2&gt;

&lt;p&gt;Cyclomatic complexity, or conditional complexity, is the number of independent paths an algorithm can follow. It was developed by Thomas J. McCabe in 1976, published in the article “A Complexity Measure”. (Was nostalgic to see an Fortran example in the article. It was my first programming language and I used it practically all the 12 years I spent at university).&lt;/p&gt;

&lt;p&gt;In practical terms, it is the amount of “ifs” and “elses” that a class, method, function or equivalent has.&lt;/p&gt;

&lt;p&gt;According to McCabe, the maximum acceptable cyclomatic complexity is 10, but searching the internet, several sources indicate the maximum between 5 and 6.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cyclomatic complexity and tests
&lt;/h2&gt;

&lt;p&gt;Cyclomatic complexity is the minimum number of tests that must be done. The greater the complexity, greater number of tests are needed, and greater the risk of bugs.&lt;/p&gt;

&lt;p&gt;On the internet there are websites that calculate the cyclomatic complexity of a piece of code. Just copy and paste. I'll leave these 2 here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://jshint.com/"&gt;JSHint&lt;/a&gt; to JavaScript&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.lizard.ws/"&gt;Lizard&lt;/a&gt; for several languages like Java, Ruby, Python and Swift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Static analysis tools such as &lt;a href="https://docs.sonarqube.org/latest/user-guide/metric-definitions/#:~:text=It%20is%20the%20Cyclomatic%20Complexity,because%20keywords%20and%20functionalities%20do"&gt;SonarQube&lt;/a&gt; or SonarLint, &lt;a href="https://eslint.org/docs/rules/complexity"&gt;ESLint&lt;/a&gt;, &lt;a href="https://docs.rubocop.org/rubocop/cops_metrics.html"&gt;Rubocop&lt;/a&gt; also do this but you need to setup them in the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  In practice
&lt;/h2&gt;

&lt;p&gt;On a team I belong, cyclomatic complexity was used as a reference for Planning Poker scores, because unit tests was required and the devs knew that the greater the complexity, the more tests they had to do, in addition to development.&lt;/p&gt;

&lt;p&gt;On another team, I used it as an argument for not implementing a feature. The functionality was if the person passed the number in the address search bar, the app would take that number and automatically fill in the number in field. Otherwise, the field would be empty for manual filling.&lt;/p&gt;

&lt;p&gt;When I said that this would increase complexity, I had to explain that it wasn't the complexity of development (be harder to implement) but of testing, and that would increase the risk of bugs. I explained two or three scenarios in which there could be an error and the PO agreed not to put it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Another point to worry about is performance. One developer I worked with always put the failure API return case in the first &lt;code&gt;if&lt;/code&gt;, even if it happened only a few times. I always thought about how it will affect performance, even it's minimal. A time to send the request, more time to respond, more time to compare, more time to render… the person has already given up.&lt;/p&gt;

&lt;p&gt;Searching the internet, I saw that this was a “good practice” for JavaScript, but only in some cases and just to make the code more readable. Unfortunately I didn't find anything that spoke of the performance. Not in JavaScript.&lt;/p&gt;

&lt;p&gt;So, I found &lt;a href="https://www.c-sharpcorner.com/article/performance-consideration-for-c-sharp-conditional-statements/"&gt;Performance Consideration For C# Conditional Statements&lt;/a&gt;, as the title says, is for C#. In this article, Atul Sharma do some experiments with &lt;code&gt;ifs&lt;/code&gt;, &lt;code&gt;if-else&lt;/code&gt;, &lt;code&gt;switch-case&lt;/code&gt;, with match cases in the first and last statement. The experiment shows that the decision can be more than 6 times slower if &lt;code&gt;true&lt;/code&gt; only comes in the last if-else. Do the experiment in your language too!&lt;/p&gt;

&lt;h2&gt;
  
  
  Good practices
&lt;/h2&gt;

&lt;p&gt;I found several articles that teach how to substitute if-else and switch-case. I'll leave 3 here below, for Java, Ruby and JavaScript respectively.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/5-ways-to-replace-if-else-statements-857c0ff19357"&gt;https://medium.com/swlh/5-ways-to-replace-if-else-statements-857c0ff19357&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@qaschool/use-hashes-em-vez-de-case-statement-2316437470ea"&gt;https://medium.com/@qaschool/use-hashes-em-vez-de-case-statement-2316437470ea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/better-programming/why-you-should-use-enumerations-in-javascript-3cbb0d03b8de"&gt;https://medium.com/better-programming/why-you-should-use-enumerations-in-javascript-3cbb0d03b8de&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are QA, take a look at the code of the application you are testing. Suggest changes.&lt;/p&gt;

&lt;p&gt;If you are a Dev, try to implement best practices in your code. Use Linters and static analysis tools. And read the &lt;a href="https://amzn.to/3mX2Q9w"&gt;Clean Code&lt;/a&gt; book.&lt;/p&gt;

&lt;h2&gt;
  
  
  To know more
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;https://en.wikipedia.org/wiki/Cyclomatic_complexity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://literateprogramming.com/mccabe.pdf"&gt;http://literateprogramming.com/mccabe.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.c-sharpcorner.com/article/performance-consideration-for-c-sharp-conditional-statements/"&gt;https://www.c-sharpcorner.com/article/performance-consideration-for-c-sharp-conditional-statements/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Appendix: Real production code with complexity 12
&lt;/h2&gt;

&lt;p&gt;And another 50 warnings, measured in &lt;a href="https://jshint.com/"&gt;JSHint&lt;/a&gt;. Some words were removed and/or modified to not identify the product and translated to English.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;checkNavigation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new_services&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;typePos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasTicket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You don't have any open invoice!&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alertOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You don't have any open invoice!&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;propsNavigate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navigateTo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;propsNavigate--&amp;gt; 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propsNavigate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navigateTo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propsNavigate&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;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alertOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;openAlert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasTicket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;propsNavigate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navigateTo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;propsNavigate--&amp;gt; 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propsNavigate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navigateTo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propsNavigate&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;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;extractPreReducer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&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;Alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You don't have any open debts!&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="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Close&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="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Further informations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;onPress&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;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HowWorkScreen&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="p"&gt;},&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;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navigateTo&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;



</description>
      <category>testing</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Do you know testing? Maybe it’s not enough...</title>
      <dc:creator>Rodrigo Matola</dc:creator>
      <pubDate>Fri, 09 Apr 2021 16:15:42 +0000</pubDate>
      <link>https://dev.to/rodmatola/do-you-know-testing-maybe-it-s-not-enough-3jja</link>
      <guid>https://dev.to/rodmatola/do-you-know-testing-maybe-it-s-not-enough-3jja</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally written at my &lt;a href="https://www.linkedin.com/pulse/do-you-know-testing-maybe-its-enough-rodrigo-matola/"&gt;LinkedIn&lt;/a&gt; on September 6, 2016. I had just finished my first job with software testing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was thinking of writing this article when I read this other here &lt;a href="https://www.linkedin.com/pulse/20140627110120-3037808-do-software-testers-need-to-learn-coding"&gt;Do software testers need to learn coding?&lt;/a&gt;. They complement each other.&lt;/p&gt;

&lt;p&gt;I hear sometimes at work: this is not my problem, I don’t need to know that, it’s not my task and I don’t care. Yes, you will not meddle in the task / work of others, but a project where several areas are involved, we have to get a sense of the role and what makes each project area. This sense needs to be deeper if these areas work directly with each other.&lt;/p&gt;

&lt;p&gt;In my case for example, we test the results software. Keeping simple, there are two different companies, one for getting and one for dissemination of results. So I have to deal with two different ways of working (very different).&lt;/p&gt;

&lt;p&gt;At the beginning I was told to just do my job (manual testing). Anything needed to be made in the system, was necessary to call someone or open a ticket. This sometimes caused a break in testing, because we depended on others to continue.&lt;/p&gt;

&lt;p&gt;Over time, I learned the processes and procedures that helped me to improve my testing and save time. Many defects opened to a system was in fact from another, which have the previous processing. Unfortunately this was not taught and had to run back on its own, on trial and error, asking people who knew more (or should), sometimes with vague answers.&lt;/p&gt;

&lt;p&gt;Black box testing is sometimes taken very seriously. You test only what you see, no idea what's behind. By analogy, if your computer crashes is not better you understand how your work tool works? You do not need to know how to fix, but this knowledge will help you to argue with the technician who may want to fool you or make a kludge.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anybody know anything about internal combustion engines? Of couse! Anybody know how to fix an internal combustion engine? No... (The Big Bang Theory)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are not only in the testing department, or development, or software sales. We are in the software delivery business, and to deliver the  best quality software, different areas and companies should work integrated as a single team.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Teamwork is not when everyone works together, but when we trust each other." (Unknown)&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>testing</category>
      <category>softskills</category>
    </item>
  </channel>
</rss>
