<?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: gpiress</title>
    <description>The latest articles on DEV Community by gpiress (@gpiress).</description>
    <link>https://dev.to/gpiress</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%2F440562%2Fe120e11d-24fa-42c3-a64a-e331aa2663e7.png</url>
      <title>DEV Community: gpiress</title>
      <link>https://dev.to/gpiress</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gpiress"/>
    <language>en</language>
    <item>
      <title>Como seguir a pirâmide de testes</title>
      <dc:creator>gpiress</dc:creator>
      <pubDate>Wed, 05 Aug 2020 15:57:45 +0000</pubDate>
      <link>https://dev.to/gpiress/como-seguir-a-piramide-de-testes-a94</link>
      <guid>https://dev.to/gpiress/como-seguir-a-piramide-de-testes-a94</guid>
      <description>&lt;p&gt;Testes automatizados estão presentes em (quase) todos os projetos atuais.&lt;br&gt;
Seu uso aumenta a qualidade do produto gerado e torna os times envolvidos mais confiantes e produtivos.&lt;/p&gt;

&lt;p&gt;Como tentativa de garantir a qualidade de um projeto, não é difícil encontrar requisitos de porcentagem de código coberto por testes e outras métricas semelhantes. Essas métricas podem acabar sendo maléficas ao código, criando a existência de testes que efetivamente não testam nada, mas que mantém a métrica acima do limite desejado.&lt;/p&gt;

&lt;p&gt;Mas então o que devemos testar? E como?&lt;/p&gt;
&lt;h2&gt;
  
  
  Pirâmide de testes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dcM0135C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ealtg2m79jiaur0ryb3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dcM0135C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ealtg2m79jiaur0ryb3v.png" alt="Pirâmide de testes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A pirâmide de testes é como você deve pensar sua estratégia de testes: a base da pirâmide é composta por testes unitários, o meio por testes de integração e o topo por testes &lt;em&gt;End-to-end&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;A analogia da pirâmide é útil para trazer uma imagem da quantidade de testes esperada em cada uma dessas camadas. Testes unitários (a base) devem estar presentes em maior número que testes de integração, e testes de integração devem existir em maior número que testes &lt;em&gt;End-to-end&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos falar sobre cada um desses tipos de teste e o como utilizá-los.&lt;/p&gt;

&lt;p&gt;Nota: é possível encontrar muitas versões diferentes dessa pirâmide, mas eu acredito que essa é a mais útil para entender os conceitos e contém o necessário para a maioria dos projetos.&lt;/p&gt;
&lt;h2&gt;
  
  
  Testes unitários
&lt;/h2&gt;

&lt;p&gt;Testes unitários são provavelmente os mais conhecidos e mais difundidos dentre os testes automatizados. Eles testam uma &lt;em&gt;unidade&lt;/em&gt; e são normalmente bem rápidos e auto-contidos.&lt;/p&gt;
&lt;h3&gt;
  
  
  O que é uma unidade?
&lt;/h3&gt;

&lt;p&gt;Eu gosto de definir uma &lt;em&gt;unidade&lt;/em&gt; a ser testada como o menor grupo lógico de código possível em sua arquitetura. Isso quer dizer que em Java isso seria uma classe, em ReactJS seria um componente, em alguns projetos NodeJS e Python seria um módulo e assim por diante. O mais importante é ser consistente com a sua definição de unidade para o projeto.&lt;/p&gt;
&lt;h3&gt;
  
  
  O que testar?
&lt;/h3&gt;

&lt;p&gt;Por via de regra, é necessário escrever testes para toda &lt;em&gt;lógica&lt;/em&gt; e &lt;em&gt;regra de negócio&lt;/em&gt; contida em sua unidade. Basicamente sua unidade só existe por conta das regras de negócio que ela satisfaz, então elas devem estar bem testadas.&lt;/p&gt;

&lt;p&gt;Sendo mais específico, eu costumo testar o &lt;em&gt;contrato&lt;/em&gt; de uma unidade, isto é, todas as interfaces públicas que podem ser usadas por outras partes do código.&lt;/p&gt;

