<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Paulo Gonçalves</title>
    <description>The latest articles on Forem by Paulo Gonçalves (@paulogoncalvesr).</description>
    <link>https://forem.com/paulogoncalvesr</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%2F273916%2F1b98490c-57f6-4ae1-8c21-00db31529bdd.jpeg</url>
      <title>Forem: Paulo Gonçalves</title>
      <link>https://forem.com/paulogoncalvesr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/paulogoncalvesr"/>
    <language>en</language>
    <item>
      <title>Teste de mutação 👽: O que é e como fica a cobertura de código?</title>
      <dc:creator>Paulo Gonçalves</dc:creator>
      <pubDate>Wed, 19 Aug 2020 03:53:36 +0000</pubDate>
      <link>https://forem.com/paulogoncalvesr/testes-de-mutacao-1c7p</link>
      <guid>https://forem.com/paulogoncalvesr/testes-de-mutacao-1c7p</guid>
      <description>&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Who tests the tests?&lt;/li&gt;
&lt;li&gt;Porque cobertura de código não é confiável&lt;/li&gt;
&lt;li&gt;
Testes de mutação

&lt;ul&gt;
&lt;li&gt;Detalhe da execução&lt;/li&gt;
&lt;li&gt;RIP Cobertura de código?&lt;/li&gt;
&lt;li&gt;Desvantagem&lt;/li&gt;
&lt;li&gt;Adoção em grandes projetos - Case Google&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Verificando na prática

&lt;ul&gt;
&lt;li&gt;Cobertura de código&lt;/li&gt;
&lt;li&gt;Teste de mutação&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Fontes&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Esse conteúdo foi apresentado com mais detalhes e profundidade na live do AT Talks em 25/11/20. &lt;a href="https://www.youtube.com/watch?v=TIiVYhoEB8o" rel="noopener noreferrer"&gt;Para assistir clique aqui.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Who tests the tests?&lt;/h2&gt;

&lt;p&gt;Quando pensamos em validar a eficiência dos testes implementados, normalmente o que vem à mente é a métrica de cobertura de código. Porém, será que ela realmente é a melhor prática para garantir que os testes estão realmente testando os cenários possíveis?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cobertura de código é uma métrica que valida o quanto do código foi coberto pelos testes.&lt;br&gt;
Ou seja, verifica quais linhas do código foram executadas ao rodar os testes e retorna o percentual de cobertura.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Leia esse &lt;a href="https://en.wikipedia.org/wiki/Code_coverage" rel="noopener noreferrer"&gt;conteúdo (en)&lt;/a&gt; e &lt;a href="https://medium.com/liferay-engineering-brazil/um-pouco-sobre-cobertura-de-c%C3%B3digo-e-cobertura-de-testes-4fd062e91007" rel="noopener noreferrer"&gt;esse (pt-br)&lt;/a&gt; para saber mais.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Utilizando apenas a métrica de quantidade de cobertura de código não conseguimos garantir que todos os cenários foram cobertos, apenas... quais linhas foram executadas 😮.&lt;/p&gt;

&lt;p&gt;Pense um pouco sobre isso. Alguma vez já viu um teste sem asserção apenas para aumentar a cobertura de código? Tenho certeza que já soube de uma situação parecida.&lt;/p&gt;

&lt;p&gt;Claro que nessa situação, para evitarmos engraçadinhos, basta colocarmos alguma biblioteca que valida que todos os testes possuem asserção e que o percentual de cobertura de código está acima de algum número mágico, como 80%.&lt;/p&gt;

&lt;p&gt;O problema é que, como dito, a cobertura de código não valida a eficiência dos testes, e vamos ver abaixo o porquê.&lt;/p&gt;




&lt;h2&gt;Porque cobertura de código não é confiável&lt;/h2&gt;

&lt;p&gt;Abaixo temos um pequeno método que possui apenas 1 teste validando o seu comportamento.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
É perceptível que esse método possui mais de 1 cenário, porém precisamos de exemplo prático e simples para comparar &lt;em&gt;cobertura de código&lt;/em&gt; e &lt;em&gt;teste de mutação&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./src/cnh.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;podeTirarCarteiraDeMotorista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ./__tests__/cnh.spec.js&lt;/span&gt;
&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Deve retornar false para pessoa com menos de 18 anos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;podeTirarCarteiraDeMotorista&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se verificarmos a cobertura de código do arquivo &lt;code&gt;cnh.js&lt;/code&gt;, será apresentado que ele foi 100% coberto (aqui o gestor comemora), porém sabemos, por ser um teste simples, que a validação não está eficiente e que poderíamos validar outros cenários, como:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deve retornar &lt;code&gt;true&lt;/code&gt; se idade for igual a &lt;code&gt;18&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Deve retornar &lt;code&gt;true&lt;/code&gt; se idade for igual a &lt;code&gt;19&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Cobertura de código de &lt;code&gt;cnh.js&lt;/code&gt;:
&lt;/h4&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%2Fbaqoghc0i0xpwd5jbdr2.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%2Fbaqoghc0i0xpwd5jbdr2.png" alt="Print da cobertura de código mostrando score de 100%" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E é baseado nessa brecha da métrica de linhas executadas é que o uso do teste de mutação faz sentido.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"...100% code coverage score only means that all lines were exercised at least once, but it says nothing about tests accuracy or use-cases completeness, and that’s why mutation testing matters"&lt;br&gt;
&lt;em&gt;Baeldung, 2018&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;Testes de mutação&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagine um sanduíche coberto com uma pasta. Cobertura de código vai te dizer que o pão está 80% coberto com pasta. O teste de mutação, por outro lado, vai dizer que a pasta é &lt;em&gt;chocolate&lt;/em&gt; e não... bem... qualquer outra coisa.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O conceito de teste de mutação é bem simples:&lt;/p&gt;

&lt;p&gt;Bugs, ou &lt;strong&gt;mutantes&lt;/strong&gt;, são inseridos no código e os testes são executados em cima do código mutado. Se pelo menos 1 dos testes quebrar ou tiver timeout, o mutante é considerado morto 💀 e aquele trecho de código alterado é considerado como coberto pelos testes.&lt;/p&gt;

