<?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: Guilherme</title>
    <description>The latest articles on DEV Community by Guilherme (@guilhermeloyola).</description>
    <link>https://dev.to/guilhermeloyola</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%2F980956%2Fb1f34ed1-8503-4e4a-8d6e-f7ddbd416a2c.jpeg</url>
      <title>DEV Community: Guilherme</title>
      <link>https://dev.to/guilhermeloyola</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guilhermeloyola"/>
    <language>en</language>
    <item>
      <title>Do Anti-Vibecoding ao Caos: A Saga do "Ficha Monstra"</title>
      <dc:creator>Guilherme</dc:creator>
      <pubDate>Fri, 26 Dec 2025 15:36:45 +0000</pubDate>
      <link>https://dev.to/guilhermeloyola/do-anti-vibecoding-ao-caos-a-saga-do-ficha-monstra-2p3j</link>
      <guid>https://dev.to/guilhermeloyola/do-anti-vibecoding-ao-caos-a-saga-do-ficha-monstra-2p3j</guid>
      <description>&lt;p&gt;O projeto "Ficha Monstra" nasceu de uma mistura de necessidade e impulso: eu comprei um VPS durante a black friday por puro consumismo, 2) eu queria escrever e aprender mais sobre usar a inteligência artificial de uma maneira legal no desenvolvimento de software e 3) eu estava cansado de perder minhas fichas de papel na caixinha de fichas de treinos na academia.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm96cn5ovt0bn0z6k48p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm96cn5ovt0bn0z6k48p.jpg" alt=" " width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ai nasceu o Ficha Monstra, nome que veio do gemini.&lt;/p&gt;

&lt;p&gt;A premissa era criar uma stack "anti-vibecoding": queria estrutura e controle. Escolhi Blazor .NET Core, Identity, EF e Semantic Kernel no Azure.&lt;/p&gt;

&lt;p&gt;A Fase da Ordem Comecei disciplinado. Usei o Gemini apenas para brainstorming e geração de HTML/CSS, mas mantive o controle arquitetural. Criei a solução .NET manualmente (para evitar o vício das IAs em bibliotecas antigas) e usei o Spec Kit para criar uma "Constituição" do projeto, impondo regras rígidas ao modelo. O resultado? Um MVP honesto e funcional entregue em tempo recorde.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyquou6yaggkh26ip1wh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyquou6yaggkh26ip1wh.jpg" alt=" " width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telas, autenticação, telas de criação, detalhe, listagem, paginação, integração com redis cache, eu fiz também um agente integrado com Plugins do Semantic Kernel que é capaz de ver os exercícios na base e sugerir treinos baseado nas informações que o usuário enviou, validações, testes unitários e integrados, tudo isso em 1 dia. &lt;/p&gt;

&lt;p&gt;É verdade que o código estava longe da qualidade desejada.&lt;/p&gt;

&lt;p&gt;A Queda para o Vibecoding O problema de ver tudo funcionando rápido é que o poder sobe à cabeça. A sensação de invencibilidade me fez abandonar o plano original. De repente, eu estava improvisando outras features que não estavam planejadas como gamificação, múltiplos dashboards, admin.&lt;/p&gt;

&lt;p&gt;O rigor técnico desapareceu. Parei de criticar o código gerado e o resultado foi inevitável: o projeto, antes até que bonitinho, degradou-se rapidamente.&lt;/p&gt;

&lt;p&gt;O Aprendizado Apesar do caos no código final, houve um brilho técnico: integrei o Playwright com o Gemini via MCP. Ver o modelo "olhando" para a interface e rodando seus próprios testes foi animal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6yjd4mpbf1c0rq3cndo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6yjd4mpbf1c0rq3cndo.gif" alt=" " width="600" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O Spec Kit é uma surpresa, apesar de ser um pouquinho complicado de entender, ele realmente é uma ferramenta que auxilia e da controle na hora de criação das features.&lt;/p&gt;

&lt;p&gt;As vezes é melhor botar a mão no código e resolver problemas do que escrever mais um prompt e esperar a solução. É preciso saber identificar quando o modelo está patinando no gelo porque a verdade é que quem vai patinar é você e não o modelo.&lt;/p&gt;

