<?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: Júlio Guedes</title>
    <description>The latest articles on Forem by Júlio Guedes (@juliobguedes).</description>
    <link>https://forem.com/juliobguedes</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%2F201700%2Fb6df19d6-2ce1-4400-be1e-49e0d52edfe1.jpeg</url>
      <title>Forem: Júlio Guedes</title>
      <link>https://forem.com/juliobguedes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juliobguedes"/>
    <language>en</language>
    <item>
      <title>Não corra. Pode doer.</title>
      <dc:creator>Júlio Guedes</dc:creator>
      <pubDate>Mon, 12 Jul 2021 17:02:58 +0000</pubDate>
      <link>https://forem.com/opendevufcg/nao-corra-pode-doer-1165</link>
      <guid>https://forem.com/opendevufcg/nao-corra-pode-doer-1165</guid>
      <description>&lt;p&gt;Nós temos um grande potencial dentro de cada um de nós, e muitas vezes escolhemos o curso superior tentando atingir o máximo que somos capazes, e também provar que somos. Experimentamos novas áreas, aprendemos coisas novas, nos dispomos como voluntários, pesquisamos, desenvolvemos e analisamos coisas.&lt;/p&gt;

&lt;p&gt;É engraçado perceber que tudo isso acontece naquele minúsculo espaço, entre nós e o computador. Nós lemos, tentamos, assistimos aulas, perguntamos e, acima de tudo, nos esforçamos. Até conseguirmos. Quantas vezes não repetimos esse ciclo num único dia?&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%2Fmedia0.giphy.com%2Fmedia%2FSTroE7bTBLTzxQUrZc%2Fgiphy.gif" 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%2Fmedia0.giphy.com%2Fmedia%2FSTroE7bTBLTzxQUrZc%2Fgiphy.gif" alt="Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Durante a jornada da graduação, enfrentamos problemas, e começamos a buscar liberdades e alívios. Problemas financeiros, com a família, com amigos, de saúde, entre tantos outros. Alguns veem no estudo e no trabalho uma fuga, já que essa realidade não é confrontada no ambiente profissional ou universitário. Urge a necessidade de se formar, como primeiro passo pra libertação. &lt;/p&gt;

&lt;p&gt;Mas para se formar bem, é preciso experiência, afinal, que empresa legal e que pode pagar um salário bacana iria contratar um recém-formado com currículo em branco? Ainda nos primeiros períodos do curso, surge a necessidade de preencher o currículo com monitorias, pesquisas, projetos e estágios. Mesmo que, a princípio, sejam voluntários. Tudo isso sem baixar as notas.&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%2Fi0.wp.com%2Fwww.incubadoraliberato.com.br%2Fwp-content%2Fuploads%2F2017%2F05%2Fwriting-in-notebook.jpg%3Fssl%3D1" 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%2Fi0.wp.com%2Fwww.incubadoraliberato.com.br%2Fwp-content%2Fuploads%2F2017%2F05%2Fwriting-in-notebook.jpg%3Fssl%3D1" alt="Estudando"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A cada dia que passa, enxergamos o quanto é difícil. Aos poucos se vai abdicando pequenas coisas: assistir um filme com a família, fazer as refeições no mesmo horário, encontrar com os amigos, conversar com eles sobre coisas além da universidade. Seus hobbies se transformam em estudos, já que você ainda não conseguiu o tão sonhado estágio que vai garantir algumas portas abertas depois. A cada mês ou semestre, novas coisas começam a deixadas de lado: dormir bem, praticar exercícios ou esportes, a relação com seus amigos, e até um relacionamento.&lt;/p&gt;

&lt;p&gt;É claro que nessa jornada você conseguiu muita coisa, afinal, nenhum esforço grande assim passa despercebido pelo mundo, principalmente quando você quer ser notado. Você consegue oportunidades em estágios, projetos ou pesquisas, e é exemplar em cada um deles. Então, começa a se questionar porquê não é notado por aqueles que você queria. E aposta mais coisas nessa busca.&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%2Fcdn2.hubspot.net%2Fhubfs%2F419889%2Fblue%2520light%2520computer%2520night%2520negative%2520effects.jpg" 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%2Fcdn2.hubspot.net%2Fhubfs%2F419889%2Fblue%2520light%2520computer%2520night%2520negative%2520effects.jpg" alt="Computador de noite"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não é mais um problema trabalhar e estudar à noite, nos finais de semana e feriados. É o que precisa ser feito. A carga é grande demais pra não fazê-lo. E, diminuindo a carga, você sabe que não chegará onde quer.&lt;/p&gt;

&lt;p&gt;Cada vez é um fator a mais, um estresse a mais, que surge de uma oportunidade boa demais pra negar. E aceitamos a vida assim. Por um ou dois anos, vai valer a pena esse sacrifício. É um investimento no futuro.&lt;/p&gt;

&lt;p&gt;As decepções começam a aparecer, suas expectativas de ser notado continuam não se cumprindo a cada dia, e essa carga de trabalho tão pesada se transforma no seu dia. Você acorda e dorme para cumprir o que acha que os outros esperam de você, adiando a esperança de que vai dar certo. Cada vez mais você acumula rejeições nos estágios dos sonhos. Não desiste de lutar. E meses se passam.&lt;/p&gt;