&lt;p&gt;Ainda não está claro? Então vamos lá.&lt;/p&gt;

&lt;p&gt;Abaixo está o nosso código original:&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="c1"&gt;// ./src/cnh.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;podeTirarCarteiraDeMotorista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O teste de mutação irá detectar todos os pontos que podem ser alterados no código e atuar em cima deles. No nosso exemplo serão feitas as seguintes alterações (serão 5 mutantes no total):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A expressão condicional &lt;code&gt;idade &amp;gt;= 18&lt;/code&gt; será alterada para &lt;code&gt;true&lt;/code&gt; e &lt;code&gt;false&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;O operador de idade &lt;code&gt;&amp;gt;=&lt;/code&gt; será alterado para &lt;code&gt;&amp;lt;&lt;/code&gt; e &lt;code&gt;&amp;gt;&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;O bloco &lt;code&gt;=&amp;gt; { return idade &amp;gt;= 18 }&lt;/code&gt; será alterado para &lt;code&gt;=&amp;gt; {}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Quer entender tudo que será mutado no seu código e para o que será mutado? Leia '&lt;a href="https://github.com/stryker-mutator/stryker-handbook/blob/master/mutator-types.md" rel="noopener noreferrer"&gt;Mutantes suportados pelo stryker (en)&lt;/a&gt;'.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A cada alteração feita, todos os testes criados são executados. Se algum teste quebrar, significa que aquela alteração (&lt;strong&gt;mutação&lt;/strong&gt;) está coberta, então ela foi assassinada.&lt;/p&gt;

&lt;p&gt;É um pouco confuso a questão de que para que aquela mutação seja considerada como morta (sucesso) é preciso que algum teste quebre (afinal, teste quebrar é ruim). Porém temos que entender que o nosso teste foi feito para o cenário ABC e se o cenário foi alterado para ABZ, o nosso teste tem que detectar essa mudança e falhar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O teste de mutação é nada mais e nada menos do que automatizar todo o processo de "sabotar o código e executar testes para ver se eles falham"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se executarmos teste de mutação utilizando o teste e código apresentados anteriormente, o resultado seria esse:&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%2Fcy98als3huajzzejao14.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%2Fcy98als3huajzzejao14.png" alt="Print do teste de mutação mostrando score de 60%, 5 mutações criadas e sendo que 2 delas não foram detectadas pelos testes" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tínhamos 100% de cobertura de código, porém o teste de mutação revelou que 2 mutações criadas não resultaram em quebra do nosso teste (sobreviventes), demonstrando que há brecha no nosso teste.&lt;/p&gt;

&lt;p&gt;Para que todos os 5 mutantes não sobrevivam, precisamos criar um novo teste que cubra essa brecha, como:&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="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Deve retornar true para pessoa maior de 18 anos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;podeTirarCarteiraDeMotorista&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;Detalhe da execução&lt;/h3&gt;

&lt;p&gt;Quando executamos o teste de mutação são feitas as seguintes etapas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analisa quais arquivos serão mutados;

&lt;ul&gt;
&lt;li&gt;No nosso caso foi &lt;code&gt;cnh.js&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Executa todos os testes e espera que todos passem;

&lt;ul&gt;
&lt;li&gt;O teste é abortado se algum teste falhar. Para validar se algum teste quebrou com mutação é imprescindível que todos os testes sejam executados com sucesso com o código original.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Gera mutante para todos os trechos de código;

&lt;ul&gt;
&lt;li&gt;No nosso caso foram 5 mutantes criados.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Executa todos os testes para cada mutante gerado;&lt;/li&gt;
&lt;li&gt;A pontuação final do teste é de acordo com a quantidade de mutantes que foram mortos ou resultaram em timeout em comparação com a quantidade total de mutantes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;RIP Cobertura de código?&lt;/h3&gt;

&lt;p&gt;Embora teste de mutação seja uma métrica muito interessante para entendermos a saúde dos testes criados, é importante salientar que ele &lt;strong&gt;NÃO&lt;/strong&gt; substitui a cobertura de código, atuando apenas como complemento e possui algumas desvantagens que impedem fortemente a sua adoção em larga escala.&lt;/p&gt;

&lt;p&gt;Portanto, cobertura de código continuará sendo uma métrica bastante usada e não é uma ferramenta antagonista ao teste de mutação&lt;/p&gt;

&lt;h3&gt;Desvantagem&lt;/h3&gt;

&lt;p&gt;Como o teste de mutação analisa todos os possíveis pontos que podem ser mutados no código e executa todos os testes para cada mutação, ele possui uma execução que onera bastante a máquina e possui um alto tempo de execução.&lt;/p&gt;

&lt;p&gt;Devido à necessidade de ter um alto poder computacional, o uso do teste de mutação chega a ser proibitivo em projetos médios e grandes.&lt;/p&gt;

&lt;p&gt;Um exemplo dessa limitação é o projeto &lt;a href="https://github.com/PauloGoncalvesBH/serverest" rel="noopener noreferrer"&gt;ServeRest&lt;/a&gt;. Todos os 86 testes existentes são executados em aproximadamente 550 milissegundos, enquanto os testes de mutação atuam em cima de 22 arquivos, resultando em 599 mutantes e com execução média de 19 minutos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No nosso código de exemplo a cobertura de código é executada em 9 ms enquanto o teste de mutação é executado em 3 segundos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Adoção em grandes projetos - Case Google&lt;/h4&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A seção &lt;em&gt;Adoção em grandes projetos - Case Google&lt;/em&gt; será atualizado com os detalhes das estratégias de testes de mutação em breve. Esses detalhes foram apresentados na &lt;a href="https://www.youtube.com/watch?v=TIiVYhoEB8o" rel="noopener noreferrer"&gt;live do AT Talks&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;Essa limitação de poder computacional não impediu a adoção do teste de mutação pela Google nos seus códigos (&lt;a href="https://dl.acm.org/doi/pdf/10.1145/2854146" rel="noopener noreferrer"&gt;que possuía 2 bilhões de linhas em 2018&lt;/a&gt;), porém ela teve que utilizar de algumas estratégias de criação da mutação.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Traditional mutation analysis is computationally prohibitive which hinders its adoption as an industry standard. In order to alleviate the computational issues, we present a diff-based probabilistic approach to mutation analysis that drastically reduces the number of mutants by omitting lines of code without statement coverage and lines that are determined to be uninteresting - we dub these arid lines.&lt;br&gt;
&lt;em&gt;State of Mutation Testing at Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No bom português:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A análise de mutação tradicional é computacionalmente proibitiva, o que impede sua adoção como um padrão da indústria. A fim de aliviar os problemas computacionais, apresentamos uma abordagem probabilística baseada em diff para análise de mutação que reduz drasticamente o número de mutantes, omitindo linhas de código sem cobertura de instrução e linhas que são determinadas como desinteressantes - dublamos essas linhas áridas.&lt;br&gt;
&lt;em&gt;Estado do teste de mutação na Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para entender a fundo a estratégia adotada por essa companhia, leia a publicação de pesquisa sobre o &lt;a href="https://research.google/pubs/pub46584/" rel="noopener noreferrer"&gt;estado do teste de mutação na Google&lt;/a&gt;, feita para a ocasião da &lt;em&gt;40ª Conferência Internacional de Engenharia de Software&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;Verificando na prática&lt;/h2&gt;