&lt;p&gt;No fim, o Ficha Monstra me ensinou que a IA acelera a construção, mas também acelera a criação de dívida técnica se você baixar a guarda. O código gerado é realmente feio e ruim, e é preciso se tornar mais revisor do que o codificador. E saber as bases da engenharia de software é o que faz a diferença.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp37xiol4ah726844is6q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp37xiol4ah726844is6q.gif" alt=" " width="600" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fimydd8ezzq6k1r6po4wc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fimydd8ezzq6k1r6po4wc.jpg" alt=" " width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E me deu uma sensação meio estranha para 2026 de que nada será como antes, MESMO.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>azure</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Transforme seus testes de .NET em um painel visual com Coverlet + GitHub Actions</title>
      <dc:creator>Guilherme</dc:creator>
      <pubDate>Fri, 25 Jul 2025 20:13:14 +0000</pubDate>
      <link>https://dev.to/guilhermeloyola/gerando-relatorio-de-cobertura-de-testes-de-um-projeto-em-net-com-coverlet-github-actions-4b70</link>
      <guid>https://dev.to/guilhermeloyola/gerando-relatorio-de-cobertura-de-testes-de-um-projeto-em-net-com-coverlet-github-actions-4b70</guid>
      <description>&lt;p&gt;Precisava, rápido, de um relatório de cobertura de testes para um projeto meu.&lt;/p&gt;

&lt;p&gt;Um projeto simples feito em .NET, com alguns testes unitários, e que, a cada pull request na branch &lt;code&gt;main&lt;/code&gt;, fosse gerado um relatório de forma que eu pudesse divulgar entre minha equipe (no caso eu mesmo e meus pensamentos).&lt;/p&gt;

&lt;p&gt;Um detalhe importante: meu repositório no GitHub é &lt;strong&gt;privado&lt;/strong&gt;, e se eu quiser usar o GitHub Pages, preciso torná-lo público, o que está fora de questão.&lt;/p&gt;




&lt;h2&gt;
  
  
  Por que usar o Coverlet?
&lt;/h2&gt;

&lt;p&gt;Vamos gerar o relatório de cobertura de testes com o &lt;strong&gt;Coverlet&lt;/strong&gt;, porque:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Funciona com os principais frameworks de teste: &lt;strong&gt;xUnit&lt;/strong&gt;, &lt;strong&gt;NUnit&lt;/strong&gt; e &lt;strong&gt;MSTest&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;É &lt;strong&gt;open source&lt;/strong&gt;, leve e amplamente adotado pela comunidade .NET&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/coverlet-coverage/coverlet" rel="noopener noreferrer"&gt;https://github.com/coverlet-coverage/coverlet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E para transformar os dados brutos de cobertura em relatórios legíveis:&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que usar o ReportGenerator?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Converte os arquivos de cobertura (como o &lt;code&gt;coverage.xml&lt;/code&gt; gerado pelo Coverlet) em relatórios HTML interativos e fáceis de visualizar&lt;/li&gt;
&lt;li&gt;É leve, rápido e gratuito&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Criando um workflow no GitHub Actions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Code Coverage&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup .NET&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-dotnet@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;dotnet-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;9.0.x'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restore dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet restore&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests with coverage&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;dotnet test ./tests/MeuProjetoDe.Tests/Domain.Tests.csproj \&lt;/span&gt;
            &lt;span class="s"&gt;--collect:"XPlat Code Coverage"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install ReportGenerator&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet tool install --global dotnet-reportgenerator-globaltool&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate HTML report&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;reportgenerator \&lt;/span&gt;
            &lt;span class="s"&gt;-reports:"**/coverage.cobertura.xml" \&lt;/span&gt;
            &lt;span class="s"&gt;-targetdir:"coveragereport" \&lt;/span&gt;
            &lt;span class="s"&gt;-reporttypes:Html&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload coverage report artifact&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coverage-report&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coveragereport&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse workflow vai:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurar o ambiente .NET&lt;/li&gt;
&lt;li&gt;Restaurar dependências&lt;/li&gt;
&lt;li&gt;Executar os testes com o &lt;code&gt;--collect:"XPlat Code Coverage"&lt;/code&gt;, que ativa o data collector do Coverlet&lt;/li&gt;
&lt;li&gt;Instalar o ReportGenerator&lt;/li&gt;
&lt;li&gt;Gerar o relatório HTML&lt;/li&gt;
&lt;li&gt;Fazer upload do resultado como artefato&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depois de rodar o workflow, o relatório já estará disponível nos artefatos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2azcajgxptljdaq9xzts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2azcajgxptljdaq9xzts.png" alt="Relatório" width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Como publicar o relatório no GitHub Pages
&lt;/h2&gt;