&lt;p&gt;Até que você quebra.&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%2Fwww.phocuswire.com%2FuploadedImages%2FArticles%2FOpinion%2F2019%2FSeptember%2Fbroken-marketing-funnel.jpg%3Forigwidth%3D800%26origheight%3D400%26origmode%3Dcrop%26Anchor%3DMiddleCenter%26width%3D640%26height%3D480%26scale%3Dboth%26mode%3Dcrop" 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%2Fwww.phocuswire.com%2FuploadedImages%2FArticles%2FOpinion%2F2019%2FSeptember%2Fbroken-marketing-funnel.jpg%3Forigwidth%3D800%26origheight%3D400%26origmode%3Dcrop%26Anchor%3DMiddleCenter%26width%3D640%26height%3D480%26scale%3Dboth%26mode%3Dcrop" alt="Quebrado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você está cansado. Olha para o lado e seus amigos, que antes se divertiam tanto juntos, não estão diariamente ao seu lado. Não estão ao seu lado há algum tempo, e você sequer tinha notado. Você não está satisfeito com seu corpo, sua aparência. Pensa em fazer outra coisa pra desestressar, mas o que fazer? Você deixou seus hobbies pra trás há muito tempo.&lt;/p&gt;

&lt;p&gt;Estar no computador começa a causar dor, e aos poucos você começa a abdicar de algumas das obrigações. Mesmo sem ter alcançado nada do que imaginava ser possível. Sair de um projeto, não se inscrever em mais uma monitoria. Surge o medo de se formar e estar desempregado, seu pior pesadelo.&lt;/p&gt;

&lt;p&gt;Mas existe a possibilidade de continuar na universidade, numa pós graduação, e extender esse tempo de se decidir. Com suas notas e seus esforços, deve ser possível. Mas foi pra isso que você lutou tanto? Pra continuar no mesmo lugar que você está? Sabendo que uma vez ouviu que "a pós-graduação é onde ficam aqueles que não conseguem um emprego"?&lt;/p&gt;

&lt;p&gt;Você sabe que isso não é verdade. Mas você correu demais. Esqueceu de aproveitar a graduação. Viver o dia a dia de um projeto, de uma monitoria. Divertir-se com seus amigos, ao invés de tentar agarrar o mundo com seus braços. Esqueceu de cursar uma disciplina e conversar com o professor após a aula, sobre como aquele conteúdo se aplica num problema, mesmo que você não fosse fazê-lo. Sua curiosidade e seu interesse sumiram, pois não havia mais tempo para novas coisas. &lt;/p&gt;

&lt;p&gt;Aos poucos, você foi murchando. E, só agora, percebeu que estava murcho.&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%2Flive.staticflickr.com%2F4683%2F39355517851_0353a16705_b.jpg" 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%2Flive.staticflickr.com%2F4683%2F39355517851_0353a16705_b.jpg" alt="Flor murcha"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não é possível voltar no tempo e reparar tudo, você sabe muito bem. Mas sempre é possível reconsiderar o que está fazendo agora, ponderar melhor e entender suas prioridades. Saúde, tempo, amigos, rir, sorrir, brincar. Assistir um filme ruim só pra dizer que é ruim mesmo, e então rir com seus amigos por vocês terem escolhido passar por isso. Se reaproximar daqueles que importam, das coisas que te faziam sorrir.&lt;/p&gt;

&lt;p&gt;A relação com o seu trabalho e seus estudos precisa ser saudável pra dar certo, afinal, você escolheu tudo isso por gostar. Mas sua vida não se resume a um emprego, um título, um trabalho. Escolher esse caminho pode te isolar. Pode doer.&lt;/p&gt;

&lt;p&gt;Pare, pense, reflita.&lt;br&gt;
Sempre.&lt;br&gt;
Para só então saber como continuar.&lt;/p&gt;

</description>
      <category>ptbr</category>
      <category>motivation</category>
      <category>career</category>
    </item>
    <item>
      <title>Análise de Dados para Iniciantes em Python: Parte 1</title>
      <dc:creator>Júlio Guedes</dc:creator>
      <pubDate>Thu, 07 May 2020 19:16:18 +0000</pubDate>
      <link>https://forem.com/juliobguedes/analise-de-dados-para-iniciantes-em-python-parte-1-3g1b</link>
      <guid>https://forem.com/juliobguedes/analise-de-dados-para-iniciantes-em-python-parte-1-3g1b</guid>
      <description>&lt;p&gt;Este post foi feito em parceria com o &lt;a href="http://colaboradados.com.br/" rel="noopener noreferrer"&gt;Colabora Dados&lt;/a&gt;, e você pode conferir o post original &lt;a href="http://colaboradados.com.br/blogposts/analise-de-dados-em-pytho-pt1.html" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A análise de dados é um conjunto de técnicas que permite extrair informação sobre um conjunto de dados. Achou muito técnico? Podemos entender isso como uma forma de &lt;strong&gt;conhecer melhor os dados que temos&lt;/strong&gt;. Caso queira se aprofundar mais nos termos, &lt;a href="https://dev.to/opendevufcg/introducao-a-ciencia-de-dados-n4c"&gt;esse post introduz bem o que é ciência de dados&lt;/a&gt; e suas áreas.&lt;/p&gt;

&lt;p&gt;Os tópicos que serão abordados neste post são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Python

&lt;ul&gt;
&lt;li&gt;O que é&lt;/li&gt;
&lt;li&gt;Como instalar&lt;/li&gt;
&lt;li&gt;Como executar um programa&lt;/li&gt;
&lt;li&gt;Como usar Python online&lt;/li&gt;
&lt;li&gt;Bibliotecas&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sintaxe&lt;/li&gt;
&lt;li&gt;Conjunto de dados = Tabelas!&lt;/li&gt;
&lt;li&gt;Abrindo tabelas em Python&lt;/li&gt;
&lt;li&gt;Primeira Visualização&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Python
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O que é
&lt;/h3&gt;

&lt;p&gt;Como você já deve ter imaginado, Python é uma &lt;strong&gt;Linguagem de Programação&lt;/strong&gt; de propósito geral. Isso quer dizer que diferentemente de outras linguagens, Python pode ser utilizado para diversos propósitos, dependendo do seu objetivo. Alguns possíveis são: criar e manter um site, fazer análises de dados ou até mesmo criar um programa que identifica se uma foto é de um cachorro ou um gato.&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%2Fstorage.googleapis.com%2Fkaggle-competitions%2Fkaggle%2F3362%2Fmedia%2Fwoof_meow.jpg" 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%2Fstorage.googleapis.com%2Fkaggle-competitions%2Fkaggle%2F3362%2Fmedia%2Fwoof_meow.jpg" alt="Cats vs Dogs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Como instalar
&lt;/h3&gt;