&lt;p&gt;Para executar a cobertura de código e teste de mutação citados nesse texto, primeiramente clone &lt;a href="https://github.com/PauloGoncalvesBH/teste-de-mutacao" rel="noopener noreferrer"&gt;esse repositório&lt;/a&gt;, executando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/PauloGoncalvesBH/teste-de-mutacao.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instale as dependências com o comando &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Testes&lt;/h3&gt;

&lt;p&gt;O teste foi implementado utilizando &lt;a href="https://www.npmjs.com/package/jest" rel="noopener noreferrer"&gt;jest&lt;/a&gt;. Para rodar os testes execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;Cobertura de código&lt;/h3&gt;

&lt;p&gt;Para rodar a cobertura de código, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;:coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;Teste de mutação&lt;/h3&gt;

&lt;p&gt;O teste de mutação é executado com a biblioteca &lt;a href="https://www.npmjs.com/package/@stryker-mutator/core" rel="noopener noreferrer"&gt;stryker&lt;/a&gt; e com o runner do &lt;a href="https://www.npmjs.com/package/@stryker-mutator/jest-runner" rel="noopener noreferrer"&gt;stryker para jest&lt;/a&gt;. Para rodar o teste de mutação execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;:mutation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Desafio
&lt;/h4&gt;

&lt;p&gt;O que acha de aumentar o score do teste de mutação de &lt;em&gt;60%&lt;/em&gt; para &lt;em&gt;100%&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Crie novo teste no arquivo &lt;a href="///__tests__/cnh.spec.js"&gt;cnh.spec.js&lt;/a&gt; que mate 👿 as 2 mutações que estão sobrevivendo e mantenha a cobertura de código em &lt;em&gt;100%&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;Fontes&lt;/h2&gt;

&lt;p&gt;Os seguintes materiais forneceram conteúdo e base para a criação desse texto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://research.google/pubs/pub46584/" rel="noopener noreferrer"&gt;State of Mutation Testing at Google&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Mutation_testing" rel="noopener noreferrer"&gt;Mutation Testing - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://speakerdeck.com/pedrorijo91/mutation-testing-pixels-camp-2019" rel="noopener noreferrer"&gt;Apresentação 'An intro to mutation testing - or why coverage sucks'&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/stryker-mutator/stryker-handbook/blob/master/mutator-types.md" rel="noopener noreferrer"&gt;Mutantes suportados pelo Stryker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/carlosschults/mutation-testing-what-it-is-and-how-it-makes-code-coverage-matter-ijp"&gt;Mutation Testing: What It Is and How It Makes Code Coverage Matter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/johnpreese/code-coverage-is-useless-1h3h"&gt;Code coverage is useless&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/conectionist/why-code-coverage-is-not-a-reliable-metric-327l"&gt;Why code coverage is not a reliable metric&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/schreiber_chris/mutation-testing-in-1000-characters-193a"&gt;Mutation testing in 1000 characters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dl.acm.org/doi/pdf/10.1145/2854146" rel="noopener noreferrer"&gt;Why Google Stores Billions of Lines of Code in a Single Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h5&gt;
  
  
  &lt;em&gt;Esse post está sendo versionado e hospedado no &lt;a href="https://github.com/PauloGoncalvesBH/teste-de-mutacao" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>testes</category>
      <category>ptbr</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Pare de usar git push --force</title>
      <dc:creator>Paulo Gonçalves</dc:creator>
      <pubDate>Wed, 12 Aug 2020 20:01:05 +0000</pubDate>
      <link>https://forem.com/paulogoncalvesr/pare-de-usar-git-push-force-4ngd</link>
      <guid>https://forem.com/paulogoncalvesr/pare-de-usar-git-push-force-4ngd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/PauloGoncalvesBH/treinamento-git" rel="noopener noreferrer"&gt;Esse conteúdo é abordado no meu treinamento de conceitos de git&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reescrevendo a história da branch com segurança
&lt;/h2&gt;

&lt;p&gt;Ao reescrever a história da nossa branch, com &lt;code&gt;git rebase&lt;/code&gt;, por exemplo, costumamos utilizar o &lt;code&gt;git push --force&lt;/code&gt;. Essa opção força o envio das alterações e substitui todas as alterações remotas pela versão local.&lt;/p&gt;

&lt;p&gt;O grande perigo é que, se outra pessoa tiver enviado uma alteração no repositório remoto e que não estava na sua versão local, esse trabalho será totalmente perdido.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;git push --force-with-lease&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Para evitar essa situação (e muita dor de cabeça), adote o uso de &lt;code&gt;git push --force-with-lease&lt;/code&gt; em detrimento de &lt;code&gt;git push --force&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Esta opção permite forçar o push sem o risco de sobrescrever acidentalmente o trabalho de outra pessoa.&lt;/p&gt;