&lt;p&gt;Como meu repositório original é privado e pretendo mantê-lo assim, criei um segundo repositório público apenas para servir o relatório via GitHub Pages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwsllcfyr5roabr2hgnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwsllcfyr5roabr2hgnq.png" alt="GitHub Pages" width="400" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Criando um token de acesso
&lt;/h3&gt;

&lt;p&gt;Acesse &lt;strong&gt;Developer Settings&lt;/strong&gt; no GitHub e crie um token com as permissões adequadas:&lt;/p&gt;

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

&lt;p&gt;Guarde esse token, pois ele será necessário para a próxima etapa do workflow.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Adicionando o deploy no final do workflow
&lt;/h3&gt;

&lt;p&gt;Adicione o trecho abaixo no final do seu workflow para publicar o conteúdo no branch &lt;code&gt;gh-pages&lt;/code&gt; do repositório público:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy coverage report to MeuProjeto.Coverage repo&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.name "seu nome"&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.email "seu email"&lt;/span&gt;
          &lt;span class="s"&gt;cd coveragereport&lt;/span&gt;
          &lt;span class="s"&gt;git init&lt;/span&gt;
          &lt;span class="s"&gt;git checkout -b gh-pages&lt;/span&gt;
          &lt;span class="s"&gt;git remote add origin https://x-access-token:${{ secrets.COVERAGE_PUBLISH_TOKEN }}@github.com/{seu-usuario}/{repositorio-publico}.git&lt;/span&gt;
          &lt;span class="s"&gt;git add .&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m "feat: atualização automática de cobertura"&lt;/span&gt;
          &lt;span class="s"&gt;git push --force origin gh-pages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Criando e adicionando o token no GitHub
&lt;/h3&gt;

&lt;p&gt;Vá em &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;https://github.com/settings/tokens&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Crie um token com permissão de escrita no repositório de destino&lt;/p&gt;

&lt;p&gt;Copie o token e adicione no repositório privado (Generioc) em&lt;br&gt;
Settings &amp;gt; Secrets and variables &amp;gt; Actions, como:&lt;br&gt;
COVERAGE_PUBLISH_TOKEN&lt;/p&gt;

&lt;p&gt;Pronto. O GitHub Actions agora pode fazer o deploy automaticamente no Pages. ✅&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>testing</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Gerando Relatório de Cobertura de Testes de um projeto em .NET com Coverlet + GitHub Actions</title>
      <dc:creator>Guilherme</dc:creator>
      <pubDate>Fri, 25 Jul 2025 20:13:14 +0000</pubDate>
      <link>https://dev.to/guilhermeloyola/gerando-relatorio-de-cobertura-de-testes-de-um-projeto-em-net-com-coverlet-github-actions-20hh</link>
      <guid>https://dev.to/guilhermeloyola/gerando-relatorio-de-cobertura-de-testes-de-um-projeto-em-net-com-coverlet-github-actions-20hh</guid>
      <description>&lt;p&gt;Precisava, rápido, de um relatório de cobertura de testes para um projeto meu.&lt;/p&gt;

&lt;p&gt;Um projeto simples feito em .NET, com alguns testes unitários, e que, a cada pull request na branch &lt;code&gt;main&lt;/code&gt;, fosse gerado um relatório de forma que eu pudesse divulgar entre minha equipe (no caso eu mesmo e meus pensamentos).&lt;/p&gt;

&lt;p&gt;Um detalhe importante: meu repositório no GitHub é &lt;strong&gt;privado&lt;/strong&gt;, e se eu quiser usar o GitHub Pages, preciso torná-lo público, o que está fora de questão.&lt;/p&gt;




&lt;h2&gt;
  
  
  Por que usar o Coverlet?
&lt;/h2&gt;