&lt;p&gt;Esta seção do tutorial só é importante se você está usando o sistema operacional Windows. Se você usa alguma distribuição Linux ou MacOS, o Python já está instalado.&lt;/p&gt;

&lt;p&gt;Nota rápida: caso você não queira instalar o Python neste momento, siga para a próxima seção.&lt;/p&gt;

&lt;p&gt;No &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;site oficial do Python&lt;/a&gt;, você pode encontrar uma aba para downloads. Nessa aba, queremos baixar a versão &lt;em&gt;3.6.10&lt;/em&gt;. Durante a instalação, marque a opção &lt;strong&gt;Add Python 3.6.10 to PATH&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como executar um programa
&lt;/h3&gt;

&lt;p&gt;Caso você use Windows deverá abrir o o cmd. Se usa Linux ou MacOS abra o terminal. Nesse tutorial, a única diferença é o comando para listar os arquivos e pastas: no Windows, use o comando &lt;em&gt;"dir"&lt;/em&gt; para listar, enquanto nos outros, use o comando &lt;em&gt;"ls"&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Para acessar uma subpasta, use o comando &lt;em&gt;"cd nome_da_pasta"&lt;/em&gt;. Por exemplo: se você está na pasta Documentos e quer entrar na pasta códigos, use o comando &lt;em&gt;"cd codigos"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Para garantir que o Python está instalado, execute &lt;em&gt;"python"&lt;/em&gt; na linha de comando, ou &lt;em&gt;"python3"&lt;/em&gt; se você está usando Linux. Você verá algo semelhante a imagem abaixo:&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%2Fpanda.ime.usp.br%2Fpensepy%2Fstatic%2Fpensepy%2F_images%2Fpython_shell.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%2Fpanda.ime.usp.br%2Fpensepy%2Fstatic%2Fpensepy%2F_images%2Fpython_shell.png" alt="Python Shell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O lugar mágico que você acabou de acessar chama-se &lt;strong&gt;shell do Python&lt;/strong&gt;. É uma linha de comando para executar comandos em Python. Ele serve pra calcular alguma coisa e também testar comandos. Para sair dele, execute o comando &lt;em&gt;"exit()"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Quando você tiver escrito um programa em Python, precisará entrar na pasta onde o arquivo está e depois usar o comando &lt;em&gt;"python nome_do_arquivo.py"&lt;/em&gt; para executá-lo. O arquivo de um programa é exatamente igual a um arquivo de texto (um .txt), mas o salvamos com a extensão &lt;strong&gt;.py&lt;/strong&gt; para representar que é um arquivo de texto Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como usar Python online
&lt;/h3&gt;

&lt;p&gt;Se você escolheu executar online, há alternativas para utilizar Python, como o &lt;strong&gt;Google Colab&lt;/strong&gt;. Para acessar, basta entrar na sua conta Google (Gmail), e abrir o seu Google Drive. Nas opções para a criação de documentos, clique em exibir mais opções e você encontrará a opção &lt;strong&gt;Google Colaboratory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O Google Colab funciona em modo &lt;strong&gt;notebook&lt;/strong&gt; (ou &lt;strong&gt;jupyter notebook&lt;/strong&gt;). Se você já programou em R, é equivalente a R markdown. Num notebook, é possível adicionar textos ou códigos.&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%2Fthumbor.forbes.com%2Fthumbor%2F960x0%2Fhttps%253A%252F%252Fblogs-images.forbes.com%252Fgregoryferenstein%252Ffiles%252F2019%252F08%252Fscreenshot-1200x688.jpg" 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%2Fthumbor.forbes.com%2Fthumbor%2F960x0%2Fhttps%253A%252F%252Fblogs-images.forbes.com%252Fgregoryferenstein%252Ffiles%252F2019%252F08%252Fscreenshot-1200x688.jpg" alt="Google Colab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como é possível ver acima, existem trechos de texto em fundo branco, e trechos de código em fundo cinza. Caso queira usar notebooks no seu computador, é possível usando Jupyter. Você pode encontrar mais informações sobre isso neste &lt;a href="https://jupyter.org/install" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliotecas
&lt;/h3&gt;

&lt;p&gt;No contexto de programação, bibliotecas contém o código que já foi escrito por alguém e nos permite executar funcionalidades específicas já prontas.&lt;/p&gt;

&lt;p&gt;Bibliotecas usualmente utilizadas na análise de dados são: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NumPy, que permite fazer operações matemáticas mais avançadas; &lt;/li&gt;
&lt;li&gt;Pandas, que permite ler arquivos de dados mais facilmente; e &lt;/li&gt;
&lt;li&gt;MatPlotLib, que permite gerar visualizações dos dados em gráficos de barras, boxplots, e outros tipos de gráficos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Após a instalação local do Python, utilizaremos o pip (&lt;em&gt;Package Installer for Python&lt;/em&gt;). O pip é o gerenciador de pacotes (bibliotecas) do Python. Utilize o comando abaixo para instalar o NumPy, Pandas e MatPlotLib:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;numpy pandas matplotlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Sintaxe
&lt;/h2&gt;