&lt;p&gt;Segue um exemplo de uma classe &lt;code&gt;CaseConverter&lt;/code&gt; que converte uma string para outro tipo de case (snake_case, camelCase):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Case&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;CAMEL_CASE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="no"&gt;SNAKE_CASE&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Case&lt;/span&gt; &lt;span class="n"&gt;convertTo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;convertTo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;CAMEL_CASE:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;convertToCamel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SNAKE_CASE:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;convertToSnake&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;convertToCamel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;camelCaseBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;camelCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;camelCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;camelCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;substring&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                &lt;span class="n"&gt;camelCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;substring&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;camelCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;convertToSnake&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;snakeCaseBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snakeCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;snakeCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;snakeCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;snakeCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;snakeCaseBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O &lt;em&gt;contrato&lt;/em&gt; dessa classe é &lt;em&gt;convert(String, Case) -&amp;gt; String&lt;/em&gt; ou seja, ao chamar a única função pública &lt;code&gt;convert&lt;/code&gt; passando como parâmetros uma String e o tipo de Case desejados, essa função retornará a String convertida.&lt;/p&gt;

&lt;p&gt;Devemos porém criar testes que testem toda funcionalidade que oferecemos, converter para camelCase e para snake-case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CaseConverterTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;convert_should_convert_to_camel_case&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SOmE teXt hERE"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"someTextHere"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt; &lt;span class="n"&gt;caseConverter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;caseConverter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;convert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CAMEL_CASE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;convert_should_convert_to_snake_case&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SOmE teXt hERE"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"some_text_here"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt; &lt;span class="n"&gt;caseConverter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;caseConverter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;convert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CaseConverter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Case&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SNAKE_CASE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Desse modo, verificamos que nossa classe cumpre os requisitos necessários, mesmo sem invocar explicitamente cada uma de suas funções. Perceba que as funções ainda são invocadas indiretamente, mas isso não é o mais importante, seu teste agora não assume nada sobre o funcionamento interno. Apenas testa que o &lt;em&gt;contrato&lt;/em&gt; é cumprido.&lt;/p&gt;

&lt;p&gt;Observação 1: Algumas linguagens não possuem o conceito de funções públicas e privadas, mas ainda assim elas seguem um  padrão de contrato de uso. Tente pensar qual o contrato da sua unidade antes de escrever qualquer código!&lt;/p&gt;