&lt;p&gt;Vamos gerar o relatório de cobertura de testes com o &lt;strong&gt;Coverlet&lt;/strong&gt;, porque:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Funciona com os principais frameworks de teste: &lt;strong&gt;xUnit&lt;/strong&gt;, &lt;strong&gt;NUnit&lt;/strong&gt; e &lt;strong&gt;MSTest&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;É &lt;strong&gt;open source&lt;/strong&gt;, leve e amplamente adotado pela comunidade .NET&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/coverlet-coverage/coverlet" rel="noopener noreferrer"&gt;https://github.com/coverlet-coverage/coverlet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E para transformar os dados brutos de cobertura em relatórios legíveis:&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que usar o ReportGenerator?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Converte os arquivos de cobertura (como o &lt;code&gt;coverage.xml&lt;/code&gt; gerado pelo Coverlet) em relatórios HTML interativos e fáceis de visualizar&lt;/li&gt;
&lt;li&gt;É leve, rápido e gratuito&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Criando um workflow no GitHub Actions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Code Coverage&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup .NET&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-dotnet@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;dotnet-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;9.0.x'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restore dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet restore&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests with coverage&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;dotnet test ./tests/MeuProjetoDe.Tests/Domain.Tests.csproj \&lt;/span&gt;
            &lt;span class="s"&gt;--collect:"XPlat Code Coverage"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install ReportGenerator&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet tool install --global dotnet-reportgenerator-globaltool&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate HTML report&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;reportgenerator \&lt;/span&gt;
            &lt;span class="s"&gt;-reports:"**/coverage.cobertura.xml" \&lt;/span&gt;
            &lt;span class="s"&gt;-targetdir:"coveragereport" \&lt;/span&gt;
            &lt;span class="s"&gt;-reporttypes:Html&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload coverage report artifact&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coverage-report&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coveragereport&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse workflow vai:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurar o ambiente .NET&lt;/li&gt;
&lt;li&gt;Restaurar dependências&lt;/li&gt;
&lt;li&gt;Executar os testes com o &lt;code&gt;--collect:"XPlat Code Coverage"&lt;/code&gt;, que ativa o data collector do Coverlet&lt;/li&gt;
&lt;li&gt;Instalar o ReportGenerator&lt;/li&gt;
&lt;li&gt;Gerar o relatório HTML&lt;/li&gt;
&lt;li&gt;Fazer upload do resultado como artefato&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depois de rodar o workflow, o relatório já estará disponível nos artefatos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2azcajgxptljdaq9xzts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2azcajgxptljdaq9xzts.png" alt="Relatório" width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Como publicar o relatório no GitHub Pages
&lt;/h2&gt;

&lt;p&gt;Como meu repositório original é privado e pretendo mantê-lo assim, criei um segundo repositório público apenas para servir o relatório via GitHub Pages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwsllcfyr5roabr2hgnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwsllcfyr5roabr2hgnq.png" alt="GitHub Pages" width="400" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Criando um token de acesso
&lt;/h3&gt;

&lt;p&gt;Acesse &lt;strong&gt;Developer Settings&lt;/strong&gt; no GitHub e crie um token com as permissões adequadas:&lt;/p&gt;

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

&lt;p&gt;Guarde esse token, pois ele será necessário para a próxima etapa do workflow.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Adicionando o deploy no final do workflow
&lt;/h3&gt;

&lt;p&gt;Adicione o trecho abaixo no final do seu workflow para publicar o conteúdo no branch &lt;code&gt;gh-pages&lt;/code&gt; do repositório público:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy coverage report to MeuProjeto.Coverage repo&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.name "seu nome"&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.email "seu email"&lt;/span&gt;
          &lt;span class="s"&gt;cd coveragereport&lt;/span&gt;
          &lt;span class="s"&gt;git init&lt;/span&gt;
          &lt;span class="s"&gt;git checkout -b gh-pages&lt;/span&gt;
          &lt;span class="s"&gt;git remote add origin https://x-access-token:${{ secrets.COVERAGE_PUBLISH_TOKEN }}@github.com/{seu-usuario}/{repositorio-publico}.git&lt;/span&gt;
          &lt;span class="s"&gt;git add .&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m "feat: atualização automática de cobertura"&lt;/span&gt;
          &lt;span class="s"&gt;git push --force origin gh-pages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Criando e adicionando o token no GitHub
&lt;/h3&gt;

&lt;p&gt;Vá em &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;https://github.com/settings/tokens&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Crie um token com permissão de escrita no repositório de destino&lt;/p&gt;

&lt;p&gt;Copie o token e adicione no repositório privado (Generioc) em&lt;br&gt;
Settings &amp;gt; Secrets and variables &amp;gt; Actions, como:&lt;br&gt;
COVERAGE_PUBLISH_TOKEN&lt;/p&gt;