&lt;p&gt;Inicialmente, é necessário entender o conceito de &lt;strong&gt;variável&lt;/strong&gt;. Uma variável é utilizada para armazenar um valor durante a execução do programa. A sintaxe segue o seguinte formato:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;nome_da_variavel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O "=" é chamado de atribuição.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As variáveis podem ser utilizadas também em expressões, veja a expressão aritmética abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dobro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima não foi necessário utilizar o &lt;code&gt;21&lt;/code&gt; novamente, pois seu valor estava armazenado na variável. Outro exemplo onde armazena-se um nome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Júlio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entre os exemplos anteriores, há uma diferença sutil: o uso das aspas. Isso faz a distinção de fierentes tipos de dados. Os tipos mais  simples (denominados &lt;strong&gt;tipos literais&lt;/strong&gt;) são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;String&lt;/strong&gt;: é um dado que se refere uma sequência de caracteres. Por exemplo: &lt;code&gt;nome = "Júlio"&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Int&lt;/strong&gt;: é um dado numérico que não tem valor decimal. Por exemplo: &lt;code&gt;idade = 21&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Float&lt;/strong&gt;: é um dado numérico que possui valor decimal. Por exemplo:
&lt;code&gt;altura = 1.83&lt;/code&gt;. Para valores decimais utiliza-se o ponto, e não a vírgula.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A medida que você se aprofundar, será possível encontrar tipos mais avançados de dados, inclusive criar seus próprios tipos de dados. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conjunto de dados = Tabelas?
&lt;/h2&gt;

&lt;p&gt;Após a breve explicação sobre variáveis e os tipos mais básicos de dados, o próximo passo é usar dados existentes nos programas.&lt;/p&gt;

&lt;p&gt;Na análise de dados não tratamos o tipo do dado apenas como o tipo de uma variável. Entende-se que os conjuntos de dados assumem alguns tipos diferentes: dados tabulares (Excel, CSV, etc), imagens, vídeos, pdfs ou docs, páginas da internet, entre outros. Dependendo da análise, o dado pode tomar diferentes formas: um tweet, uma foto, um e-mail, entre outros.&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%2Fmiro.medium.com%2Fmax%2F530%2F1%2AVAjYygFUinnygIx9eVCrQQ.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%2Fmiro.medium.com%2Fmax%2F530%2F1%2AVAjYygFUinnygIx9eVCrQQ.png" alt="mnist"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No decorrer deste tutorial, usaremos tabelas para representar os dados que temos interesse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abrindo tabelas em Python
&lt;/h2&gt;

&lt;p&gt;Usaremos como conjunto de dados os valores da Cota para o Exercício da Atividade Parlamentar (CEAP). Você pode ler mais sobre o que é a CEAP &lt;a href="https://www2.camara.leg.br/transparencia/acesso-a-informacao/copy_of_perguntas-frequentes/cota-para-o-exercicio-da-atividade-parlamentar" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;, mas pode-se resumir como um auxílio financeiro para os deputados para gastos com hotelaria, transporte, passagens, etc. Você pode baixar a tabela &lt;em&gt;dadosCEAP1.csv&lt;/em&gt; &lt;a href="https://raw.githubusercontent.com/juliobguedes/predictive-data-science/master/lab1/datasets/dadosCEAP1.csv" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para abrir uma tabela, podemos usar a biblioteca Pandas. O código que precisamos escrever para incluir a biblioteca é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A linha acima torna as funcionalidades existentes na biblioteca Pandas para o nosso código através da variável &lt;em&gt;pd&lt;/em&gt;. Em seguida, podemos abrir a tabela:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tabela&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dadosCEAP1.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para visualizar nossa tabela, podemos usar o comando &lt;em&gt;.head()&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tabela&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso nos permite ver as cinco primeiras linhas da nossa tabela para entendermos melhor os dados que estamos lidando. Se você tiver executando na linha de comando, será algo como:&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%2Fi.imgur.com%2FE849hBx.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%2Fi.imgur.com%2FE849hBx.png" alt="tabela head cli"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso esteja executando em um notebook, será assim:&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%2Fi.imgur.com%2FmLBdjWP.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%2Fi.imgur.com%2FmLBdjWP.png" alt="tabela head"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que abrimos a nossa tabela com Python, podemos fazer diversas coisas, incluindo visualizar os dados. &lt;/p&gt;

&lt;h2&gt;
  
  
  Primeira Visualização
&lt;/h2&gt;

&lt;p&gt;Um dos gráficos mais simples que podemos gerar é um histograma. Uma variável interessante para analisar é o valor gasto, que está presente na tabela na coluna &lt;em&gt;valorLíquido&lt;/em&gt;. Quando pensamos nas perguntas: "Quantos reembolsos foram pedidos até o valor de cinco mil reais? E entre cinco e dez mil reais?", podemos respondê-las usando um histograma.&lt;/p&gt;

&lt;p&gt;Para gerar o histograma, usaremos a biblioteca &lt;em&gt;matplotlib&lt;/em&gt;, mais especificamente a função &lt;em&gt;pyplot&lt;/em&gt; que existe nessa biblioteca. Novamente, importamos a biblioteca com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;matplotlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acima, estamos importando apenas a função &lt;em&gt;pyplot&lt;/em&gt; da biblioteca inteira e colocando essa função na variável &lt;em&gt;plt&lt;/em&gt;. Anteriormente importamos a biblioteca Pandas por completo, mas apenas utilizamos a função &lt;em&gt;read_csv&lt;/em&gt;. poderíamos também ter feito isso através do comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;read_csv&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;abre_csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abrindo dessa forma, ao invés de abrir o csv utilizando &lt;em&gt;pd.read_csv&lt;/em&gt;, usamos &lt;em&gt;abre_csv&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Continuando com o código para gerar nosso histograma, podemos declarar o início de uma nova figura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, geramos o histograma da coluna valorLíquido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tabela&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;valorLíquido&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acima, a coluna da tabela foi acessada usando colchetes e colocando o nome da coluna dentro, &lt;em&gt;tabela['valorLíquido']&lt;/em&gt;. Por fim, podemos salvar nosso gráfico como uma imagem png usando o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;savefig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;histograma.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao abrir, teremos o gráfico:&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%2Fi.imgur.com%2FwooSP9w.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%2Fi.imgur.com%2FwooSP9w.png" alt="plot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pelo gráfico, entendemos que mais de 500 mil reembolsos foram pedidos com o valor até 25 mil reais. Ainda assim, observando a extensão do eixo X, observa-se que há pelo menos um reembolso com valor próximo a 175 mil.&lt;/p&gt;