&lt;p&gt;Observação 2: Java possui a anotação &lt;code&gt;@VisibleForTesting&lt;/code&gt; disponível através de diferentes bibliotecas. Eu acredito que o uso dessa anotação é um [code smell(&lt;a href="https://en.wikipedia.org/wiki/Code_smell"&gt;https://en.wikipedia.org/wiki/Code_smell&lt;/a&gt;) e deve ser evitado quando possível.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que não testar: Mocks (Spies)
&lt;/h3&gt;

&lt;p&gt;Frequentemente nossas classes possuem dependências, tanto outras classes definidas no mesmo repositório ou dependências externas. Exemplos comuns são classes de acesso a Banco de Dados e clientes para requisições HTTPS.&lt;/p&gt;

&lt;p&gt;Nesses casos, a recomendação é utilizar Injeção de Dependências no construtor da classe e &lt;strong&gt;não&lt;/strong&gt; testar o funcionamento dessas dependências, pois:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Se forem outras classes do seu repositório, elas serão testadas unitariamente em seus próprios testes.&lt;/li&gt;
&lt;li&gt;Se forem dependências externas, elas devem ser testadas unitariamente pelos donos da dependência.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Em ambos os casos, as dependências devem ser testadas em testes de &lt;em&gt;integração&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Para não testar e falhar com sua dependência, utiliza-se &lt;em&gt;mocks&lt;/em&gt;, que são objetos que fingem implementar os contratos das dependências, e que a pessoa escrevendo testes tem total controle sobre o comportamento.&lt;/p&gt;

&lt;p&gt;Lembre-se que o objetivo dos testes unitários é garantir o contrato e testar a lógica interna da unidade, nada além disso. Por isso é necessário seguir a pirâmide de testes!&lt;/p&gt;

&lt;p&gt;Uma última dica é que seus testes unitários jamais devem fazer requisições para nada fora da sua aplicação, como por exemplo serviços web externos. Isso se deve porque não há como garantir que esses serviços externos se mantenham online o tempo todo e com a mesma interface (api). Seu teste unitário não pode falhar por conta de um serviço externo.&lt;/p&gt;

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

&lt;p&gt;Testes de integração são os mais comuns de serem esquecidos na hora de escrever testes para um projeto. O objetivo dos testes de integração não é testar a lógica das unidades, mas testar como diferentes unidades interagem entre si.&lt;/p&gt;

&lt;p&gt;Não é incomum que repositórios tenham várias unidades que juntas são responsáveis por uma finalidade. É possível que todas essas unidades passem testes unitários e mesmo assim não funcionem em conjunto. Os testes de integração garantem que as unidades são utilizáveis em conjunto.&lt;/p&gt;

&lt;p&gt;Exemplos de testes de integração:&lt;/p&gt;

&lt;h3&gt;
  
  
  Em uma página com uma lista de tarefas
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Página com componentes de lista de tarefas e adicionar tarefa.&lt;/li&gt;
&lt;li&gt;TESTE: Todos os componentes são exibidos corretamente&lt;/li&gt;
&lt;li&gt;Adicionar uma tarefa nova&lt;/li&gt;
&lt;li&gt;TESTE: A lista de tarefas é atualizada para incluir a tarefa adicionada&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Teste "vertical" de uma funcionalidade
&lt;/h3&gt;

&lt;p&gt;Para uma funcionalidade de exibir um mapa com restaurantes bem avaliados na proximidade.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Front end: Página ou componente de App que mostre o mapa&lt;/li&gt;
&lt;li&gt;Back end: Serviço que retorna restaurantes bem avaliados dado uma localização&lt;/li&gt;
&lt;li&gt;Banco de Dados: Contém as informações de restaurantes: localização e avaliação&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Iniciando o ambiente de testes

&lt;ol&gt;
&lt;li&gt;Inicializar o componente frontend&lt;/li&gt;
&lt;li&gt;Inicializar o serviço backend&lt;/li&gt;
&lt;li&gt;Inicializar o Banco de Dados com dados de teste&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;No front end, navegar para uma posição de teste e pedir recomendações&lt;/li&gt;
&lt;li&gt;No front end, verificar que os restaurantes esperados foram recomendados&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nesse caso você garante que a funcionalidade funciona em um ambiente ainda controlado, que não é o que o usuário final vai seguir. Ainda que utilize um Banco de Dados de teste, existe uma garantia de qualidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testes de segurança
&lt;/h3&gt;

&lt;p&gt;Por exemplo para garantir que a comunicação entre um componente frontend e um componente backend seja encriptada e que nenhum dado sensível seja transmitido pela rede.&lt;/p&gt;

&lt;p&gt;Esses testes são mais lentos que os testes unitários, pois envolvem mais partes e inicializações. E por se tratarem de integrações entre unidades, seu número deve ser bem menor que o de testes unitários.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testes end-to-end
&lt;/h2&gt;

&lt;p&gt;Testes end-to-end (de fim-a-fim ?) são os testes que simulam a jornada de um usuário no seu aplicativo. Eles devem simular &lt;em&gt;exatamente&lt;/em&gt; o que um usuário faria para utilizar seu produto a fim de capturar erros em alguma dessas etapas.&lt;/p&gt;

&lt;p&gt;Não é incomum encontrar repositórios com muitos testes desse tipo. Esse é o tipo de teste mais simples de justificar a existência do ponto de vista do produto, pois emula a experiência do usuário. São portanto muito importantes, pois são os testes mais próximos do que o usuário realmente vai encontrar ao utilizar o aplicativo.&lt;/p&gt;

&lt;p&gt;Mas testes end-to-end tem alguns problemas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Podem ser difíceis de definir -- nem sempre é simples escrever um script para seguir o fluxo exato no aplicativo e testar exatamente cada passo&lt;/li&gt;
&lt;li&gt;São muito lentos -- por simular a experiência de usuário, normalmente precisam de todos os componentes inicializados, carregar imagens, executar requisições, etc&lt;/li&gt;
&lt;li&gt;Baixa granularidade de erros -- mesmo quando capturam erros, muitas vezes é difícil saber a origem exata do problema já que esses testes são definidos em nível muito alto, cada passo pode envolver muitas unidades.&lt;/li&gt;
&lt;li&gt;Podem ter custo elevado -- testes que comparam vídeos ou imagens de uso rapidamente precisam aumentar o armazenamento de dados para comparação e, se muito utilizados, podem representar um custo não negligível para o projeto.&lt;/li&gt;
&lt;li&gt;Testes "flaky", que hora passam, hora falham -- quanto mais pra cima da pirâmide o seu teste, mais ele é afetado por questões fora do seu controle, rede interna, conexões externas, performance da máquina rodando o teste, etc. Ter muitos testes flaky pode diminuir a confiança dos times nos testes e diminuir a qualidade do código.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por conta dos problemas associados, esses testes devem ser usados em quantidades moderadas, para os fluxos críticos do aplicativo em questão.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo de teste end-to-end
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Usuário faz login no aplicativo com user "foca" e senha "123"&lt;/li&gt;
&lt;li&gt;Usuário vê uma tela com todas suas faturas futuras: 1, 2 e 3&lt;/li&gt;
&lt;li&gt;Usuário clica na fatura 2&lt;/li&gt;
&lt;li&gt;Tela com mais informações sobre a fatura 2 é exibida&lt;/li&gt;
&lt;li&gt;Usuário clica para alterar data de pagamento da fatura 2&lt;/li&gt;
&lt;li&gt;Usuário altera data para 31/12/2021&lt;/li&gt;
&lt;li&gt;Usuário vê alerta de data inválida&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pelo exemplo dá pra perceber que testar todos os possíveis cenários seja uma tarefa hercúlea. E é mesmo, por isso é importante garantir que os testes unitários e de integração estejam bem escritos e realmente testando a lógica do projeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Esse artigo cobriu a pirâmide de testes, descreveu a importância de cada um dos tipos de teste que a compõe, testes &lt;em&gt;unitários&lt;/em&gt;, &lt;em&gt;de integração&lt;/em&gt; e &lt;em&gt;end-to-end&lt;/em&gt;. Os testes unitários devem ser os mais presentes em qualquer repositório, mas devem testar apenas a lógica de uma unidade e seu contrato. Testes de integração verificam o funcionamento de várias unidades em conjunto e os testes end-to-end testam a jornada crítica de seus usuários.&lt;/p&gt;

&lt;p&gt;Uma proporção base pra utilizar como orientação é: a cada 100 testes unitários, 10 testes de integração e 1 teste end-to-end&lt;/p&gt;

&lt;p&gt;Gostou? Achou útil? Discorda? Me conta :).&lt;/p&gt;

</description>
      <category>testing</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Quando usar TDD</title>
      <dc:creator>gpiress</dc:creator>
      <pubDate>Sat, 25 Jul 2020 22:09:20 +0000</pubDate>
      <link>https://dev.to/gpiress/quando-usar-tdd-1c18</link>
      <guid>https://dev.to/gpiress/quando-usar-tdd-1c18</guid>
      <description>&lt;p&gt;&lt;em&gt;Test-Driven Development&lt;/em&gt;, ou Desenvolvimento Orientado a Testes em português, conhecido por sua sigla TDD é uma prática de engenharia de software que nunca foi unanimidade e que, passado o &lt;em&gt;hype&lt;/em&gt;, tem sido mais criticada do que apoiada nos círculos mais populares.&lt;/p&gt;

&lt;p&gt;Pelo título, dá pra perceber que eu acredito que a prática tem seu lugar e tentarei explicar meu ponto de vista nesse texto, passando por definição, pontos positivos e negativos. Esse artigo reflete minha opinião, então não é completamente imparcial, mas tentarei passar por todos os pontos que creio relevantes.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é TDD?
&lt;/h2&gt;

&lt;p&gt;Talvez a definição não seja muito óbvia caso não seja familiar com o tema, mas Desenvolvimento Orientado a Testes quer dizer que o processo de escrita de código começa pela escrita dos testes, e somente após os testes estarem escritos (e falhando) que a implementação do código começa. Esse ciclo é chamado "Red-Green-Refactor".&lt;/p&gt;

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

&lt;p&gt;A ideia é que dessa maneira, antes de começar a escrever o código, as pessoas desenvolvedoras procurem descobrir quais são as &lt;em&gt;regras de negócio&lt;/em&gt; que o código deve satisfazer, e quais são as &lt;em&gt;expectativas&lt;/em&gt; daquele código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolvendo FizzBuzz, um exemplo de TDD em prática
&lt;/h2&gt;

&lt;p&gt;Para ilustrar a ideia, segue um exemplo de solução do problema &lt;em&gt;FizzBuzz&lt;/em&gt;. A definição do problema é, para todo inteiro &lt;code&gt;n&lt;/code&gt; entre 1 e 100:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se &lt;code&gt;n&lt;/code&gt; for divisível por 3, retorne &lt;code&gt;Fizz&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Se &lt;code&gt;n&lt;/code&gt; for divisível por 5, retorne &lt;code&gt;Buzz&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Se &lt;code&gt;n&lt;/code&gt; for divisível por 3 e 5 ao mesmo tempo, retorne &lt;code&gt;FizzBuzz&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usarei Java nos exemplos mas pessoas familiarizadas com código devem entender a ideia ainda que não todos os detalhes.&lt;/p&gt;

&lt;p&gt;Estrutura inicial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;fizzBuzz&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O primeiro passo é decidir a lógica de negócio e escrever nossos testes. Vamos seguir o ciclo &lt;em&gt;Red-Green-Refactor&lt;/em&gt;, então o primeiro teste que eu vou escrever é cobrindo a primeira regra, &lt;em&gt;Se &lt;code&gt;n&lt;/code&gt; for divisível por 3, retorne &lt;code&gt;Fizz&lt;/code&gt;&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fizzBuzz_RetornaFizz_QuandoMultiploDe3&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;esperado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;resposta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fizzBuzz&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resposta&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CoreMatchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equalTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;esperado&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao rodar o teste, encontramos o esperado, o teste falha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java.lang.AssertionError: 
Expected: "Fizz"
     but: was ""
Expected :Fizz
Actual   :
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como em nosso código sempre retornamos uma String vazia, precisamos implementar o código necessário para que esse teste passe. Atualizando a função &lt;code&gt;fizzBuzz&lt;/code&gt; mostrada anteriormente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;fizzBuzz&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora, ao rodar o teste novamente, vemos que ele passa. O próximo passo seria fazer um teste para quando &lt;code&gt;n&lt;/code&gt; for divisível por 5 e depois por 3 e 5. Sempre começando por um teste falhando e fazendo ele passar. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gpiress/FizzBuzzTDD" rel="noopener noreferrer"&gt;Cheque aqui&lt;/a&gt; o repositório desse projeto para ver como o código e seus testes ficam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pontos positivos
&lt;/h2&gt;

&lt;p&gt;Depois de seguir o processo, podemos tecer opiniões sobre o ciclo. Primeiro vou escrever o que penso ser bom no processo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pró #1: Primeiro pensar na regra de negócio antes de escrever código&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ao primeiro pensar nos testes, a pessoa desenvolvendo é obrigada a pensar nas regras de negócio, em quais são os casos complicados e se compreenderam o problema. Isso é positivo pois a função do código é satisfazer as regras de negócio, então começar por elas faz sentido.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pró #2: TDD incentiva a escrita de código testável&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por primeiro escrever os testes, o código por consequência fica organizado de uma maneira que é mais fácil de testar. Usando o mesmo problema FizzBuzz como exemplo, seria possível escrever apenas uma função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;resolveTudoEmUm&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa função executa corretamente, mas é difícil de testar unitariamente. Lógico que nesse exemplo de problema simples é fácil de verificar manualmente, mas assim que os problemas se tornam mais complexos, os testes manuais ficam menos confiáveis.&lt;/p&gt;

&lt;p&gt;Código sem teste é código legado, indepedente da "idade", já falei sobre isso em &lt;a href="https://medium.com/@gpiress/trabalhando-com-c%C3%B3digo-legado-sem-enlouquecer-8155b5ec5e8a" rel="noopener noreferrer"&gt;outro post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;TDD pode ser extremamente útil especialmente quando lidando com problemas complexos e para acostumar a escrever código mais testável.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pontos negativos
&lt;/h2&gt;

&lt;p&gt;Muito já foi escrito sobre porque não utilizar TDD e eu vou tentar cobrir os que são mais importantes na minha opinião.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Contra #1: O desenvolvimento fica mais lento&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para qualquer um que tente seguir o ciclo TDD, uma das primeiras impressões é que a técnica parece diminuir muito a velocidade de desenvolvimento, e seguir à risca pode significar muitos ciclos entre escrever um teste de cada vez e o código associado.&lt;/p&gt;

&lt;p&gt;Eu concordo com essa crítica, mas sugiro uma mitigação: para casos óbvios de vários testes, sinta-se à vontade para escrever todos os testes de uma vez e implementar aos poucos. É muito importante manter um ciclo curto entre os testes para garantir o progresso e que nenhum caso deixe de funcionar, mas isso diminui o número de interrupções no processo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Contra #2: TDD não é a única maneira de escrever código testável&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;É possível ter os pontos positivos do TDD - ter código testável e pensar na lógica primeiro - sem ter que seguir o processo do TDD que por vezes é muito &lt;em&gt;baby steps&lt;/em&gt; e cheio de interrupções.&lt;/p&gt;

&lt;p&gt;Esse é o principal motivo pelo qual eu não uso TDD sempre, mas ainda acho o TDD uma técnica muito útil para aumentar o conhecimento sobre como escrever código testável.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Usar TDD influencia positivamente o código gerado, de modo geral o resultado é mais simples de testar e garantir que as regras de negócio são cumpridas. É também muito útil para aprender como escrever código testável.&lt;/p&gt;

&lt;p&gt;Porém é uma técnica que, caso seguida à risca, promove muitas interrupções no fluxo de desenvolvimento, o que pode ser frustrante e diminuir muito a velocidade de desenvolvimento.&lt;/p&gt;

&lt;p&gt;Particularmente, eu acho excelente para novos serviços em que as regras de negócio não estão super definidas e também para parear com pessoas com menos experiência em escrever testes e código testável.&lt;/p&gt;

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