&lt;p&gt;Pronto. O GitHub Actions agora pode fazer o deploy automaticamente no Pages. ✅&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Criando testes de integração no ASP.NET core | Parte 1</title>
      <dc:creator>Guilherme</dc:creator>
      <pubDate>Sun, 07 Jan 2024 22:05:00 +0000</pubDate>
      <link>https://dev.to/guilhermeloyola/criando-testes-de-integracao-no-aspnet-core-parte-1-1984</link>
      <guid>https://dev.to/guilhermeloyola/criando-testes-de-integracao-no-aspnet-core-parte-1-1984</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Uma rápida passada em testes unitários&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;De modo geral, os testes unitários testam, isoladamente, a menor unidade de um código, ou seja: os métodos e classes sem acesso a banco ou serviços externos.&lt;/p&gt;

&lt;p&gt;Os testes unitários são de rápida execução, desenvolvimento, refatoração e detecção de bugs no código.&lt;/p&gt;

&lt;p&gt;É bom lembrar que os testes unitários são totalmente mockados, isto é, as implementações das classes mockam acessos a repositórios, serviços etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Os testes de integração&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wd3eQ0My--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3955uyg17k9ocb1ukwy6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wd3eQ0My--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3955uyg17k9ocb1ukwy6.jpg" alt="A famosa pirâmide de testes" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os testes de integração desempenham o papel de avaliar a interação entre diferentes componentes do sistema, a fim de verificar seu funcionamento em conjunto.&lt;/p&gt;

&lt;p&gt;É por meio desses testes que asseguramos a consistência das interações entre diversas partes do sistema, validamos fluxos complexos e completos, garantindo assim a qualidade do código como um todo, não se limitando a uma única parte isolada.&lt;/p&gt;