&lt;p&gt;Na próxima parte do tutorial, abordaremos tópicos mais avançadas que podemos fazer usando apenas essas bibliotecas, e assim entender ainda mais o nosso conjunto de dados.&lt;/p&gt;

&lt;p&gt;Agradeço a leitura, e fique a vontade para ler mais textos na minha página do &lt;a href="https://medium.com/@juliobguedes" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; e na minha página do &lt;a href="https://dev.to/juliobguedes"&gt;Dev.to&lt;/a&gt;. Se quiser entrar em contato, &lt;a href="https://twitter.com/juliobguedes" rel="noopener noreferrer"&gt;@juliobguedes&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ptbr</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Entendendo JavaScript: Promises</title>
      <dc:creator>Júlio Guedes</dc:creator>
      <pubDate>Tue, 17 Sep 2019 17:13:46 +0000</pubDate>
      <link>https://forem.com/juliobguedes/entendendo-javascript-promises-4hep</link>
      <guid>https://forem.com/juliobguedes/entendendo-javascript-promises-4hep</guid>
      <description>&lt;p&gt;No início da programação em JavaScript as coisas geralmente vão bem: é fácil entender a sintaxe da linguagem e assimilar a outras linguagens popularmente conhecidas, como Python e Java. Ao entrar mais a fundo nas possibilidades de implementação com JavaScript, surge o "bicho papão" para todo iniciante: as Promises.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/gh6emBSF3auzxzQamc/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/gh6emBSF3auzxzQamc/giphy.gif" alt="Bicho Papão"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entretanto, embora pareçam assustadoras, as Promises são essenciais enquanto programando JavaScript e, com um pouco de prática, passam a ser rotina. Neste post, discutiremos o que são Promises, como utilizá-las, além de um plus pro async/await.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antes de tudo, assíncrono
&lt;/h2&gt;

&lt;p&gt;Diferente de algumas outras linguagens, como Python e Java, JavaScript permite a programação de forma &lt;strong&gt;assíncrona&lt;/strong&gt;, isto é, as linhas de código de uma função podem não ser executadas uma após a outra: as linhas 1, 2 e 3 serem executadas uma após a outra não é garantia de que a linha 4 será a próxima a ser executada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/tn8zWeNYA73G0/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/tn8zWeNYA73G0/source.gif" alt="Síncrono vs Assíncrono"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetch
&lt;/h2&gt;

&lt;p&gt;Durante o restante desse tutorial utilizaremos o &lt;code&gt;fetch&lt;/code&gt; como base para os exemplos. Agora nativo no JavaScript, a API do fetch nos permite fazer requisições HTTP sem utilizar libs externas. Sumarizando bastante, as requisições são pedidos de informação de fontes externas à nossa aplicação, seja de um servidor, uma API, ou outras fontes, e o &lt;code&gt;fetch&lt;/code&gt; será a função que nos permite solicitar essa informação no nosso código. &lt;/p&gt;

&lt;p&gt;Além do &lt;code&gt;fetch&lt;/code&gt;, existem libs que permitem fazer requisições HTTP: um exemplo forte na comunidade é a &lt;a href="https://github.com/axios/axios/" rel="noopener noreferrer"&gt;axios&lt;/a&gt;. Alguns frameworks, como o Angular.js, possuem funções internas (&lt;a href="https://docs.angularjs.org/api/ng/service/$http" rel="noopener noreferrer"&gt;$http&lt;/a&gt;, no caso do Angular.js) que permitem fazer essas requisições.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são Promises?
&lt;/h2&gt;

&lt;p&gt;Agora sim, Promises. Como explicado na sessão anterior, as requisições buscam informação em fontes externas. Entretanto, o nome &lt;em&gt;fetch&lt;/em&gt; não foi escolhido ao acaso: pedir informação de uma fonte externa é como jogar uma bola para o cachorro ir buscar — em inglês, a expressão &lt;em&gt;go fetch&lt;/em&gt; é usada no lugar do &lt;strong&gt;pega&lt;/strong&gt;, que é geralmente usado aqui no Brasil — mas, assim como o cachorro demora para trazer a bola de volta, a informação também demora a chegar do servidor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/klPeFHrWqzPDW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/klPeFHrWqzPDW/giphy.gif" alt="Go fetch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas, JavaScript é assíncrono: se a linha 3 demorar demais, como impedir que a linha 4 execute? As Promises surgem então nesse contexto: no nosso código, uma Promise (promessa, em português) serve para impedir que a linha 4 execute antes da linha 3, pois era necessária a informação adquirida na linha 3 antes de executar a linha 4. A semântica básica das promises é &lt;code&gt;do this ... then do that&lt;/code&gt; — &lt;code&gt;faça isso ... depois faça aquilo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Infelizmente, assim como na vida real, nem toda promessa é cumprida, e precisamos nos precaver para esse tipo de situação. A semântica, nesse caso, lembra um pouco o &lt;code&gt;try catch&lt;/code&gt; de Java: se não é possível recuperar a informação ou houve erro no código do &lt;code&gt;then&lt;/code&gt;, caímos num &lt;code&gt;catch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fboygeniusreport.files.wordpress.com%2F2016%2F11%2Fobama-trump-finger-cross-photoshop.jpg%3Fquality%3D98%26strip%3Dall" 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%2Fboygeniusreport.files.wordpress.com%2F2016%2F11%2Fobama-trump-finger-cross-photoshop.jpg%3Fquality%3D98%26strip%3Dall" alt="Quebrando promessas"&gt;&lt;/a&gt;&lt;br&gt;Obama cruzando os dedos: Promises também podem ser quebradas! Disclaimer: essa foto é uma montagem
  &lt;/p&gt;