&lt;p&gt;Ele atualizará a branch remota APENAS se o histórico dela for igual ao histórico que você alterou localmente, caso contrário o &lt;code&gt;push&lt;/code&gt; será rejeitado. Nesse caso, você terá que levar a alteração remota da outra pessoa para a sua branch local antes de tentar fazer o &lt;code&gt;git push --force-with-lease&lt;/code&gt; novamente.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo de &lt;code&gt;push&lt;/code&gt; rejeitado com o alerta de &lt;code&gt;stale info&lt;/code&gt; (informação velha):&lt;/em&gt;&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%2F7kyc53kz8cnj2w8hoai5.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%2F7kyc53kz8cnj2w8hoai5.png" alt="O que acontece com push --force-with-lease" width="721" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto 😃 agora você pode garantir que não irá apagar acidentalmente alteração que alguém possa ter dado &lt;code&gt;push&lt;/code&gt; enquanto você reescreveu o histórico!&lt;/p&gt;

&lt;p&gt;Para aprofundar no tema recomendo a própria &lt;a href="https://git-scm.com/docs/git-push" rel="noopener noreferrer"&gt;documentação do git sobre &lt;em&gt;git-push&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't rewrite public history unless you're really sure about what you're doing. And if you do, be safe and force-with-lease.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h6&gt;
  
  
  &lt;em&gt;Esse post está sendo versionado e hospedado no &lt;a href="https://github.com/PauloGoncalvesBH/Pare-de-usar-git-push--force" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/em&gt;
&lt;/h6&gt;

</description>
      <category>ptbr</category>
      <category>git</category>
    </item>
    <item>
      <title>Aprenda conceitos de git, não comandos</title>
      <dc:creator>Paulo Gonçalves</dc:creator>
      <pubDate>Tue, 14 Jul 2020 23:34:46 +0000</pubDate>
      <link>https://forem.com/paulogoncalvesr/aprenda-conceitos-de-git-nao-comandos-4il3</link>
      <guid>https://forem.com/paulogoncalvesr/aprenda-conceitos-de-git-nao-comandos-4il3</guid>
      <description>&lt;p&gt;Liquid syntax error: Unknown tag 'endraw'&lt;/p&gt;
</description>
      <category>git</category>
    </item>
    <item>
      <title>Entrega contínua no ServeRest 🚀</title>
      <dc:creator>Paulo Gonçalves</dc:creator>
      <pubDate>Mon, 08 Jun 2020 01:46:00 +0000</pubDate>
      <link>https://forem.com/paulogoncalvesr/entrega-continua-no-serverest-hg3</link>
      <guid>https://forem.com/paulogoncalvesr/entrega-continua-no-serverest-hg3</guid>
      <description>&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;❓ O que é entrega contínua (Continuous delivery)?&lt;/li&gt;
&lt;li&gt;❓ O que é o &lt;em&gt;ServeRest&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;🏁 Resultado&lt;/li&gt;
&lt;li&gt;🔨 Desafios&lt;/li&gt;
&lt;li&gt;📁 Libs NPM utilizadas&lt;/li&gt;
&lt;li&gt;
📑 Fluxo de trabalho

&lt;ul&gt;
&lt;li&gt;1️⃣ Issue&lt;/li&gt;
&lt;li&gt;2️⃣ Desenvolvimento local&lt;/li&gt;
&lt;li&gt;3️⃣ Pull Request&lt;/li&gt;
&lt;li&gt;4️⃣ Criação da release&lt;/li&gt;
&lt;li&gt;5️⃣ Comunicação de release gerada&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;Nesse texto vou relatar todas as etapas necessárias para a implementação da  &lt;em&gt;entrega contínua&lt;/em&gt; no &lt;em&gt;ServeRest&lt;/em&gt;, as vantagens dela e porque não é apenas inserir &lt;code&gt;npm publish&lt;/code&gt; na pipeline do projeto, mas sendo um conjunto de boas práticas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não é possível entregar código de qualidade sem um bom processo de desenvolvimento &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;⛔ O QUE NÃO IREI ABORDAR:&lt;/strong&gt; &lt;em&gt;Detalhes de implementação o suficiente para configurar a entrega contínua no seu projeto. Porém é possível utilizar as informações passadas para tal fim, já que é um agregado de informações coletadas e que deram certo.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Antes de abordarmos a entrega contínua aplicada no &lt;em&gt;ServeRest&lt;/em&gt;, temos que entender 2 coisas:&lt;/p&gt;

&lt;h5&gt;
  
  
  ❓ O que é entrega contínua (Continuous delivery)?
&lt;/h5&gt;

&lt;p&gt;A definição de entrega contínua fornecida pelo &lt;a href="http://continuousdelivery.com" rel="noopener noreferrer"&gt;http://continuousdelivery.com&lt;/a&gt; é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entrega Contínua é a capacidade de obter alterações de todos os tipos - incluindo novos recursos, alterações de configuração, correções de bugs e experimentos - em produção ou nas mãos dos usuários, com &lt;strong&gt;segurança e rapidez&lt;/strong&gt;, de maneira sustentável.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  ❓ O que é o &lt;em&gt;ServeRest&lt;/em&gt;?
&lt;/h5&gt;

&lt;p&gt;O &lt;a href="https://www.npmjs.com/package/serverest" rel="noopener noreferrer"&gt;ServeRest&lt;/a&gt; é um projeto NPM open source de ensino de testes de API para QAs. Ele fornece APIs Rest de forma fácil e bem documentada para que seja possível testar os verbos GET, POST, DELETE e PUT, autenticação e segurança de API.&lt;/p&gt;

&lt;p&gt;Sendo o &lt;em&gt;ServeRest&lt;/em&gt; um projeto com foco em qualidade, não seria menos esperado dele de que possuísse um processo de desenvolvimento de qualidade.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Resultado
&lt;/h2&gt;

&lt;p&gt;Antes de passarmos por detalhes da entrega contínua, é importante entendermos o ganho adquirido.&lt;/p&gt;

&lt;p&gt;A entrega contínua foi importante para garantir a qualidade de software do &lt;em&gt;ServeRest&lt;/em&gt; e rapidez na entrega de novas releases. Com ela apenas código bem estruturado, que passa em todos os testes e possui boa mensagem de commit é integrado ao código. Além de que as releases são geradas apenas se necessário, de acordo com alguns critérios.&lt;/p&gt;