&lt;p&gt;Sim, eles são mais complexos de desenvolver e manter, além de serem mais lentos ao serem executados em comparação aos testes de unidade. Isso ocorre porque testam funcionalidades completas, inclusive a persistência dos dados quando aplicável, ou o acesso a serviços externos.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Vamos ao código&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xYGwFF12--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g3kcomgz82dxja32xns4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xYGwFF12--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g3kcomgz82dxja32xns4.gif" alt="Image description" width="480" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edite o arquivo do projeto da API dando visibilidade da sua api ao testes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1sDGvkFb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mclmn356oh8c1b176l7p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1sDGvkFb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mclmn356oh8c1b176l7p.gif" alt="Editando o project file" width="720" height="480"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`&amp;lt;Project Sdk="Microsoft.NET.Sdk.Web"&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net8.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;
    &amp;lt;InvariantGlobalization&amp;gt;true&amp;lt;/InvariantGlobalization&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include="Dapper" Version="2.1.28" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" /&amp;gt;
    &amp;lt;PackageReference Include="Npgsql" Version="8.0.1" /&amp;gt;
    &amp;lt;PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;

    &amp;lt;ItemGroup&amp;gt;
        &amp;lt;InternalsVisibleTo Include="CheckoutApiTests"/&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
&amp;lt;/Project&amp;gt;`

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exponha seu Program.cs adicionando a linha ao final do arquivo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public partial class Program { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Crie a classe de testes integrados&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CheckoutApiTests
{
    public class CheckoutServiceIntegrationTests : IClassFixture&amp;lt;WebApplicationFactory&amp;lt;Program&amp;gt;&amp;gt;
    {
        private readonly WebApplicationFactory&amp;lt;Program&amp;gt; _sut;
        public CheckoutServiceIntegrationTests(WebApplicationFactory&amp;lt;Program&amp;gt; sut)
        {
            _sut = sut;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sut é um acrônimo para System Under Test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Opcional: adicione um enviroment variable *&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public CheckoutServiceIntegrationTests(WebApplicationFactory&amp;lt;Program&amp;gt; sut)
 {
     _sut = sut.WithWebHostBuilder(builder =&amp;gt;
     {
         builder.UseEnvironment("Development");
     });
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Crie um teste *&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Fact]
![Criando um teste de integração](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0u3j6ewycp0ec9mjlwz9.gif)


public async Task PostCheckout_ReturnsOkWithInsertedId_WhenValidData()
{
    var client = _sut.CreateClient();

    var checkoutData = new
    {
        CardNumber = "10000011100011",
        UserId = Guid.NewGuid(),
        ExpirationDate = "12/25",
        SecurityCode = "123",
        Amount = 19,
        Currency = "BRL"
    };

    var content = new StringContent(JsonSerializer.Serialize(checkoutData), System.Text.Encoding.UTF8, "application/json");

    var response = await client.PostAsync("/checkout", content);

    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

    var responseContent = await response.Content.ReadAsStringAsync();
    var insertedId = JsonSerializer.Deserialize&amp;lt;Guid&amp;gt;(responseContent);

    Assert.NotEqual(Guid.Empty, insertedId);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hora de rodar os testes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AC9yZBeC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xuf8j2rnjklxn2209fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AC9yZBeC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xuf8j2rnjklxn2209fg.png" alt="Teste com sucesso! =" width="800" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lembrando que esses testes estão conectados no banco de desenvolvimento, portanto um registro foi criado na tabela:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---B9KJY64--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5n9mmubxrukiy1x18st.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---B9KJY64--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5n9mmubxrukiy1x18st.png" alt="Select da tabela de checkout com o registro inserido via teste de integração" width="800" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E agora você sabe como criar testes de integração, hora de botar a mão na massa e criar mais testes.&lt;/p&gt;

&lt;p&gt;No próximo artigo vamos utilizar o Testcontainers para criar um banco em tempo de execução dos testes integrados! &lt;/p&gt;

&lt;p&gt;Até mais!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Aprendendo e botando em prática com as muitas APIs disponíveis. Um pequeno incentivo pra você.</title>
      <dc:creator>Guilherme</dc:creator>
      <pubDate>Tue, 26 Sep 2023 01:23:31 +0000</pubDate>
      <link>https://dev.to/guilhermeloyola/aprendendo-e-botando-em-pratica-com-as-muitas-apis-disponiveis-um-pequeno-incentivo-pra-voce-462a</link>
      <guid>https://dev.to/guilhermeloyola/aprendendo-e-botando-em-pratica-com-as-muitas-apis-disponiveis-um-pequeno-incentivo-pra-voce-462a</guid>
      <description>&lt;p&gt;A dica é óbvia, mas sempre válida: comece pela documentação e leia-a com calma. Os detalhes aqui são importantes.&lt;/p&gt;

&lt;p&gt;Lendo e trabalhando com APIs consagradas e disponíveis você deverá aprender coisas como:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uso básico da API&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Ou seja, como fazer solicitações, autenticação, autorização, entender as respostas e como funcionam em diferentes empresas. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autenticação/Autorização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Compreender os métodos de autenticação e notar que, de maneira geral, as APIs funcionam de forma semelhante, seja com o uso de chaves de API, OAuth, entre outros. Você pode implementar um método de autenticação na sua API com base na documentação de um produto bem estabelecido no mercado. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escrever documentação&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine que você tenha uma tarefa agendada para amanhã que envolve a modificação de um endpoint sem documentação existente. Essa é uma excelente oportunidade para ganhar reconhecimento junto à equipe, mesmo que envolva apenas a documentação desse endpoint. Você já tem exemplos de como documentar uma API. Siga o exemplo!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Um desafio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Considere encapsular as funcionalidades da API em um único lugar usando um "wrapper" (encapsulamento). Nesse caso, pode ser uma ótima ideia reinventar a roda, pois isso permite colocar em prática conceitos importantes, como abstração, testes e legibilidade de código. Além disso, não hesite em dar uma olhada nas soluções já publicadas no GitHub para aprender com os melhores exemplos disponíveis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algumas APIs pra você:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Last.fm API: &lt;a href="http://www.last.fm/api"&gt;http://www.last.fm/api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Spotify Developer: &lt;a href="https://developer.spotify.com/"&gt;https://developer.spotify.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ANBIMA (Associação Brasileira das Entidades dos Mercados Financeiro e de Capitais): [&lt;a href="https://developers.anbima.com.br/pt/documentacao/visao-geral/introducao-a-api/"&gt;https://developers.anbima.com.br/pt/documentacao/visao-geral/introducao-a-api/&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;Discord Developer Portal: &lt;a href="https://discord.com/developers/docs/intro"&gt;https://discord.com/developers/docs/intro&lt;/a&gt;
Telegram Bot API: &lt;a href="https://core.telegram.org/"&gt;https://core.telegram.org/&lt;/a&gt;
Adyen API Explorer: &lt;a href="https://docs.adyen.com/api-explorer"&gt;https://docs.adyen.com/api-explorer&lt;/a&gt;
&lt;a href="https://core.telegram.org/"&gt;https://core.telegram.org/&lt;/a&gt;
&lt;a href="https://docs.adyen.com/api-explorer/"&gt;https://docs.adyen.com/api-explorer/
&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>beginners</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