&lt;p&gt;Mesmo que o código dentro do nosso &lt;code&gt;then&lt;/code&gt; não cause erros, erros lançados pelo servidor e erros na comunicação precisam ser tratados, por exemplo: quando o serviço externo no qual se está buscando a informação não está online, nossa requisição gera um erro de &lt;em&gt;timeout&lt;/em&gt;; se não estamos conectados à internet no momento em que a requisição é feita, nossa requisição gera um erro de &lt;em&gt;network&lt;/em&gt;. Detalhes como esse precisam ser tratados, e muitas vezes é isso que transforma as promises em algo delicado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos de Promise
&lt;/h2&gt;

&lt;p&gt;Para fins de exemplo, nosso serviço externo será o &lt;a href="https://laguinho.opendevufcg.org/" rel="noopener noreferrer"&gt;Laguinho&lt;/a&gt; da &lt;a href="https://github.com/OpenDevUFCG" rel="noopener noreferrer"&gt;OpenDevUFCG&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Quando fizermos uma requisição &lt;strong&gt;GET&lt;/strong&gt; para o Laguinho, ele deve nos retornar &lt;code&gt;{"status":"running"}&lt;/code&gt;. Assim, utilizando o fetch, vejamos o código necessário para fazer essa requisição:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://laguinho.opendevufcg.org/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resposta:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando executamos o código acima, o &lt;code&gt;console.log&lt;/code&gt; nos retorna um objeto do tipo &lt;code&gt;Promise&lt;/code&gt;, e não o objeto com o status, que deveria ser o retorno. Vamos aplicar a semântica de promises ao código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://laguinho.opendevufcg.org/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resposta:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resposta&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;Temos então um objeto do tipo &lt;code&gt;Response&lt;/code&gt;, e a partir dele é possível obter os dados da resposta dada pelo serviço externo. Já que o Laguinho nos retorna um objeto em JSON, aplicaremos a função &lt;code&gt;json&lt;/code&gt; na resposta para obter os dados. Note que a função &lt;code&gt;json&lt;/code&gt; também é uma promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://laguinho.opendevufcg.org/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resposta:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;respostaDoServidor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resposta do Servidor:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;respostaDoServidor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Até agora, todos os nossos casos funcionam. Mas, e se houvéssemos escrito a url incorreta? Como provavelmente não haveria um servidor que se comunica utilizando JSON na url que (por exemplo) trocamos uma letra, a requisição iria falhar. Nesse caso, precisamos de um catch, para impedir que seja lançada uma exceção, e podermos tratar de acordo. Vejamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://laguinoh.opendevufcg.org/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resposta:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;respostaDoServidor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resposta do Servidor:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;respostaDoServidor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Aconteceu um erro durante a requisição:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;erro&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;Agora você já deve ter entendido o que são promises, como elas aparecem no seu código, e como lidar com elas. Mas, em termos de legibilidade de código, ainda há um problema: se existem diversas promises que estão uma dentro da outra, torna-se muito difícil entender o fluxo de execução. Vejamos então uma forma diferente de escrever Promises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plus: Async/Await
&lt;/h2&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%2Fgithub.com%2FboyEstrogen%2FAnime-Girls-Holding-Programming-Books%2Fblob%2Fmaster%2FJavascript%2FDoma_Umaru_Java_Script_The_Good_Parts.png%3Fraw%3Dtrue" 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%2Fgithub.com%2FboyEstrogen%2FAnime-Girls-Holding-Programming-Books%2Fblob%2Fmaster%2FJavascript%2FDoma_Umaru_Java_Script_The_Good_Parts.png%3Fraw%3Dtrue" alt="Os mimos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, os mimos. Async/await é uma forma sensacional e bastante legível de escrever Promises, pois além de não ser verborrágica, não torna o código ilegível, seja pelo fluxo ou pelas indentações, mas é necessário encapsular o código em uma função. Vejamos os códigos anteriores quando escrito usando async/await:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://laguinho.opendevufcg.org/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fluxo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;respostaServidor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resposta do servidor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;respostaServidor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Aconteceu um erro durante a requisição:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que, não importa em que linha de código o erro aconteceu, ele sempre cairá no bloco do &lt;code&gt;catch&lt;/code&gt;. Se você não gostou da ideia de ter um bloco &lt;code&gt;try/catch&lt;/code&gt; no seu código, saiba que você não é o único: eu costumo escrever as promises utilizando uma mistura dos dois estilos, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://laguinho.opendevufcg.org/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fluxo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Erro no fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;respostaServidor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Erro no .json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resposta do servidor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;respostaServidor&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;Async/Await está se tornando cada vez mais popular, mas o estilo não agrada a todos: fica a seu critério decidir entre usar ou não :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Chegamos ao fim desse post... :(
&lt;/h2&gt;

&lt;p&gt;Agradeço bastante pela leitura e sinta-se à vontade para tirar quaisquer dúvidas que ainda existam. Se esse tutorial foi útil, dá uma olhada no meu &lt;a href="https://dev.to/opendevufcg/testes-em-javascript-conceitos-iniciais-1okj"&gt;outro post&lt;/a&gt;, introduzindo conceitos de teste em JavaScript.&lt;/p&gt;

&lt;p&gt;Caso queira entrar em contato, só mandar um &lt;a href="https://twitter.com/juliobguedes" rel="noopener noreferrer"&gt;Tweet&lt;/a&gt;! Te convido a continuar lendo textos meus, confere meu &lt;a href="https://medium.com/@Juliobguedes/" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se estiver buscando posts sobre programação em Português, te recomendo dar uma olhada no conteúdo do &lt;a href="https://dev.to/opendevufcg"&gt;OpenDevUFCG&lt;/a&gt;. Se curtir desenvolvimento OpenSource, aproveita e dá uma olhada no &lt;a href="https://github.com/opendevufcg" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; também!&lt;/p&gt;