&lt;p&gt;Para o mantenedor do projeto, basta realizar code review em PR de outros colaboradores e realizar o merge com a branch master ou beta. Não terá mais a preocupação em atualizar a master/beta local, criar tag, atualizar o changelog, commitar, executar &lt;code&gt;git push&lt;/code&gt; e &lt;code&gt;npm publish&lt;/code&gt; apontando para a tag correta (&lt;em&gt;@latest caso fosse a branch master e &lt;a class="mentioned-user" href="https://dev.to/beta"&gt;@beta&lt;/a&gt; caso fosse a branch beta&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;O impacto para o usuário é de que correções sejam liberadas de forma mais rápida e, principalmente, bugs em produção são menos frequentes.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔨 Desafios
&lt;/h2&gt;

&lt;p&gt;Para entregar o código em produção com rapidez e segurança, alguns itens teriam que ser solucionados:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Todos os cenários deveriam ser cobertos por teste;&lt;/li&gt;
&lt;li&gt;O código deveria seguir o &lt;a href="https://standardjs.com/" rel="noopener noreferrer"&gt;padrão do JS&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;As mensagens de commit deveriam seguir o padrão do &lt;a href="https://www.conventionalcommits.org/" rel="noopener noreferrer"&gt;Conventional Commit&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Todas as alterações que geraram release deveriam estar documentadas no &lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/blob/master/CHANGELOG.md" rel="noopener noreferrer"&gt;Changelog&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;O versionamento deveria corresponder às alterações desde a última release e ao &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;Semantic versioning&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;A estratégia de branches deveria permitir integrar código na &lt;code&gt;master&lt;/code&gt; e &lt;code&gt;beta&lt;/code&gt; apenas se todas as validações fossem executadas;&lt;/li&gt;
&lt;li&gt;Publicar na dist-tag &lt;em&gt;@latest&lt;/em&gt; apenas o que fosse integrado na &lt;code&gt;master&lt;/code&gt;, e &lt;em&gt;&lt;a class="mentioned-user" href="https://dev.to/beta"&gt;@beta&lt;/a&gt;&lt;/em&gt; o que fosse integrado na branch &lt;code&gt;beta&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Somente deveria ser feita publicação automática caso a alteração realizada necessitasse de publicação.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📁 Libs NPM utilizadas
&lt;/h2&gt;

&lt;p&gt;Para solucionar todos os desafios listados acima e poder entregar uma release com qualidade e manter o código bem estruturado, foram utilizadas diversas libs NPM em conjunto, cada qual com sua responsabilidade e sendo executadas em etapas diferentes no fluxo de trabalho.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/standard" rel="noopener noreferrer"&gt;Standard&lt;/a&gt; - &lt;code&gt;JavaScript style guide, linter, and formatter&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/husky" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; - Executa ações em git hooks, como &lt;code&gt;pre-commit&lt;/code&gt; e &lt;code&gt;commit-msg&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@commitlint/cli" rel="noopener noreferrer"&gt;Commitlint&lt;/a&gt; - Valida se a mensagem de commit segue o conventional commits;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/supertest" rel="noopener noreferrer"&gt;Supertest&lt;/a&gt; - Testes de APIs Rest;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@semantic-release/commit-analyzer" rel="noopener noreferrer"&gt;Semantic-release/commit-analyzer&lt;/a&gt; - Analisa as mensagens de commit de acordo com o &lt;a href="https://github.com/conventional-changelog/conventional-changelog" rel="noopener noreferrer"&gt;conventional-changelog&lt;/a&gt; e informa qual tipo de versão deve ser gerada (&lt;code&gt;major&lt;/code&gt;, &lt;code&gt;minor&lt;/code&gt; ou &lt;code&gt;patch&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@semantic-release/release-notes-generator" rel="noopener noreferrer"&gt;Semantic-release/release-notes-generator&lt;/a&gt; - Gera as notas da release;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@semantic-release/changelog" rel="noopener noreferrer"&gt;Semantic-release/changelog&lt;/a&gt; - Gera/atualiza o changelog com as notas da release;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@semantic-release/npm" rel="noopener noreferrer"&gt;Semantic-release/npm&lt;/a&gt; - Atualiza a versão do projeto e publica o pacote NPM;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@semantic-release/git" rel="noopener noreferrer"&gt;Semantic-release/git&lt;/a&gt; - Commita o &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;package-lock.json&lt;/code&gt; e o &lt;code&gt;CHANGELOG.md&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@semantic-release/github" rel="noopener noreferrer"&gt;Semantic-release/github&lt;/a&gt; - Publica uma release no Github com as notas da release.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Para mais detalhes visualize a seção &lt;em&gt;devDependencies&lt;/em&gt; do &lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/blob/master/package.json" rel="noopener noreferrer"&gt;package.json&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📑 Fluxo de trabalho
&lt;/h2&gt;

&lt;p&gt;Abaixo será relatado todo o fluxo de trabalho, desde o momento que um bug é relatado até o momento que a correção está publicada em nova release.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Issue
&lt;/h3&gt;

&lt;p&gt;Um usuário abre uma nova &lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/issues" rel="noopener noreferrer"&gt;issue&lt;/a&gt; no projeto, relatando um bug e seguindo o template de issue.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Desenvolvimento local
&lt;/h3&gt;

&lt;p&gt;Libs: &lt;code&gt;husky&lt;/code&gt;, &lt;code&gt;commitlint&lt;/code&gt; e &lt;code&gt;standard&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O desenvolvedor irá atuar em uma branch a partir da &lt;em&gt;master&lt;/em&gt; (seguindo o &lt;em&gt;Github Flow&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Serão feito os ajustes afim de corrigir o bug, e então será realizado o commit. Nesse momento será utilizado a lib &lt;code&gt;husky&lt;/code&gt;.

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;pre-commit&lt;/em&gt;: Será executado o &lt;code&gt;standard&lt;/code&gt;, validando se o código respeita ao padrão de código do JS.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;commit-msg&lt;/em&gt;: Será executado o &lt;code&gt;commitlint&lt;/code&gt;, validando se a mensagem de commit segue o conventional commit.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Caso alguma validação encontre problema, o commit será abortado, e então o dev terá que ajustar o código ou a mensagem de commit. Com isso todo commit realizado estará bem estruturado.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Pull Request
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/PauloGoncalvesBH/serverest/workflows/Continuous%20Integration/badge.svg" alt="Continuous Integration" width="198" height="20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Libs: &lt;code&gt;supertest&lt;/code&gt;, &lt;code&gt;commitlint&lt;/code&gt; e &lt;code&gt;standard&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O desenvolvedor irá abrir no Github uma Pull Request para integrar a sua branch com a &lt;em&gt;master&lt;/em&gt;. O PR somente será mergeado caso as seguintes etapas sejam aprovadas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Code review de outro desenvolvedor;&lt;/li&gt;
&lt;li&gt;Validação dos testes de API criados com &lt;code&gt;supertest&lt;/code&gt; nas 3 principais versões LTS do node. Executado na pipeline de integração contínua;&lt;/li&gt;
&lt;li&gt;Validação da mensagem de commit com &lt;code&gt;commitlint&lt;/code&gt;. Executado na pipeline de integração contínua;&lt;/li&gt;
&lt;li&gt;Validação da estrutura do código com &lt;code&gt;standard&lt;/code&gt;. Executado na pipeline de integração contínua.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Print de validações feitas em um Pull Request:&lt;/strong&gt;&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%2Fysdddco3va3fcc7eamlt.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%2Fysdddco3va3fcc7eamlt.png" width="340" height="322"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  4️⃣ Criação da release
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/PauloGoncalvesBH/ServeRest/workflows/Continuous%20Delivery/badge.svg" alt="Continuous Delivery" width="181" height="20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lib: &lt;code&gt;semantic-release/*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Após o PR ser aprovado e integrado com a &lt;em&gt;master&lt;/em&gt; ou &lt;em&gt;beta&lt;/em&gt;, começa todo o processo de entrega contínua.&lt;/p&gt;

&lt;p&gt;Inicialmente são executados as mesmas validações feitas na PR (&lt;em&gt;commitlint&lt;/em&gt;, &lt;em&gt;standard&lt;/em&gt; e &lt;em&gt;testes de API&lt;/em&gt;). Apenas com a execução com sucesso de todas essas validações é que é iniciado o processo de entrega contínua.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Print da pipeline de Continuous Delivery:&lt;/strong&gt;&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%2Ficslg2lx8hasos4tu68v.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%2Ficslg2lx8hasos4tu68v.png" width="340" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na atividade &lt;em&gt;release&lt;/em&gt; é executado o &lt;code&gt;semantic-release&lt;/code&gt;, que utiliza a configuração implementada e realiza as tarefas de entrega contínua.&lt;/p&gt;

&lt;p&gt;Inicialmente é validado se há commit, desde a última git tag, que gera uma nova release &lt;code&gt;major&lt;/code&gt;, &lt;code&gt;minor&lt;/code&gt; ou &lt;code&gt;patch&lt;/code&gt;. Caso esse critério seja atendido as seguintes ações são realizadas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A versão do &lt;em&gt;package.json&lt;/em&gt; e do &lt;em&gt;package-lock.json&lt;/em&gt; são atualizadas;&lt;/li&gt;
&lt;li&gt;É gerada as notas de release contendo informação de todos os commits desde a última git tag;&lt;/li&gt;
&lt;li&gt;O &lt;em&gt;CHANGELOG&lt;/em&gt; é atualizado com as notas de release;&lt;/li&gt;
&lt;li&gt;É realizado publicação no &lt;em&gt;NPM&lt;/em&gt;, e o artefato é armazenado temporariamente;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;package.json&lt;/em&gt;, &lt;em&gt;package-lock.json&lt;/em&gt; e &lt;em&gt;CHANGELOG&lt;/em&gt; são commitados com nova tag e informação da nova release. É utilizado o usuário &lt;code&gt;semantic-release-bot&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;É criado nova release no Github utilizando a tag gerada, o artefato armazenado temporariamente e as notas de release;&lt;/li&gt;
&lt;li&gt;É feita comunicação aos interessados sobre a nova release. Veja mais na seção Comunicação de release gerada.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Print do commit do &lt;code&gt;semantic-release&lt;/code&gt;:&lt;/strong&gt;&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%2Ft368ch0hjqxtj8ufpyda.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%2Ft368ch0hjqxtj8ufpyda.png" width="552" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Print da release gerada no github:&lt;/strong&gt;&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%2Fw6be0g1b4frcryve3oxy.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%2Fw6be0g1b4frcryve3oxy.png" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caso queira verificar com mais detalhes a configuração feita quanto ao &lt;code&gt;semantic-release&lt;/code&gt;, verifique o arquivo &lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/blob/master/.releaserc.js" rel="noopener noreferrer"&gt;.releaserc.js&lt;/a&gt; e o &lt;a href="https://github.com/PauloGoncalvesBH/ServeRest/blob/master/.github/workflows/continuous_delivery.yml" rel="noopener noreferrer"&gt;workflow de continuous delivery&lt;/a&gt; (a partir da linha 60).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  5️⃣ Comunicação de release gerada
&lt;/h3&gt;

&lt;p&gt;Lib: &lt;code&gt;semantic-release&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Após a publicação da release em produção é preciso comunicar aos interessados de que suas respectivas issues e PR foram corrigidas.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;semantic-release&lt;/code&gt; verifica quais issues foram fechadas e quais PRs foram aprovados e que fazem parte da nova release. Com isso ele adiciona comentário informando de que uma nova release está disponível com a solução para a situação relatada e adiciona as labels &lt;em&gt;released on @{tag}&lt;/em&gt; e &lt;em&gt;released on @{versão}&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Print de comentário e label automático em PR:&lt;/strong&gt;&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%2Fguz29w2odbmqyesk85gn.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%2Fguz29w2odbmqyesk85gn.png" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Com isso passamos por todas as etapas da entrega contínua no contexto do &lt;em&gt;ServeRest&lt;/em&gt;. Caso tenha dúvidas ou sugestões, deixe um comentário abaixo. Não deixe de visitar o repositório do &lt;a href="https://github.com/PauloGoncalvesBH/serverest" rel="noopener noreferrer"&gt;ServeRest&lt;/a&gt; e deixar a sua estrelinha ⭐.&lt;/p&gt;




&lt;h6&gt;
  
  
  &lt;em&gt;Esse post está sendo versionado e hospedado no &lt;a href="https://github.com/PauloGoncalvesBH/entrega-continua-no-serverest" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/em&gt;
&lt;/h6&gt;

</description>
      <category>continuousdelivery</category>
      <category>serverest</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>QA, trate sua automação como software</title>
      <dc:creator>Paulo Gonçalves</dc:creator>
      <pubDate>Tue, 19 Nov 2019 04:58:11 +0000</pubDate>
      <link>https://forem.com/paulogoncalvesr/qa-trate-sua-automacao-como-software-noo</link>
      <guid>https://forem.com/paulogoncalvesr/qa-trate-sua-automacao-como-software-noo</guid>
      <description>&lt;p&gt;Quando pensamos em automação de testes, muitas vezes passa pela nossa cabeça questões como pirâmide de testes e qual linguagem/framework será utilizado para realizar a automação. Caso seja levado em conta boas práticas de automação, não passamos da discussão de adotar page objects ou page actions na automação de interface.&lt;/p&gt;

&lt;p&gt;Porém, é importante atentarmos que há muitos outros fatores determinantes para a manutenção daquela automação por membros da equipe, afinal, quem nunca trocou trechos de código via chat ou teve dificuldade para saber porque que uma determinada alteração foi realizada na automação? &lt;/p&gt;

&lt;p&gt;É importante preocuparmos mais com o nosso código, afinal...&lt;/p&gt;

&lt;h3&gt;
  
  
  Código de teste é software e deve ser tratado como tal
&lt;/h3&gt;

&lt;p&gt;E vamos ser sinceros, assim como o dev deve entregar seu código com qualidade, nada mais justo que nós, QA, também entreguemos com qualidade.&lt;/p&gt;

&lt;p&gt;Esses problemas foram solucionados há muito tempo no desenvolvimento de software e pretendo listar aqui algumas dicas interessantes de serem adotadas no seu &lt;del&gt;código de automação&lt;/del&gt; software.&lt;/p&gt;

&lt;p&gt;Resumo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilize Git e deixe o código acessível&lt;/li&gt;
&lt;li&gt;Escreva boas mensagens de commit (caso já utilize git)&lt;/li&gt;
&lt;li&gt;Padronize o seu código&lt;/li&gt;
&lt;li&gt;Documente o seu projeto&lt;/li&gt;
&lt;li&gt;Separe as dependências de desenvolvimento e produção&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Utilize Git e deixe o código acessível
&lt;/h2&gt;

&lt;p&gt;Versione o seu código utilizando Git e o torne acessível para os outros membros através de conta no &lt;a href="https://about.gitlab.com" rel="noopener noreferrer"&gt;Gitlab&lt;/a&gt;, &lt;a href="//github.com"&gt;Github&lt;/a&gt; ou hospedado em servidor da empresa.&lt;br&gt;
Com isso, pare de:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hospedar o código apenas na sua máquina (ela pode pifar).&lt;/li&gt;
&lt;li&gt;De manter código comentado, por ter medo de que aquele trecho de código será necessário um dia (nunca será).&lt;/li&gt;
&lt;li&gt;E, principalmente, de enviar arquivos via e-mail e tendo sempre que fazer o controle de qual arquivo pode ser substituído ou não.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Deixe tudo isso para o git resolver.&lt;/p&gt;

&lt;p&gt;Para saber mais, veja as &lt;a href="https://medium.com/assertqualityassurance/dicas-de-git-para-testers-fdd721585fae" rel="noopener noreferrer"&gt;dicas de git para testers&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bônus:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use branch.&lt;/li&gt;
&lt;li&gt;Evite usar GitFlow. Para saber mais leia &lt;a href="https://lucamezzalira.com/2014/03/10/git-flow-vs-github-flow/" rel="noopener noreferrer"&gt;Git Flow vs Github Flow&lt;/a&gt; e &lt;a href="https://www.endoflineblog.com/gitflow-considered-harmful" rel="noopener noreferrer"&gt;GitFlow considered harmful&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;rebase&lt;/code&gt;, evite de usar &lt;code&gt;merge&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Escreva boas mensagens de commit (caso já utilize git)
&lt;/h2&gt;

&lt;p&gt;Agora que está utilizando o git, é importante que não cometa as falhas de escrita de mensagens de commit.&lt;br&gt;
 É comum clonarmos um repositório de testes, tentarmos investigar porque tal arquivo foi modificado e depararmos com um log nada amigável como esse:&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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fboas-mensagens-de-commit-1.jpg" 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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fboas-mensagens-de-commit-1.jpg" alt="Print do terminal do windows, aonde mostra alguns títulos de commits. Os commits são mal descritos, como " width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Sim, esse log é real&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vendo esse log, consegue identificar de forma fácil o motivo de cada alteração? Para saber terá que investigar as alterações realizadas ou conversar com o autor do código, que pode nem estar mais na empresa. E tudo isso vai te fazer gastar um bom tempo.&lt;/p&gt;

&lt;p&gt;É importante que as mensagens de commit sejam totalmente claras, de forma de que ao lê-la fique claro que tipo de alteração foi feita e o que levou ela a ser feita, como essa:&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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fboas-mensagens-de-commit-2.jpg" 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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fboas-mensagens-de-commit-2.jpg" alt="Print do terminal do windows, mostrando uma mensagem de commit clara, que informa que a alteração é devido a uma feature e o porquê foi feito a alteração, e não quais arquivos que foram alterados." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consegue notar que esse commit consegue passar mais informações importantes, poupando tempo de investigação?&lt;/p&gt;

&lt;p&gt;Para entender sobre como escrever boas mensagens de commit, leia o &lt;a href="https://github.com/RomuloOliveira/commit-messages-guide/blob/master/README_pt-BR.md" rel="noopener noreferrer"&gt;guia de mensagens de commit&lt;/a&gt; e &lt;a href="https://www.conventionalcommits.org" rel="noopener noreferrer"&gt;convenção de commit&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bônus:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;a href="https://www.npmjs.com/package/git-cz" rel="noopener noreferrer"&gt;git-cz&lt;/a&gt; para te ajudar a escrever mensagens de commit usando a convenção.&lt;/li&gt;
&lt;li&gt;Valide se a mensagem está respeitando o padrão no &lt;code&gt;pre-commit&lt;/code&gt;, conciliando, por exemplo, &lt;a href="https://commitlint.js.org/#/" rel="noopener noreferrer"&gt;commitlint&lt;/a&gt; e &lt;a href="https://github.com/typicode/husky" rel="noopener noreferrer"&gt;husky&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Padronize o seu código
&lt;/h2&gt;

&lt;p&gt;Como cada pessoa possui o seu estilo de codificar, é esperado de que o projeto de automação, por ter mais de 1 pessoa, possua vários estilos diferentes.&lt;/p&gt;

&lt;p&gt;O código abaixo, escrito por 2 pessoas, possui as seguintes diferenças:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Espaçamento no início do código.&lt;/li&gt;
&lt;li&gt;Uso de ponto-e-vírgula.&lt;/li&gt;
&lt;li&gt;Uso de aspas duplas e aspas simples.&lt;/li&gt;
&lt;/ol&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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fpadronize-seu-codigo.jpg" 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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fpadronize-seu-codigo.jpg" alt="Exemplo de código aonde mostra várias linhas de código contendo 2 métodos. Ambos os métodos diferem no tamanho da identação, 1 deles possui ponto e vírgula e o outro não, e 1 usa aspas duplas e outro aspas simples no mapeamento de elemento." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para solucionar esse problema use um formatador de código opinativo, como o &lt;a href="https://prettier.io" rel="noopener noreferrer"&gt;prettier&lt;/a&gt;, para garantir que todo o código esteja consistente e com um estilo único, facilitando sua leitura.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bônus:&lt;br&gt;
Execute o &lt;a href="https://prettier.io" rel="noopener noreferrer"&gt;prettier&lt;/a&gt; no &lt;code&gt;pre-commit&lt;/code&gt; com &lt;a href="https://github.com/typicode/husky" rel="noopener noreferrer"&gt;husky&lt;/a&gt;, para garantir que todo código enviado esteja padronizado.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Documente o seu projeto
&lt;/h2&gt;

&lt;p&gt;É importante que o seu projeto possua uma boa documentação, pois é ela que vai informar para as outras pessoas sobre qual o papel do projeto, como configurar, executar, contribuir e outras informações importantes.&lt;/p&gt;

&lt;p&gt;Código sem documentação é difícil de ser operado por pessoas alheias ao projeto, que terão que perder tempo analisando o código para entenderem um pouco sobre o mesmo.&lt;/p&gt;

&lt;p&gt;Por isso, foque em escrever um README.md para o seu projeto. A extensão &lt;code&gt;.md&lt;/code&gt; é de markdown, uma linguagem simples de marcação que apoia a escrever com boa produtividade textos organizados.&lt;/p&gt;

&lt;p&gt;README.md é tão importante que todo projeto open source procura ter ele bem detalhado e atualizado.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo de markdown extraído do projeto open source &lt;a href="https://github.com/wlsf82/protractor-helper" rel="noopener noreferrer"&gt;protractor-helper&lt;/a&gt;&lt;/em&gt;&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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fdocumente-seu-projeto.jpg" 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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fdocumente-seu-projeto.jpg" alt="Print da documentação do projeto protractor-helper, explicando para que serve o projeto, como configurar ele e como usá-lo. É apenas um simples documento de texto com organização visual escrito usando o markdown." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para saber mais, veja esse ótimo &lt;a href="https://agea.github.io/tutorial.md/" rel="noopener noreferrer"&gt;tutorial de markdown&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Separe as dependências de desenvolvimento e produção
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Essa dica serve apenas para javascript&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quando estiver instalando as dependências necessárias para o seu projeto, é importante identificar quais são necessárias apenas para desenvolvimento e quais são para a execução dos testes.&lt;/p&gt;

&lt;p&gt;Essa separação é importante para quando outra pessoa ou o ambiente de CI for rodar a sua automação, ele baixe apenas as dependências necessárias. Afinal, para rodar os testes não é importante baixar o pacote de validação de commit.&lt;br&gt;
É preciso ter em mente também de que algumas dependências possuem dezenas de dependências, fazendo com que, de forma fácil, seja baixado mais de 100 pacotes de forma desnecessária.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo de separação&lt;/em&gt;&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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fsepare-as-dependencias.jpg" 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%2Fraw.githubusercontent.com%2FPauloGoncalvesBH%2FQA-trate-sua-automacao-como-software%2Fmaster%2FREADME.md%2Fimages%2Fsepare-as-dependencias.jpg" alt="Nesse print do visual studio code há 2 seções, o devdependencies e o dependencies, e dentro de cada tem várias bibliotecas diferente. Na seção devdependencies tem bibliotecas necessárias para codificar, e na dependencies para rodar os testes, como protractor e faker." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nessa situação, quando for fazer a instalação apenas para executar a automação, utilize:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para saber mais, leia a documentação do &lt;a href="https://docs.npmjs.com/files/package.json#dependencies" rel="noopener noreferrer"&gt;package.json&lt;/a&gt; e do &lt;a href="https://docs.npmjs.com/cli/install" rel="noopener noreferrer"&gt;npm-install&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Se chegou até aqui, não deixa de fornecer feedback e curtir o post 😃&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Gostou do assunto e quer saber mais? Leia &lt;a href="https://medium.com/assertqualityassurance/por-favor-dont-code-like-a-tester-1a93eb3ee3ae" rel="noopener noreferrer"&gt;Por favor, “don't code like a tester”&lt;/a&gt; um ótimo post do Leonardo Galani e de onde tirei a frase 'Código de teste é software e deve ser tratado como tal'.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>testing</category>
      <category>testautomation</category>
      <category>ptbr</category>
    </item>
  </channel>
</rss>