</description>
      <category>ptbr</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Testes em JavaScript: Conceitos iniciais</title>
      <dc:creator>Júlio Guedes</dc:creator>
      <pubDate>Sat, 07 Sep 2019 21:51:15 +0000</pubDate>
      <link>https://forem.com/opendevufcg/testes-em-javascript-conceitos-iniciais-1okj</link>
      <guid>https://forem.com/opendevufcg/testes-em-javascript-conceitos-iniciais-1okj</guid>
      <description>&lt;p&gt;Diferentemente do que muitos pensam, o desenvolvimento de uma aplicação Web ou Mobile necessita de testes, seja para assegurar a qualidade do produto, o funcionamento, e até mesmo a aparência, durante a evolução do código.&lt;br&gt;
Quando nosso software está bem consolidado em termos de testes, podemos estabelecer estratégias de integração e deploy contínuos (CI/CD). Esses métodos atuam para garantir que nossa aplicação não tenha sofrido efeitos colaterais com as adições, modificações e correções que estarão sendo enviadas à branch principal para deploy. Nesse post, serão introduzidos os conceitos de &lt;strong&gt;Spies&lt;/strong&gt; e &lt;strong&gt;Stubs&lt;/strong&gt;, e como eles são úteis durante o desenvolvimento de um conjunto de testes de unidade.&lt;/p&gt;
&lt;h1&gt;
  
  
  Teste de Unidade
&lt;/h1&gt;

&lt;p&gt;Vamos supor o seguinte cenário: temos uma aplicação que requer o cadastro dos seus usuários com um &lt;em&gt;username&lt;/em&gt;, que deve ter tamanho de pelo menos 3 caracteres. Para tal, podemos adicionar no código de cadastro uma verificação para o tamanho do username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cadastrar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;senha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O username necessita de pelo menos 3 caracteres&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="c1"&gt;// Continua o cadastro&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando escrevemos testes para a função de cadastro, nossa intenção seria testar diferentes casos, escolhendo &lt;strong&gt;valores limite&lt;/strong&gt;, para podermos testar a qualidade da nossa verificação e se estamos deixando passar algum cenário indesejado. Por enquanto, não vamos nos importar tanto com a sintaxe, mas na semântica:&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testes da função de cadastro&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa um username válido&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;cadastrar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="cm"&gt;/* Nesse caso, espera-se que não seja lançado um erro,
     * visto que o username tem três ou mais caracteres
     */&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa um username invalido&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;cadastrar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;te&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O username necessita de pelo menos 3 caracteres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="cm"&gt;/* Nesse outro caso, como o username tem menos de 3 caracteres,
     * espera-se que seja lançado um erro com a mensagem descrita
     */&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// testes de senha, e outros fluxos do cadastro&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse caso, estamos testando apenas a função de cadastro, ou seja, um teste unitário que testa apenas uma "unidade básica" do sistema (entenda unidade básica como aquela unidade que não chama outras funções internamente). De agora em diante, a ideia é termos funções mais complicadas que isso, ou seja, funções que precisam chamar outras funções na sua execução, por envolverem lógicas mais complexas.&lt;/p&gt;

&lt;h1&gt;
  
  
  Spies
&lt;/h1&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%2Fpbs.twimg.com%2Fprofile_images%2F951185073402994688%2FpKyQmqYh.jpg" 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%2Fpbs.twimg.com%2Fprofile_images%2F951185073402994688%2FpKyQmqYh.jpg" alt="Spies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine agora que, uma vez cadastrado, também seja possível alterar esse &lt;em&gt;username&lt;/em&gt;. Temos, então, duas situações possíveis em que desejamos verificar se o que o usuário inseriu é válido. Para isso, podemos refatorar nosso código atual de maneira a reutilizar as linhas que verificam se o &lt;em&gt;username&lt;/em&gt; está no padrão correto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verificaUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O username necessita de pelo menos 3 caracteres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cadastrar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;senha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;verificaUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Continua o cadastro&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com o código refatorado, é também preciso refatorar os testes, para que se adequem ao contexto real do código:&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testes da função de cadastro&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa um username válido&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verificaUsername&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;cadastrar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;throw&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="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa um username invalido&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verificaUsername&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;cadastrar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;te&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O username necessita de pelo menos 3 caracteres&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// testes de senha, e outros fluxos do cadastro&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora que já vimos como os spies são declarados e verificados, é mais fácil entender seu significado: um spy serve para verificar se uma função foi chamada ou não durante a execução de outra função. No nosso exemplo, pedimos para que o sinon (a biblioteca de testes que estamos usando) "espie" o método &lt;code&gt;verificaUsername&lt;/code&gt; e, após a chamada para a execução de &lt;code&gt;cadastrar&lt;/code&gt;, verificamos se &lt;code&gt;verificaUsername&lt;/code&gt; foi chamada. &lt;/p&gt;

&lt;p&gt;Entretanto, existe uma particularidade importante a se notar no nosso código: quando testamos um username inválido, a exceção ainda é lançada. Isso nos faz notar que nosso spy não modifica nada no código em execução, apenas verifica se as chamadas internas a uma função são realmente chamadas.&lt;/p&gt;

&lt;h1&gt;
  
  
  Stubs
&lt;/h1&gt;

&lt;p&gt;Mudando um pouco a perspectiva dentro do sistema que estamos construindo, podemos pensar num sistema mais complexo e que funciona numa certa sequência de operações e, para executar a operação seguinte, a anterior precisa ter sido executada corretamente. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;operacaoComplexa&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;operacaoMenor&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resposta&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resposta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;param&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&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;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;erro&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função acima não parece ter uma lógica nem um motivo bem definidos, como é o caso da função de cadastro. Entretanto, não é esse o ponto em que precisamos focar: podemos ver que o retorno da &lt;code&gt;operacaoMenor&lt;/code&gt; é importante para entendermos o que será retornado nessa função, seja em caso de sucesso ou em caso de erro. Consideremos então que, por exemplo, essa função menor faz uma requisição a um serviço externo, uma API por exemplo.&lt;/p&gt;

&lt;p&gt;Na execução do nosso código, o código dessa função executará normalmente, fazendo a requisição necessária. Durante os testes, entretanto, não se deve fazer uma chamada à API, já que a API pode alterar dados reais da aplicação, deixar o banco de dados inconsistente e causar muitos outros problemas. Precisamos então de uma forma para testar a operação complexa sem realmente executar o código de &lt;code&gt;operacaoMenor&lt;/code&gt;, e para isso servem os &lt;strong&gt;stubs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi0.wp.com%2Fyukaichou.com%2Fwp-content%2Fuploads%2F2014%2F10%2FGamification-vs-Manipulation-image.jpg%3Fresize%3D600%252C375%26ssl%3D1" 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%2Fi0.wp.com%2Fyukaichou.com%2Fwp-content%2Fuploads%2F2014%2F10%2FGamification-vs-Manipulation-image.jpg%3Fresize%3D600%252C375%26ssl%3D1" alt="Stubs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então, o que exatamente um Stub faz? Durante a execução dos nossos testes, um stub substitui uma função existente no código por uma função representativa, na qual é possível controlar o seu retorno. Através desse controle, o restante do código pode executar normalmente e é possível percorrer todos os cenários da execução do programa durante os testes, manipulando o retorno do stub conforme adequado. Vejamos como seria a aplicação de um stub no código dessa função:&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa operacaoComplexa&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa cenario 1 do then&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operacaoMenor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolves&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;param&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;retornoComplexo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;operacaoComplexa&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="nx"&gt;retornoComplexo&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* retorno no caso 1 */&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="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa cenario 2 do then&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operacaoMenor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolves&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;param&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;retornoComplexo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;operacaoComplexa&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="nx"&gt;retornoComplexo&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* retorno no caso 2 */&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="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testa cenario catch&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operacaoMenor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rejects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mensagem de erro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;operacaoComplexa&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Operação não deveria ter dado certo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;erro&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="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mensagem de erro&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O teste acima verifica os três cenários que colocamos no código da nossa função. O teste parece ser grande, mas cobre apenas os três fluxos básicos na execução da &lt;code&gt;operacaoComplexa&lt;/code&gt;. Explicando em alto nível a sintaxe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no caso 1, estamos dizendo que a &lt;code&gt;operacaoMenor&lt;/code&gt; deve ser um stub que resolve, no retorno da Promise, um objeto &lt;code&gt;{ param: true }&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;no caso 2, estamos dizendo que a &lt;code&gt;operacaoMenor&lt;/code&gt; deve ser um stub que resolve, no retorno da Promise, um objeto &lt;code&gt;{ param: false }&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;no caso 3, de erro, estamos dizendo que a &lt;code&gt;operacaoMenor&lt;/code&gt; deve ser um stub que rejeita, no retorno da Promise, sendo &lt;code&gt;'mensagem de erro'&lt;/code&gt; a string retornada no erro.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nesse caso específico, nossa função complexa tinha uma chamada assíncrona (uma Promise) e, por isso, utilizamos &lt;code&gt;resolves&lt;/code&gt; e &lt;code&gt;rejects&lt;/code&gt; no nosso stub; caso fosse uma função síncrona, poderíamos ter utilizado &lt;code&gt;returns&lt;/code&gt; normalmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plus!
&lt;/h2&gt;

&lt;p&gt;Existem diversas bibliotecas que podem ser utilizadas para testes em JavaScript. Algumas das mais famosas são &lt;a href="https://mochajs.org/#getting-started" rel="noopener noreferrer"&gt;Mocha&lt;/a&gt;, &lt;a href="https://sinonjs.org" rel="noopener noreferrer"&gt;Sinon&lt;/a&gt; e &lt;a href="https://chaijs.com" rel="noopener noreferrer"&gt;Chai&lt;/a&gt;, que geralmente são utilizados em conjunto. Atualmente, uma das bibliotecas que está sendo bastante visada é o &lt;a href="https://jestjs.io" rel="noopener noreferrer"&gt;Jest&lt;/a&gt;. Se você está pensando em como começar a aplicar o que aprendeu aqui, te sugiro fazer alguns testes simples num dos sites que você hospeda no GitHub Pages — um portfolio, um pequeno projeto de disciplina, quem sabe? Qualquer um desses vai te dar um bom contato inicial :).&lt;/p&gt;

&lt;h2&gt;
  
  
  Chegamos ao fim desse post... :(
&lt;/h2&gt;

&lt;p&gt;Mas não se preocupe, há muito mais conteúdo do OpenDevUFCG para ler aqui no dev.to, e em breve ainda mais posts saindo do forno.&lt;/p&gt;

&lt;p&gt;Agradeço bastante pela leitura, e se quiser entrar em contato comigo, só mandar um &lt;a href="https://twitter.com/juliobguedes" rel="noopener noreferrer"&gt;Tweet&lt;/a&gt;! Se quiser ler mais textos meus, confere meu &lt;a href="https://medium.com/@Juliobguedes/" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; que em breve mais posts vão sair.&lt;/p&gt;

&lt;p&gt;Fique atento: em breve, teremos novos artigos de contribuidores do OpenDevUFCG aqui no dev.to. Acompanhe o OpenDevUFCG no &lt;a href="https://www.twitter.com/OpenDevUFCG/" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, no &lt;a href="https://www.instagram.com/OpenDevUFCG/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; e, claro, no &lt;a href="https://www.github.com/OpenDevUFCG/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

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