<?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: Yuri Peixinho</title>
    <description>The latest articles on DEV Community by Yuri Peixinho (@yuripeixinho).</description>
    <link>https://dev.to/yuripeixinho</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1647416%2Fcb24132f-cdc1-4080-8977-0786f79ceb26.png</url>
      <title>DEV Community: Yuri Peixinho</title>
      <link>https://dev.to/yuripeixinho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yuripeixinho"/>
    <language>en</language>
    <item>
      <title>Integração Contínua e Entrega Contínua (CI/CD)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Wed, 21 Oct 2026 01:00:19 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/integracao-continua-e-entrega-continua-cicd-cng</link>
      <guid>https://dev.to/yuripeixinho/integracao-continua-e-entrega-continua-cicd-cng</guid>
      <description>&lt;h1&gt;
  
  
  O que é Integração Contínua
&lt;/h1&gt;

&lt;p&gt;A definição origional (Martin Flower, por volta dos anos 2000) é: uma prática de engenharia onde os desenvolvedores integram seu trabalho a uma linha principal compartilhada com muita frequência (pelo menos uma vez por dia) e cada integração é verificada por um build automatizado (incluindo testes) que detecta erros de integração o mais rápido possível.&lt;/p&gt;

&lt;h2&gt;
  
  
  Certo, mas porque isso existe? qual o problema que resolveu?
&lt;/h2&gt;

&lt;p&gt;O problema é histórico. Quando não há essa prática em times de desenvolvimentos acontece o “Integration Hell” . Times trabalhavam semanas em branches isoladas e só juntavam tudo no fim do ciclo. E como você já deve imaginar, resultava em diversos conflitos de merges de uma vez só, bugs que só apareciam quando o código de todo mundo finalmente se encontrava, e um período de “estabilização” que podia durar semanas.&lt;/p&gt;

&lt;p&gt;Fowler então descreveu as práticas que, juntas formam CI de verdade (resumidas e adaptadas para hoje).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um repositório único de código-fonte, desse modo, todos os desenvolvedores deveriam trabalhar do mesmo lugar&lt;/li&gt;
&lt;li&gt;Automatizar o build: compilar/empacotar deve ser um comando, nunca um ritual manual com passos documentados numa wiki&lt;/li&gt;
&lt;li&gt;Fazer o build se autotestar: o build inclui rodar a suíte de testes automatizados. “Buildou” sem rodar testes não conta.&lt;/li&gt;
&lt;li&gt;Todo mundo commita na linha principal do dia: branches de feature vivem horas ou poucos dias, nunca semanas&lt;/li&gt;
&lt;li&gt;Toda integração builda a linha principal numa máquina dedicada, não vale “builda na minha máquina”; precisa buildar em um ambiente neutro, repordutível.&lt;/li&gt;
&lt;li&gt;Manter o build rápido, feedback que demora horas deixa de ser útil; o ponto todo é saber do erro em minutos&lt;/li&gt;
&lt;li&gt;Testar em um clone do ambiente de produção, para não descobrir só em produção que algo só funciona em sua máquina&lt;/li&gt;
&lt;li&gt;Tornar fácil pegar o último entregável, qualquer pessoa do time deve conseguir pegar a build mais recente sem caçada&lt;/li&gt;
&lt;li&gt;Todo mundo vê o resultado, status do build é visível pra o time inteiro, não escondido&lt;/li&gt;
&lt;li&gt;Automatizar o deploy: Já é a ponte pro que seção 2 chama de Continuous Delivery/Deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma peça central que costuma passar batido: CI &lt;strong&gt;depende&lt;/strong&gt; de um jeito de trabalhar chamado &lt;strong&gt;trunk-based development&lt;/strong&gt; — branches de vida curta (horas, no máximo 1–2 dias) que voltam pra &lt;code&gt;main&lt;/code&gt; rapidamente. Sem isso, não tem CI de verdade possível: se o código só integra de 3 em 3 semanas, você tem build automatizado, mas não tem &lt;em&gt;integração contínua&lt;/em&gt; — é só automação de um processo que continua lento no fundo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Continous Delivery vs. Continous Deployment (a distinção que quase todo mundo confunde)
&lt;/h1&gt;

&lt;p&gt;As pessoas usam CI/CD como se fosse uma coisa só, mas o “CD” sozinho já é ambíguo. existem duas práticas distintas escondidas atrás da mesma sigla.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;O que garante&lt;/th&gt;
&lt;th&gt;Deploy em produção&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Todo commit builda e passa nos testes.&lt;/td&gt;
&lt;td&gt;Não se aplica — CI para na integração, não decide nada sobre deploy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Continuous Delivery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;O software está &lt;strong&gt;sempre em um estado implantável&lt;/strong&gt;, através de um pipeline totalmente automatizado até staging/pré-produção.&lt;/td&gt;
&lt;td&gt;Manual — uma pessoa aperta um botão pra liberar aquela versão específica pra produção, quando o negócio decidir.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Continuous Deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mesma coisa que Delivery, mas vai um passo além.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Automático&lt;/strong&gt; — toda mudança que passa no pipeline vai pra produção sem nenhuma ação humana.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A diferença entre as duas últimas é &lt;strong&gt;só um gate de decisão humana antes do deploy final,&lt;/strong&gt; tecnicamente o pipeline é idêntico. Delivery é a escolha certa quando existe uma razão de negócio pra controlar o &lt;em&gt;momento&lt;/em&gt; do deploy (um lançamento coordenado com marketing, uma janela de manutenção, compliance que exige aprovação humana). Deployment contínuo é pra times que confiam o bastante no pipeline (testes, gates de qualidade, observabilidade) pra deixar ele decidir sozinho.&lt;/p&gt;

&lt;h1&gt;
  
  
  Os antipadrões que CI/CD resolve
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Funciona na minha máquina"&lt;/strong&gt;: o ambiente de build de cada desenvolvedor é ligeiramente diferente (versão de SDK, variável de ambiente, dependência global instalada manualmente), sem um ambiente de build neutro e reprodutível, ninguém tem certeza do que realmente vai rodar em produção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge day / "merge hell"&lt;/strong&gt;: integrar semanas de trabalho paralelo de uma vez só produz uma quantidade de conflito que cresce de forma não linear com o tempo de isolamento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy como evento raro e assustador&lt;/strong&gt;: quando deploy acontece a cada trimestre, cada deploy carrega meses de mudança acumulada — se algo quebra, é quase impossível saber qual das centenas de mudanças foi a causa. Deploys frequentes e pequenos isolam o risco.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Servidores "floco de neve" (snowflake servers)&lt;/strong&gt;: ambientes configurados manualmente, únicos, que ninguém consegue recriar do zero com confiança — pipeline como código (infra e deploy descritos em arquivos versionados) é o antídoto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback lento&lt;/strong&gt;: um bug introduzido numa sexta-feira só é descoberto quando aparece em produção semanas depois — nesse ponto, ninguém lembra mais o contexto da mudança que causou. Quanto mais rápido o feedback, mais barato o bug.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;As peças fundamentais de qualquer pipeline (vocabulário universal, antes de qualquer ferramenta específica)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Esse vocabulário vale pra Jenkins, GitLab CI, Azure DevOps, CircleCI ou GitHub Actions, só muda o nome que cada ferramenta dá pra mesma ideia.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline&lt;/strong&gt;: a sequência inteira de estágios automatizados, do commit até (potencialmente) a produção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger / gatilho&lt;/strong&gt;: o evento que inicia a pipeline — um &lt;code&gt;push&lt;/code&gt;, a abertura de um Pull Request, uma tag de release, um agendamento (&lt;code&gt;schedule&lt;/code&gt;, tipo cron), ou um disparo manual.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runner / agente / worker&lt;/strong&gt;: a máquina (física, virtual ou efêmera) que executa os passos de um job. Pode ser hospedada pela própria ferramenta de CI ou auto-hospedada pelo time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job&lt;/strong&gt;: um agrupamento de passos que roda inteiro num único runner. Jobs diferentes de uma mesma pipeline normalmente rodam em runners diferentes, em paralelo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step / task&lt;/strong&gt;: uma ação individual dentro de um job — rodar um comando, restaurar dependências, compilar, etc. Steps de um mesmo job rodam em sequência e compartilham o sistema de arquivos daquele runner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artifact&lt;/strong&gt;: o resultado produzido por um estágio (um binário compilado, um pacote, um relatório de testes) que precisa passar pro próximo estágio ou ficar disponível pra download.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment (ambiente)&lt;/strong&gt;: onde um artifact é implantado — development, staging, produção — cada um com suas próprias variáveis, segredos e, às vezes, regras de aprovação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets&lt;/strong&gt;: credenciais (chaves de API, connection strings, tokens) injetadas em tempo de execução pela própria ferramenta de CI — nunca escritas no código-fonte.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Como medir se isso está funcionando com as métricas DORA&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;O &lt;strong&gt;DORA&lt;/strong&gt; (DevOps Research and Assessment, hoje parte do Google Cloud) passou anos de pesquisa comparando times de alta e baixa performance, e chegou a &lt;strong&gt;4 métricas&lt;/strong&gt; que correlacionam fortemente com desempenho organizacional:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Frequency&lt;/strong&gt; (frequência de deploy) — com que frequência o time implanta em produção. Times de elite: várias vezes ao dia. Times de baixa performance: uma vez por mês ou menos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Time for Changes&lt;/strong&gt; (tempo de entrega de mudança) — quanto tempo leva do commit até aquele código estar rodando em produção. Times de elite: menos de um dia. Times de baixa performance: meses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change Failure Rate&lt;/strong&gt; (taxa de falha de mudança) — que percentual dos deploys causa um incidente ou precisa de correção emergencial. Contraintuitivo: deployar com mais frequência &lt;strong&gt;não&lt;/strong&gt; aumenta essa taxa — times de elite têm deploys frequentes &lt;strong&gt;e&lt;/strong&gt; baixa taxa de falha, porque deploys pequenos e frequentes são mais fáceis de entender e reverter que deploys gigantes e raros.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to Restore Service / MTTR&lt;/strong&gt; (tempo pra restaurar serviço) — quando algo quebra em produção, quanto tempo leva pra voltar ao normal. Times de elite: menos de uma hora.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O ponto central da pesquisa do DORA: essas 4 métricas &lt;strong&gt;andam juntas&lt;/strong&gt; — um time não troca velocidade por estabilidade, bons pipelines de CI/CD entregam as duas coisas ao mesmo tempo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Como saber a maturidade do processo da sua equipe
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nível 0 — Manual&lt;/strong&gt;: build e deploy são processos manuais, sem automação nenhuma, dependem de uma pessoa seguir um passo a passo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nível 1 — Scripts automatizados, execução manual&lt;/strong&gt;: existe um script que builda/testa, mas alguém precisa lembrar de rodar ele.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nível 2 — CI&lt;/strong&gt;: toda mudança builda e testa automaticamente a cada push/PR, sem intervenção humana — mas o deploy continua manual.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nível 3 — Continuous Delivery&lt;/strong&gt;: pipeline totalmente automatizado até staging/pré-produção; deploy em produção é um clique de alguém, não mais um processo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nível 4 — Continuous Deployment&lt;/strong&gt;: zero intervenção humana — tudo que passa no pipeline vai pra produção sozinho.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CI (Continuous Integration):&lt;/strong&gt; cada push ou pull request dispara automaticamente um pipeline que compila o código, roda os testes e valida a qualidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CD (Continuous Delivery/Deployment):&lt;/strong&gt; após o CI passar, o código pode ser entregue automaticamente ao ambiente de staging ou produção.&lt;/p&gt;

&lt;p&gt;O ponto central: &lt;strong&gt;um código que não passa nos testes nunca chega ao deploy&lt;/strong&gt;. Isso é um gate automático — sem humano no meio&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>devops</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Test Driven Development (TDD)</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 18 Oct 2026 21:52:47 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/test-driven-development-tdd-1eik</link>
      <guid>https://dev.to/yuripeixinho/test-driven-development-tdd-1eik</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;TDD (Test-Driven Development, ou Desenvolvimento Guiado por Testes) inverte a ordem natural de escrever código: em vez de implementar a funcionalidade e só depois escrever testes para confirmar que ela funciona, você escreve o teste primeiro — um teste que falha, porque o código que ele exercita ainda nem existe — e só então escreve o código mínimo necessário para fazer esse teste passar.&lt;/p&gt;

&lt;p&gt;Essa inversão parece pequena, mas muda tudo. Quando você testa depois, o teste normalmente confirma o que o código já faz — inclusive os vícios de design que ele carrega. Quando você testa antes, o teste é quem dita como o código deveria ser usado: sua API, suas dependências, seus pontos de extensão. O teste vira uma especificação executável, não uma rede de segurança criada depois do fato.&lt;/p&gt;

&lt;p&gt;TDD não é sobre "ter testes". É sobre usar o ato de escrever testes como ferramenta de design. Um código difícil de testar quase sempre é um código com problemas de design: acoplamento alto, responsabilidades misturadas, dependências escondidas. TDD expõe esses problemas cedo, antes que fiquem caros de corrigir.&lt;br&gt;
Este artigo percorre o caminho completo: o ciclo básico, as três leis formais, a anatomia de um bom teste, um exemplo prático do zero, os tipos de dublê de teste, a pirâmide de testes, como TDD molda a arquitetura, como aplicar tudo isso na stack deste projeto (C#, xUnit, FluentAssertions, NSubstitute), as duas escolas de pensamento, as armadilhas mais comuns e como resgatar código legado sem rede de segurança. Ao final, um checklist prático e uma lista de recursos para continuar evoluindo.&lt;/p&gt;
&lt;h1&gt;
  
  
  TDD é uma arquitetura?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TDD é um processo, não uma arquitetura.&lt;/strong&gt; É uma disciplina de &lt;em&gt;como&lt;/em&gt; você escreve código (teste antes, código mínimo, refatora), não uma definição de &lt;em&gt;como o sistema é estruturado&lt;/em&gt; (camadas, módulos, quem depende de quem). Você pode praticar TDD dentro de qualquer arquitetura, inclusive uma ruim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arquitetura&lt;/strong&gt; é uma preocupação separada: é o conjunto de decisões estruturais: Clean Architecture, Hexagonal (Ports &amp;amp; Adapters), camadas, microsserviços, etc, que definem fronteiras e direção de dependência.&lt;/p&gt;

&lt;p&gt;A confusão existe porque &lt;strong&gt;TDD empurra a arquitetura numa certa direção como efeito colateral&lt;/strong&gt;: para um teste ser fácil de escrever, a unidade sob teste precisa ter dependências injetáveis e abstraídas. Isso é exatamente o que arquiteturas como Clean/Hexagonal formalizam de propósito. Não é coincidência que a separação deste projeto (&lt;code&gt;Core.Domain&lt;/code&gt; → &lt;code&gt;Core.Application&lt;/code&gt; → &lt;code&gt;Core.Infrastructure&lt;/code&gt;, com a camada de aplicação dependendo de interfaces, não de implementações concretas) seja tão amigável a TDD: é uma arquitetura que já nasce com testabilidade como requisito de design.&lt;/p&gt;

&lt;p&gt;Podemos dizer então que TDD não &lt;em&gt;escolhe&lt;/em&gt; a arquitetura, mas &lt;em&gt;pressiona&lt;/em&gt; você a ter uma onde cada peça seja testável isoladamente  e isso, na prática, costuma convergir para os mesmos princípios que arquiteturas como Clean Architecture defendem (baixo acoplamento, inversão de dependência, fronteiras explícitas).&lt;/p&gt;
&lt;h1&gt;
  
  
  O ciclo Red-Green-Refactor
&lt;/h1&gt;

&lt;p&gt;O TDD funciona em um ciclo curto que se repete dezenas de vezes por dia: Red (vermelho), Green (verde) e Refactor (refatorar).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red:&lt;/strong&gt; Escreva um teste para um comportamento que ainda não existe, e rode a suíte. O teste deve falhar, se ele passar de cara, ou o comportamento já existe, ou o teste não está testando nada. Falhar aqui é o objetivo: é a prova de que o teste é capaz de detectar a ausência do comportamento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Green:&lt;/strong&gt; Escreva o código de produção mais simples possível para fazer o teste passar. Simples mesmo: é aceitável, e recomendado no início, retornar um valor fixo se isso for suficiente para passar o teste atual. A elegância vem depois; agora o objetivo é sair do vermelho o mais rápido possível.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refactor:&lt;/strong&gt; Com o teste passando, limpe o código: remova duplicação, melhore nomes, extraia métodos, ajuste o design. Os testes que já passam são sua rede de segurança: qualquer regressão introduzida na refatoração é pega imediatamente. Nenhum comportamento novo é adicionado nesta fase, só melhoria estrutural.&lt;/p&gt;

&lt;p&gt;Depois do refactor, o ciclo recomeça com um novo teste Red. Cada volta do ciclo deve durar minutos, não horas: passos pequenos demais parecem lentos no início, mas evitam o cenário clássico de "quebrei tudo e não sei por quê".&lt;/p&gt;

&lt;p&gt;Erros comuns de quem está começando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Escrever vários testes de uma vez antes de fazer qualquer um passar, perdendo o feedback imediato do ciclo.&lt;/li&gt;
&lt;li&gt;Pular a fase Red, escrevendo o código de produção primeiro e o teste depois só para "confirmar" — isso não é TDD, é teste depois do fato.&lt;/li&gt;
&lt;li&gt;Pular o Refactor porque "já está funcionando" — é assim que o código acumula dívida técnica mesmo com testes.&lt;/li&gt;
&lt;li&gt;Escrever uma solução completa e genérica já na fase Green, em vez da solução mínima — isso tende a acoplar o design a suposições erradas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;!image.png&lt;/p&gt;

&lt;p&gt;O loop fecha de Refactor de volta para Red: a cada volta, um novo teste força o próximo incremento de comportamento.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;strong&gt;As três leis do TDD&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Robert C. Martin (Uncle Bob) resumiu a disciplina do TDD em três leis, aplicadas em conjunto e repetidamente:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você não pode escrever código de produção até escrever um teste que falhe.&lt;/li&gt;
&lt;li&gt;Você não pode escrever mais de um teste do que o suficiente para falhar (não compilar também conta como falhar).&lt;/li&gt;
&lt;li&gt;Você não pode escrever mais código de produção do que o necessário para fazer o teste atual passar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Seguidas à risca, essas leis forçam ciclos de segundos: escreva uma linha de teste, veja falhar, escreva uma linha de produção, veja passar, repita. Na prática, poucos times seguem isso de forma tão granular — mas entender a disciplina no extremo ajuda a reconhecer quando você se afastou dela (por exemplo, ao escrever 40 linhas de produção para um teste que ainda nem rodou).&lt;/p&gt;

&lt;p&gt;Exemplo do ritmo em C#, implementando uma calculadora de desconto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Teste que falha (Red) — ainda não existe CalculadoraDeDesconto&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SemItens_DevolveDescontoZero&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;calculadora&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CalculadoraDeDesconto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;desconto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculadora&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calcular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valorTotal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;desconto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0m&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 2. Código mínimo para passar (Green)&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraDeDesconto&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valorTotal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0m&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 3. Novo teste força generalização (Red de novo)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AcimaDeCemReais_AplicaDezPorCentoDeDesconto&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;calculadora&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CalculadoraDeDesconto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;desconto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculadora&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calcular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valorTotal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;desconto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20m&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 4. Agora o comportamento real aparece (Green)&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculadoraDeDesconto&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Calcular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valorTotal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;valorTotal&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;100m&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;valorTotal&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.10m&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0m&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;Repare: o código de produção só cresceu porque um teste exigiu. Nenhuma regra de desconto foi antecipada "porque provavelmente vai precisar".&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;3. Anatomia de um bom teste&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Um teste bem escrito segue uma estrutura previsível, descrita pelo acrônimo AAA:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrange (organizar): prepara o cenário — cria objetos, configura dependências, define valores de entrada.&lt;/li&gt;
&lt;li&gt;Act (agir): executa a ação testada — normalmente uma única chamada de método.&lt;/li&gt;
&lt;li&gt;Assert (verificar): confirma que o resultado observado é o esperado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Times que praticam BDD usam a variação Given-When-Then, com o mesmo espírito: Given (dado um contexto) corresponde ao Arrange, When (quando uma ação ocorre) ao Act, Then (então um resultado é esperado) ao Assert. A diferença é mais de vocabulário e foco em linguagem de negócio do que de mecânica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Pedido_ComItemAbaixoDoEstoque_ReduzEstoqueDisponivel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Arrange (Given)&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;estoque&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Estoque&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantidadeDisponivel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Act (When)&lt;/span&gt;
    &lt;span class="n"&gt;estoque&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Reservar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantidade&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Assert (Then)&lt;/span&gt;
    &lt;span class="n"&gt;estoque&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QuantidadeDisponivel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7&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;Boas práticas de nomenclatura e estrutura:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nome do teste conta uma história: &lt;code&gt;Metodo_Cenario_ResultadoEsperado&lt;/code&gt; (ex.: &lt;code&gt;Reservar_QuantidadeMaiorQueEstoque_LancaExcecao&lt;/code&gt;). Quem lê o nome do teste falhando já entende o que quebrou, sem abrir o código.&lt;/li&gt;
&lt;li&gt;Um teste, um motivo para falhar: evite múltiplos &lt;code&gt;Assert&lt;/code&gt; verificando coisas não relacionadas no mesmo teste. Vários asserts sobre o MESMO resultado (vários campos de um mesmo objeto) são aceitáveis.&lt;/li&gt;
&lt;li&gt;Sem lógica condicional no teste: &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt; dentro de um teste são sinal de alerta — um teste deve ser trivial de ler, sem precisar ser depurado para entender o que ele verifica.&lt;/li&gt;
&lt;li&gt;Independência: um teste não pode depender da ordem de execução nem do estado deixado por outro teste. Cada teste prepara seu próprio cenário do zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;TDD molda o design&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;TDD não é só sobre confiança — é sobre forçar boas decisões de design antes que o código endureça. Um teste unitário só é fácil de escrever quando a unidade sob teste tem poucas dependências, e essas dependências são visíveis (injetadas), não escondidas (instanciadas internamente ou acessadas via estáticos/singletons globais).&lt;/p&gt;

&lt;p&gt;Esse efeito colateral é intencional e muito valioso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Baixo acoplamento: se para testar uma classe você precisa configurar meia aplicação, o teste "dói" — e essa dor é um sinal de design, não um problema do framework de testes. TDD expõe isso na primeira tentativa de escrever o teste, antes que o acoplamento se espalhe para mais código.&lt;/li&gt;
&lt;li&gt;Injeção de dependência: para substituir uma dependência por um dublê de teste, ela precisa ser injetável (via construtor, geralmente) em vez de criada com &lt;code&gt;new&lt;/code&gt; dentro do método. Escrever o teste primeiro empurra você a programar contra abstrações desde o início — o "D" do SOLID (Dependency Inversion) emerge naturalmente.&lt;/li&gt;
&lt;li&gt;Interfaces pequenas e coesas: é mais fácil criar um dublê para uma interface com 2 métodos do que para uma com 20. TDD incentiva interfaces enxutas — o "I" do SOLID (Interface Segregation).&lt;/li&gt;
&lt;li&gt;Responsabilidade única: uma classe que faz muitas coisas gera testes longos, com muito Arrange, testando cenários não relacionados. Quando os testes ficam difíceis de nomear ou de entender, geralmente é sinal de que a classe sob teste deveria ser duas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você está lutando para testar algo, antes de recorrer a mocks cada vez mais elaborados, pergunte se o design não está pedindo para ser simplificado. Testabilidade e boas práticas de design andam juntas.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>testing</category>
    </item>
    <item>
      <title>Teste de Caixa Branca</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 17 Oct 2026 18:07:57 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/teste-de-caixa-branca-4g52</link>
      <guid>https://dev.to/yuripeixinho/teste-de-caixa-branca-4g52</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Teste de caixa branca (também chamado de estrutural, transparente ou &lt;em&gt;glass box&lt;/em&gt;) é o teste que se baseia na &lt;strong&gt;estrutura interna do código&lt;/strong&gt;. O testador conhece a implementação e projeta casos de teste para exercitar comandos, decisões, condições e caminhos específicos. A pergunta é: "o código foi exercitado o suficiente?". &lt;/p&gt;

&lt;p&gt;Se aplica principalmente em teste unitário e de integração, porque exige acesso ao código. Em geral é feito por quem desenvolve ou sabe ler o código.&lt;/p&gt;

&lt;p&gt;Este tipo de teste é fundamental para garantir que todos os caminhos e condições do código sejam devidamente validados, promovendo uma maior confiabilidade do sistema. Ele é particularmente importante para identificar erros em uma fase inicial do desenvolvimento, evitando problemas maiores no futuro. Ele envolve a análise minuciosa do código-fonte, verificando sua lógica e fluxos de execução.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Características Principais&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conhecimento do Código&lt;/strong&gt;: O testador precisa ter acesso ao código-fonte e um profundo conhecimento sobre a estrutura interna do aplicativo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cobertura de Código&lt;/strong&gt;: Foca na cobertura de código, incluindo instruções, ramos, caminhos e condições. A cobertura é medida em termos de elementos estruturais como declarações, decisões e interfaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Técnicas Comuns de Teste de Caixa-Branca&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Teste e Cobertura de Declarações&lt;/strong&gt;: Esta técnica foca em testar e avaliar a cobertura de todas as declarações individuais no código-fonte. O objetivo é garantir que cada linha de código seja executada pelo menos uma vez durante os testes. A fórmula de cobertura é: Cobertura = (declarações executadas) / (total de declarações).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teste e Cobertura de Decisões&lt;/strong&gt;: Nesta técnica, o objetivo é testar e garantir a cobertura de todas as decisões no código, como instruções condicionais (if, else, switch). O objetivo é garantir que todas as possíveis ramificações de decisão sejam exercitadas durante os testes. A fórmula de cobertura é: Cobertura = (resultados da decisão executados) / (resultados da decisão total).&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Critérios de cobertura
&lt;/h1&gt;

&lt;p&gt;Cada critério define o que significa "ter testado o suficiente". Do mais fraco ao mais forte:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Critério&lt;/th&gt;
&lt;th&gt;Exige que...&lt;/th&gt;
&lt;th&gt;Observação&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comandos (statement)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cada linha/comando execute ao menos uma vez&lt;/td&gt;
&lt;td&gt;O mais fraco: não garante que cada &lt;code&gt;if&lt;/code&gt; tenha sido avaliado como falso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decisões (branch)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cada decisão seja verdadeira e falsa ao menos uma vez&lt;/td&gt;
&lt;td&gt;Padrão de mercado como mínimo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Condições&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cada condição atômica (&lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; em &lt;code&gt;A &amp;amp;&amp;amp; B&lt;/code&gt;) seja verdadeira e falsa&lt;/td&gt;
&lt;td&gt;Pode passar sem cobrir os dois desfechos da decisão&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MC/DC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cada condição, sozinha, mude o resultado da decisão&lt;/td&gt;
&lt;td&gt;Exigido em software crítico (aviação, DO-178C); custa n+1 testes para n condições&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Caminhos (path)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Todas as combinações de caminhos sejam percorridas&lt;/td&gt;
&lt;td&gt;Inviável com loops: o número de caminhos explode&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>Fases e Níveis de Teste</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Thu, 15 Oct 2026 22:54:42 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/fases-e-niveis-de-teste-3dfc</link>
      <guid>https://dev.to/yuripeixinho/fases-e-niveis-de-teste-3dfc</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;A Pirâmide de Teste&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A pirâmide é o jeito mais comum de organizar os nívei de teste: cada camada enfatiza o volume de testes em relação à camada de cima. A base concentra muito mais testes do que o topo.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwxxtof7lp8861tj41hcu.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwxxtof7lp8861tj41hcu.png" alt=" " width="756" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma nuance prática da pirâmide: os níveis da base (Unidade e Integração) costumam ser automatizados via API/código; os níveis do topo (Sistema e Aceite) costumam ser automatizados via GUI (interface gráfica) — e testes via GUI são estruturalmente mais lentos e mais frágeis que testes via API, o que é mais um motivo para concentrar volume na base.&lt;/p&gt;

&lt;p&gt;O conceito por trás da pirâmide é simples: &lt;strong&gt;garantia da qualidade e teste antecipado em ação&lt;/strong&gt; (o shift-left). Cada nível exige um ambiente de teste adequado, idealmente reproduzindo a produção cada vez mais fielmente à medida que se sobe na pirâmide.&lt;/p&gt;

&lt;h1&gt;
  
  
  A intuição por trás de cada nível
&lt;/h1&gt;

&lt;p&gt;Antes da tabela detalhada, vale fixar o que cada nível realmente pergunta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unidade&lt;/strong&gt; — essa função/classe isolada faz o que deveria fazer?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integração&lt;/strong&gt; — A e B conversam direito entre si (formato de dado certo, ordem de chamada certa, timeout tratado)?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sistema&lt;/strong&gt; — o sistema inteiro, de ponta a ponta, isolado do resto do mundo, se comporta como esperado?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aceite&lt;/strong&gt; — a pergunta muda de natureza: não é mais "tem defeito?", é "isso resolve o problema de negócio?". Se um defeito aparece aqui, algo já deveria ter sido pego antes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Os quatro níveis, lado a lado&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nível&lt;/th&gt;
&lt;th&gt;Objetivo&lt;/th&gt;
&lt;th&gt;Base de teste&lt;/th&gt;
&lt;th&gt;Objetos de teste&lt;/th&gt;
&lt;th&gt;Falhas/defeitos típicos&lt;/th&gt;
&lt;th&gt;Responsabilidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Unidade&lt;/strong&gt; (Componente)&lt;/td&gt;
&lt;td&gt;Reduzir riscos, verificar comportamento de componentes, criar confiança, encontrar defeitos&lt;/td&gt;
&lt;td&gt;Design detalhado, código, modelo de dados, especificações de componente&lt;/td&gt;
&lt;td&gt;Componentes, unidades/módulos, estruturas de código e dados, classes&lt;/td&gt;
&lt;td&gt;Funcionalidade incorreta, problemas de fluxo de dados, código/lógica incorretos&lt;/td&gt;
&lt;td&gt;Geralmente o próprio desenvolvedor que escreveu o código&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integração&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reduzir riscos, verificar comportamentos de interface, criar confiança, encontrar defeitos&lt;/td&gt;
&lt;td&gt;Projeto de software/sistema, diagramas de sequência, especificações de interface, arquitetura&lt;/td&gt;
&lt;td&gt;Subsistemas, bancos de dados, infraestrutura, interfaces, APIs, microsserviços&lt;/td&gt;
&lt;td&gt;Dados incorretos/ausentes, sequenciamento/sincronização incorretos, incompatibilidade de interface, falhas de conformidade regulamentar&lt;/td&gt;
&lt;td&gt;Desenvolvedores (integração de componentes) e/ou testadores (integração de sistema)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sistema&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Verificar e validar comportamento de ponta a ponta, qualidade dos dados, atender requisitos regulamentares&lt;/td&gt;
&lt;td&gt;Requisitos funcionais/não funcionais, análise de risco, casos de uso, histórias&lt;/td&gt;
&lt;td&gt;Aplicativos, sistemas completos, configuração do sistema&lt;/td&gt;
&lt;td&gt;Comportamento funcional/não funcional incorreto, falhas de ponta a ponta, problemas de ambiente&lt;/td&gt;
&lt;td&gt;Testadores independentes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Aceite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Estabelecer confiança, avaliar prontidão para implantação, satisfazer requisitos legais/contratuais — normalmente não busca encontrar defeitos&lt;/td&gt;
&lt;td&gt;Processos de negócio, requisitos do usuário, regulamentos, contratos, documentação&lt;/td&gt;
&lt;td&gt;Sistema em teste, dados de configuração, processos de negócio, sistemas de recuperação&lt;/td&gt;
&lt;td&gt;Fluxos de trabalho que não atendem requisitos de negócio, regras de negócio mal implementadas, violação de requisitos contratuais&lt;/td&gt;
&lt;td&gt;Usuários de negócio, operações, ou auditores (conforme o tipo)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integração tem mais de um nível&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Na prática, "teste de integração" quase nunca é um nível único — um projeto costuma ter pelo menos dois:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integração de componentes&lt;/strong&gt;: testa a interação entre unidades/componentes. Segue o teste de unidade, geralmente automatizado, e costuma ser feito por quem desenvolveu o código.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integração de sistema&lt;/strong&gt;: testa a interação entre sistemas, pacotes e microsserviços. Pode se sobrepor ou seguir o teste de sistema, e é bem mais complexo — múltiplas organizações controlando interfaces diferentes torna qualquer mudança mais arriscada, processos de negócio podem abranger vários sistemas, e problemas de compatibilidade de hardware/sistema podem surgir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Risco adicional da integração de sistema: você geralmente &lt;strong&gt;não controla a outra ponta&lt;/strong&gt; — um sistema externo (como o ambiente da Receita Federal para e-Financeira) pode mudar contrato, formato ou disponibilidade sem aviso, e isso fica fora do seu controle de versionamento.&lt;/p&gt;

&lt;p&gt;Por isso, planejar a estratégia de integração (em que ordem os componentes/sistemas são combinados) &lt;strong&gt;antes&lt;/strong&gt; de construí-los tende a maximizar a eficiência do teste — integrar e testar em pequenos incrementos facilita isolar onde um defeito entrou.&lt;/p&gt;

&lt;h1&gt;
  
  
  Por que essa ordem importa
&lt;/h1&gt;

&lt;p&gt;O objetivo geral de cada nível anterior é evitar que defeitos escapem para o nível seguinte — ou pior, para produção. Um defeito pego no teste de unidade nunca chega a custar o que custaria se fosse pego só no teste de aceite.&lt;/p&gt;

&lt;p&gt;Pense em cada nível como uma &lt;strong&gt;barreira sequencial&lt;/strong&gt;: o trabalho dele é não deixar o defeito passar para a próxima camada. É a mesma curva de custo do Módulo 1, só que aplicada à pirâmide — um defeito pego na Unidade custa cerca de 1x; o mesmo defeito, pego só na Aceite (ou pior, em produção), pode custar perto de 100x.&lt;/p&gt;

&lt;p&gt;Este módulo ficou só na famíliarização com os níveis — como escrever, automatizar e organizar testes em cada um deles na prática (com código C#/xUnit do projeto) vem em módulos específicos mais adiante.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Tipos de Teste (ortogonais aos níveis)&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Até agora vimos &lt;strong&gt;onde&lt;/strong&gt; testamos (os quatro níveis da pirâmide). Agora entra &lt;strong&gt;o quê&lt;/strong&gt; e &lt;strong&gt;como&lt;/strong&gt; testamos — os tipos de teste. A diferença crucial: tipo de teste não é mais um nível, é um &lt;strong&gt;eixo ortogonal&lt;/strong&gt;. Você aplica qualquer tipo de teste dentro de qualquer nível, um teste de Unidade pode ser funcional ou não funcional, caixa-branca ou caixa-preta, e o mesmo vale para Integração, Sistema e Aceite.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fthqhmx2ako3le4zs5q2b.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fthqhmx2ako3le4zs5q2b.png" alt=" " width="774" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Estático x Dinâmico
&lt;/h3&gt;

&lt;p&gt;Teste &lt;strong&gt;estático&lt;/strong&gt; avalia o artefato &lt;strong&gt;sem executar o código&lt;/strong&gt;: análise estática (ferramentas que inspecionam o código em busca de padrões problemáticos) e revisão (leitura humana — code review, walkthrough, inspeção formal). Teste &lt;strong&gt;dinâmico&lt;/strong&gt; exige &lt;strong&gt;executar&lt;/strong&gt; o código ou sistema — é o que normalmente vem à mente quando se fala em "teste".&lt;/p&gt;

&lt;p&gt;Dentro do teste dinâmico, existem três abordagens de &lt;strong&gt;design&lt;/strong&gt; de caso de teste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Caixa-branca (estrutural)&lt;/strong&gt; — deriva casos de teste a partir da estrutura interna/implementação. Mede cobertura estrutural (ex.: % do código de um componente exercitado, % de interfaces testadas numa integração).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caixa-preta (comportamental)&lt;/strong&gt; — deriva casos de teste a partir de especificação/comportamento esperado, sem olhar para o código por dentro. Se divide em &lt;strong&gt;funcional&lt;/strong&gt; (testa &lt;em&gt;o quê&lt;/em&gt; o sistema faz) e &lt;strong&gt;não funcional&lt;/strong&gt; (testa &lt;em&gt;quão bem&lt;/em&gt; o sistema faz o que faz — desempenho, usabilidade, confiabilidade, segurança, portabilidade).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baseado em experiência&lt;/strong&gt; — usa o conhecimento e a intuição de quem testa (bugs comuns, histórico do sistema, heurísticas), em vez de uma técnica formal derivada de especificação ou de código.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma distinção à parte, que às vezes se confunde com essas três: &lt;strong&gt;design de teste&lt;/strong&gt; (decidir quais casos escrever) e &lt;strong&gt;execução de teste&lt;/strong&gt; (rodar esses casos) são duas atividades diferentes do processo, não um tipo de teste — qualquer um dos três tipos acima passa por ambas.]&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Funcional x Não funcional, nível por nível&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O mesmo nível da pirâmide pode receber os dois tipos, testando coisas completamente diferentes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nível&lt;/th&gt;
&lt;th&gt;Exemplo funcional ("o quê")&lt;/th&gt;
&lt;th&gt;Exemplo não funcional ("quão bem")&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Componente&lt;/td&gt;
&lt;td&gt;Calcula os juros compostos corretamente&lt;/td&gt;
&lt;td&gt;Desempenho: ciclos de CPU para um cálculo de juros complexo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração de componentes&lt;/td&gt;
&lt;td&gt;Repassa os dados da conta capturados na interface para a lógica de negócio&lt;/td&gt;
&lt;td&gt;Segurança: vulnerabilidade de estouro de buffer nos dados que trafegam da UI para a lógica&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sistema&lt;/td&gt;
&lt;td&gt;Correntista consegue solicitar uma linha de crédito na conta&lt;/td&gt;
&lt;td&gt;Portabilidade: a camada de apresentação funciona em todos os navegadores/dispositivos suportados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração de sistema&lt;/td&gt;
&lt;td&gt;Sistema consulta um microsserviço externo de pontuação de crédito&lt;/td&gt;
&lt;td&gt;Confiabilidade: robustez se o microsserviço de pontuação não responder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aceite&lt;/td&gt;
&lt;td&gt;Banqueiro aprova ou recusa um pedido de crédito&lt;/td&gt;
&lt;td&gt;Usabilidade: acessibilidade da interface de crédito para pessoas com deficiência&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Caixa-branca, nível por nível&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nível&lt;/th&gt;
&lt;th&gt;Exemplo de teste caixa-branca&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Componente&lt;/td&gt;
&lt;td&gt;Cobertura de declaração e de decisão para os componentes que fazem cálculos financeiros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração de componentes&lt;/td&gt;
&lt;td&gt;Exercitar como cada tela repassa dados para a próxima tela e para a lógica de negócio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sistema&lt;/td&gt;
&lt;td&gt;Cobrir as sequências de páginas possíveis num fluxo de solicitação de crédito&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração de sistema&lt;/td&gt;
&lt;td&gt;Exercitar todos os tipos de consulta enviados ao microsserviço de pontuação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aceite&lt;/td&gt;
&lt;td&gt;Cobrir todas as estruturas de arquivo de dados financeiros suportadas e as faixas de valores de transferência&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Teste relacionado à mudança: confirmação e regressão&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Esse é o quinto tipo, e também se aplica a &lt;strong&gt;todos&lt;/strong&gt; os níveis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Teste de confirmação&lt;/strong&gt; — verifica se um defeito específico, já identificado, foi de fato corrigido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teste de regressão&lt;/strong&gt; — verifica que a correção (ou qualquer mudança) &lt;strong&gt;não quebrou&lt;/strong&gt; algo que já funcionava antes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como são executados com alta frequência e evoluem devagar, são fortes candidatos a automação — mas vale lembrar a pirâmide: a automação deve começar pelos níveis de baixo (Unidade/Integração), não pelo topo.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nível&lt;/th&gt;
&lt;th&gt;Exemplo de teste relacionado à mudança&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Componente&lt;/td&gt;
&lt;td&gt;Testes de regressão automatizados por componente, incluídos na esteira de integração contínua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração de componentes&lt;/td&gt;
&lt;td&gt;Confirmar que uma correção de interface não quebrou o repositório de código&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sistema&lt;/td&gt;
&lt;td&gt;Reexecutar todos os testes de um fluxo sempre que qualquer tela daquele fluxo mudar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração de sistema&lt;/td&gt;
&lt;td&gt;Reexecutar diariamente os testes de interação com o microsserviço externo, como parte do deploy contínuo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aceite&lt;/td&gt;
&lt;td&gt;Reexecutar os testes que antes falharam, depois que o defeito encontrado na aceitação for corrigido&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Por que isso é um eixo, não mais um nível
&lt;/h3&gt;

&lt;p&gt;Uma estratégia de teste madura pensa numa &lt;strong&gt;matriz&lt;/strong&gt;: nível (Unidade/Integração/Sistema/Aceite) cruzado com tipo (funcional/não funcional/caixa-branca/caixa-preta/baseado em experiência/relacionado à mudança) — não numa lista linear. As técnicas formais de como derivar casos de teste caixa-preta e caixa-branca (particionamento de equivalência, valor-limite, cobertura de código)&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que essa ordem importa
&lt;/h2&gt;

&lt;p&gt;O objetivo geral de cada nível anterior é evitar que defeitos escapem para o nível seguinte — ou pior, para produção. Um defeito pego no teste de unidade nunca chega a custar o que custaria se fosse pego só no teste de aceite (o Módulo 1 já mostrou essa curva de custo crescente com números).&lt;/p&gt;

&lt;p&gt;Pense em cada nível como uma &lt;strong&gt;barreira sequencial&lt;/strong&gt;: o trabalho dele é não deixar o defeito passar para a próxima camada. É a mesma curva de custo do Módulo 1, só que aplicada à pirâmide — um defeito pego na Unidade custa cerca de 1x; o mesmo defeito, pego só na Aceite (ou pior, em produção), pode custar perto de 100x.&lt;/p&gt;

&lt;p&gt;Este módulo ficou só na famíliarização com os níveis — como escrever, automatizar e organizar testes em cada um deles na prática (com código C#/xUnit do projeto).&lt;/p&gt;

</description>
      <category>automation</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>Cobertura de Código e Práticas de Mercado</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Tue, 13 Oct 2026 19:06:31 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/cobertura-de-codigo-e-pratiacas-de-mercado-5c2d</link>
      <guid>https://dev.to/yuripeixinho/cobertura-de-codigo-e-pratiacas-de-mercado-5c2d</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Como já sabemos, o teste caixa-branca deriva casos a partir da estrutura interna do código, e que cobertura mede isso. Mas a “cobertura” não é um número único, são pelo menos três métricas diferentes, que respondem perguntas diferentes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Pergunta que responde&lt;/th&gt;
&lt;th&gt;Granularidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Statement/Line coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Essa linha foi executada ao menos uma vez?&lt;/td&gt;
&lt;td&gt;A mais grosseira&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Branch/Decision coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cada desvio condicional (if/else, switch, operador ternário) foi exercitado nos dois sentidos?&lt;/td&gt;
&lt;td&gt;Intermediária&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Method/Function coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Esse método foi chamado ao menos uma vez?&lt;/td&gt;
&lt;td&gt;A mais grosseira de todas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Isso importa porque 100% de line coverage não significa 100% de branch coverage. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt; &lt;span class="nc"&gt;PodeContratar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt; &lt;span class="nx"&gt;temCpfValido&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="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;temCpfValido&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;Com um único teste — &lt;code&gt;PodeContratar(20, true)&lt;/code&gt; — a linha do método roda inteira: &lt;strong&gt;line coverage = 100%&lt;/strong&gt;. Mas a expressão booleana só tomou o caminho "verdadeiro"; o caminho "falso" (disparado por idade &amp;lt; 18 &lt;strong&gt;ou&lt;/strong&gt; CPF inválido) nunca foi exercitado. &lt;strong&gt;Branch coverage real aqui é 50%&lt;/strong&gt; — metade dos desvios possíveis daquela decisão nunca rodou, mesmo com a linha 100% coberta.&lt;/p&gt;

&lt;p&gt;É por isso que ferramentas sérias de cobertura, como o Coverlet, reportam line e branch separadamente e o segundo número costuma ser mais honesto sobre o que realmente foi testado.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Por que % de cobertura sozinha não prova qualidade&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Cobertura é &lt;strong&gt;sinalizador de ausência&lt;/strong&gt; ("essa linha nunca rodou"), não &lt;strong&gt;prova de correção&lt;/strong&gt; ("essa linha está certa"). Um teste pode exercitar 100% das linhas de um método sem afirmar nada sobre o resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nc"&gt;CalcularDesconto_NaoEstoura&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CalcularDesconto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&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="c1"&gt;// nenhum Assert sobre o valor retornado — só "não jogou exceção"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa linha conta como "coberta" pra qualquer ferramenta de cobertura, mesmo que o teste nunca verifique se o valor calculado está certo. Esse é exatamente o "teatro de métricas" que vimos no Módulo 1: cobrar % de cobertura como meta isolada incentiva esse tipo de teste vazio — ele sobe o número sem provar nada.&lt;/p&gt;

&lt;p&gt;A forma honesta de saber se os testes realmente &lt;em&gt;provam&lt;/em&gt; algo é o &lt;strong&gt;mutation testing&lt;/strong&gt; (Módulo 13 do roteiro): a ferramenta injeta bugs artificiais no código (troca &lt;code&gt;&amp;gt;&lt;/code&gt; por &lt;code&gt;&amp;gt;=&lt;/code&gt;, troca &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; por &lt;code&gt;||&lt;/code&gt;, inverte uma condição) e verifica se &lt;strong&gt;algum&lt;/strong&gt; teste falha. Se nenhum falhar, aquele trecho está "coberto" mas não está "testado" de verdade. Cobertura e mutation score respondem perguntas diferentes e complementares — cobertura diz &lt;em&gt;o quê roda&lt;/em&gt;, mutation score diz &lt;em&gt;o quê prova algo&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Práticas de mercado&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Não existe um número universal, mas um padrão dominante.&lt;/p&gt;

&lt;p&gt;"Qual % é o padrão do mercado" tem uma resposta mais sutil que um número fixo. A prática que mais se consolidou nos últimos anos não é "todo o repositório precisa de X%" — é medir cobertura &lt;strong&gt;só no código novo&lt;/strong&gt; ("coverage on new code" / "diff coverage" / "patch coverage").&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ferramenta&lt;/th&gt;
&lt;th&gt;Como chama o conceito&lt;/th&gt;
&lt;th&gt;Valor default comum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SonarQube/SonarCloud (quality gate "Sonar Way")&lt;/td&gt;
&lt;td&gt;Coverage on New Code&lt;/td&gt;
&lt;td&gt;≥ 80%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codecov&lt;/td&gt;
&lt;td&gt;Patch coverage&lt;/td&gt;
&lt;td&gt;70–80% (configurável)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coveralls&lt;/td&gt;
&lt;td&gt;Coverage diff&lt;/td&gt;
&lt;td&gt;configurável, sem default fixo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Por que isso virou o padrão dominante em vez de "% do repositório inteiro": um arquivo legado com 20% de cobertura não deveria travar um fix de 2 linhas feito hoje, mas essas 2 linhas deveriam estar cobertas. Cobrar % total do repositório pune código antigo que ninguém vai reescrever, e isso empurra o time a burlar a métrica (excluir arquivos do cálculo, escrever teste vazio só pra subir número). Cobrar só o código que mudou é objetivamente mais justo e mais difícil de contornar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Código novo em geral&lt;/strong&gt;: 70–80% é o número mais citado como "saudável" por times maduros — nem 0% (sem rede de segurança), nem 100% (raramente vale o custo marginal).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Código crítico/regulado&lt;/strong&gt; (cálculo fiscal, financeiro, de saúde): times costumam exigir mais — 90%+ de linha, combinado com mutation score mais alto, porque o custo de um defeito escapar é desproporcional (a e-Financeira tem fiscalização da Receita, como vimos no Módulo 1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Código de "cola"&lt;/strong&gt; (DI, mapeamento simples, controllers finos): cobertura alta aqui tem retorno marginal baixo — times maduros não forçam o mesmo número.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutation score&lt;/strong&gt;, quando adotado, normalmente é configurado &lt;strong&gt;abaixo&lt;/strong&gt; do número de cobertura de linha (ex.: cobertura 80% + mutation score 60%), porque matar mutante é um critério mais rígido — cobrar o mesmo número nos dois é irrealista.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>Teste de Caixa Preta</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sat, 10 Oct 2026 18:09:41 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/teste-de-caixa-preta-3k3j</link>
      <guid>https://dev.to/yuripeixinho/teste-de-caixa-preta-3k3j</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Teste de caixa preta é o teste que avalia o software &lt;strong&gt;apenas pelo comportamento externo&lt;/strong&gt;: você fornece entradas, observa as saídas e compara com o resultado esperado pela especificação. O testador não olha o código-fonte, a estrutura interna nem a lógica de implementação.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que ele valida?
&lt;/h1&gt;

&lt;p&gt;Os testes se baseiam em requisitos, regras de negócio, casos de uso e user stories, e não no código. Por isso o teste vale para qualquer nível (unitário, integração, sistema, aceitação) e para testes funcionais e não funcionais.&lt;/p&gt;

&lt;h1&gt;
  
  
  Técnicas Principais
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Técnica&lt;/th&gt;
&lt;th&gt;Ideia&lt;/th&gt;
&lt;th&gt;Exemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Particionamento de equivalência&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Divide as entradas em classes que o sistema deve tratar igual; testa um valor por classe&lt;/td&gt;
&lt;td&gt;Idade aceita de 18 a 65: classes &lt;code&gt;&amp;lt;18&lt;/code&gt; (inválida), &lt;code&gt;18–65&lt;/code&gt; (válida), &lt;code&gt;&amp;gt;65&lt;/code&gt; (inválida)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Análise de valor limite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Testa as bordas das partições, onde os defeitos se concentram&lt;/td&gt;
&lt;td&gt;17, 18, 65, 66&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tabela de decisão&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mapeia combinações de condições para ações&lt;/td&gt;
&lt;td&gt;Desconto depende de cliente VIP + valor da compra + cupom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transição de estados&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Testa mudanças de estado e quais são permitidas&lt;/td&gt;
&lt;td&gt;Pedido: criado → pago → enviado; "enviado → criado" deve ser rejeitado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Casos de uso / cenários&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Percorre fluxos completos do usuário&lt;/td&gt;
&lt;td&gt;Login → adicionar ao carrinho → checkout&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Exemplo concreto
&lt;/h3&gt;

&lt;p&gt;Regra: &lt;em&gt;"Frete grátis para compras a partir de R$ 200,00."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sem ver o código, você testa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;R$ 199,99 → cobra frete&lt;/li&gt;
&lt;li&gt;R$ 200,00 → frete grátis (valor limite)&lt;/li&gt;
&lt;li&gt;R$ 200,01 → frete grátis&lt;/li&gt;
&lt;li&gt;R$ 0,00 e valor negativo → rejeita ou trata como inválido&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O código pode estar escrito de qualquer forma. O que importa é se o comportamento bate com a regra.&lt;/p&gt;

&lt;h1&gt;
  
  
  Vantagens e limitações
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Vantagens&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Independe da linguagem e da implementação.&lt;/li&gt;
&lt;li&gt;Testa do ponto de vista do usuário.&lt;/li&gt;
&lt;li&gt;Pode ser feito por quem não programa.&lt;/li&gt;
&lt;li&gt;Os casos de teste podem ser escritos assim que a especificação existe, antes do código.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Limitações&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Não garante cobertura do código: ramos internos podem nunca ser executados.&lt;/li&gt;
&lt;li&gt;Especificação ambígua ou incompleta gera testes ruins.&lt;/li&gt;
&lt;li&gt;É difícil identificar a causa exata de uma falha só pela saída.&lt;/li&gt;
&lt;li&gt;Sem técnica, há risco de testes redundantes ou de lacunas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contraste com caixa branca
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Caixa preta:&lt;/strong&gt; parte da especificação e mede cobertura de requisitos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caixa branca:&lt;/strong&gt; parte do código e mede cobertura de código (comandos, decisões, caminhos).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caixa cinza:&lt;/strong&gt; combina os dois, com conhecimento parcial da estrutura interna (por exemplo, saber o schema do banco ao testar uma API).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Na prática, os dois se complementam: a caixa preta encontra o que não está de acordo com o requisito, e a caixa branca encontra o que o requisito nem previa.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>[FRONTEND] Tipos de Component/Libraries</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 09 Oct 2026 20:51:16 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/frontend-tipos-de-componentlibraries-iog</link>
      <guid>https://dev.to/yuripeixinho/frontend-tipos-de-componentlibraries-iog</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;As bibliotecas de componentes React são coleções de componentes pré-construídos e reutilizáveis que podem ser usados para acelerar o processo de desenvolvimento. Elas podem ser estilizadas usando CSS de várias maneiras, incluindo arquivos CSS tradicionais, módulos CSS e soluções CSS-in-JS como styled-components.&lt;/p&gt;

&lt;p&gt;Na prática, essas bibliotecas se dividem em três grupos, conforme a relação entre lógica, aparência e controle que entregam ao desenvolvedor.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bibliotecas estilizadas (styled)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Entregam componentes prontos, com identidade visual definida. O exemplo mais conhecido é o Material UI (MUI), baseado no Material Design do Google. Ant Design e Chakra UI seguem a mesma linha. O ganho é velocidade: botões, modais, tabelas e formulários já vêm consistentes entre si. O custo é a personalização: fugir do visual padrão exige sobrescrever temas e estilos internos, e o bundle tende a ser maior.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bibliotecas headless (sem estilo)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Fornecem apenas comportamento e acessibilidade: gerenciamento de foco, navegação por teclado, atributos ARIA, estados de abertura e fechamento. Radix UI, React Aria e Headless UI são os principais exemplos. O desenvolvedor aplica o próprio CSS, seja com Tailwind, CSS Modules ou styled-components. Isso garante controle total do design sem reimplementar acessibilidade, que é a parte mais difícil de acertar em componentes como dropdowns, dialogs e comboboxes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Modelo copy-and-paste&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O shadcn/ui popularizou uma abordagem diferente: em vez de instalar um pacote, o código dos componentes é copiado para o projeto. Os componentes são construídos sobre Radix UI e estilizados com Tailwind CSS. Como o código passa a pertencer ao projeto, não há dependência de versão da biblioteca nem limitação para modificar a implementação. A contrapartida é que atualizações e correções precisam ser aplicadas manualmente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estilização: como as abordagens se encaixam&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CSS tradicional:&lt;/strong&gt; simples e universal, mas com escopo global, o que facilita colisão de nomes em projetos grandes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Modules:&lt;/strong&gt; o escopo é local por arquivo, com nomes de classe gerados automaticamente. Não exige runtime adicional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS-in-JS (styled-components, Emotion):&lt;/strong&gt; estilos definidos dentro do componente, com suporte a props dinâmicas e temas. Em contrapartida, há custo de runtime, e o suporte a React Server Components é limitado em bibliotecas que dependem de injeção de estilos em tempo de execução.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility-first (Tailwind CSS):&lt;/strong&gt; classes utilitárias aplicadas diretamente na marcação, sem runtime e com bom tree-shaking do CSS final.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Critérios de escolha&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A decisão depende de alguns fatores objetivos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Nível de customização exigido:&lt;/strong&gt; design system próprio favorece headless ou copy-and-paste; MVP ou painel administrativo favorece uma biblioteca estilizada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acessibilidade:&lt;/strong&gt; componentes complexos devem vir de bibliotecas que já tratem ARIA e teclado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tamanho do bundle e performance:&lt;/strong&gt; bibliotecas com runtime de CSS-in-JS pesam mais que soluções com CSS estático.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibilidade com o ecossistema:&lt;/strong&gt; SSR, Next.js e Server Components restringem algumas escolhas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manutenção e comunidade:&lt;/strong&gt; frequência de releases, qualidade da documentação e tamanho da base de usuários.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Não existe uma biblioteca universalmente melhor. Bibliotecas estilizadas reduzem o tempo até a primeira entrega, enquanto headless e copy-and-paste trocam esse ganho inicial por flexibilidade a longo prazo. A escolha correta parte do contexto do produto: quanto o design precisa divergir do padrão, qual o prazo e quem vai manter o código.&lt;/p&gt;

</description>
      <category>css</category>
      <category>frontend</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Tailwind CSS</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 09 Oct 2026 20:44:27 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/tailwind-css-37gk</link>
      <guid>https://dev.to/yuripeixinho/tailwind-css-37gk</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Tailwind CSS é um framework CSS&amp;nbsp;&lt;strong&gt;utility-first&lt;/strong&gt;&amp;nbsp;(utilitário em primeiro lugar) que fornece centenas de classes de baixo nível diretamente no seu HTML para construir qualquer design — sem precisar escrever CSS personalizado.&lt;/p&gt;

&lt;p&gt;Diferente de frameworks como Bootstrap ou Foundation, o Tailwind&amp;nbsp;&lt;strong&gt;não oferece componentes prontos&lt;/strong&gt;&amp;nbsp;(botões, cards, modais pré-estilizados). Em vez disso, ele fornece&amp;nbsp;&lt;em&gt;primitivos&lt;/em&gt;&amp;nbsp;(utilitários) que você combina para criar qualquer interface que imaginar.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS Tradicional
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* style.css */&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;botao&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;b82f6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.375&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="na"&gt;html&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"meu-botao"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Clique aqui
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Com Tailwing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;Tudo&lt;/span&gt; &lt;span class="na"&gt;inline&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sem&lt;/span&gt; &lt;span class="na"&gt;CSS&lt;/span&gt; &lt;span class="na"&gt;separado&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; 
  &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;bg-blue-500&lt;/span&gt; &lt;span class="na"&gt;text-white&lt;/span&gt; 
         &lt;span class="na"&gt;px-4&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt; &lt;span class="na"&gt;rounded-md&lt;/span&gt; 
         &lt;span class="na"&gt;font-semibold&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Clique aqui
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Tailwind, você estiliza&amp;nbsp;diretamente no HTML*.* Cada classe CSS faz uma única coisa — como&amp;nbsp;&lt;code&gt;flex&lt;/code&gt;,&amp;nbsp;&lt;code&gt;text-center&lt;/code&gt;,&amp;nbsp;&lt;code&gt;mt-4&lt;/code&gt;,&amp;nbsp;&lt;code&gt;rounded-lg&lt;/code&gt;. Você combina várias para criar qualquer visual.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;A Filosofia Utility-First&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A ideia central é simples: ao invés de criar classes semânticas como&amp;nbsp;&lt;code&gt;.card&lt;/code&gt;&amp;nbsp;ou&amp;nbsp;&lt;code&gt;.header-title&lt;/code&gt;, você usa classes utilitárias de propósito único diretamente no HTML.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nomes previsíveis:&lt;/strong&gt; propriedade + valor.&amp;nbsp;&lt;code&gt;text-lg&lt;/code&gt;,&amp;nbsp;&lt;code&gt;mt-4&lt;/code&gt;,&amp;nbsp;&lt;code&gt;bg-red-500&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sem Side Effects: c&lt;/strong&gt;ada classe afeta somente a propriedade que diz. Não há cascata inesperada ou especificidade problemática.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Velocidade de Dev:&lt;/strong&gt; você não para para nomear classes ou alternar arquivos. HTML e estilo ficam no mesmo lugar.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"max-w-sm rounded-2xl overflow-hidden shadow-xl bg-white p-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-16 h-16 rounded-full mx-auto"&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"foto.jpg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-xl font-bold text-center text-gray-800 mt-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Maria Silva&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-500 text-center text-sm mt-1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Desenvolvedora&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;mt-4&lt;/span&gt; &lt;span class="na"&gt;w-full&lt;/span&gt; &lt;span class="na"&gt;bg-blue-500&lt;/span&gt; &lt;span class="na"&gt;hover&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;bg-blue-600&lt;/span&gt; 
               &lt;span class="na"&gt;text-white&lt;/span&gt; &lt;span class="na"&gt;font-semibold&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt; &lt;span class="na"&gt;rounded-xl&lt;/span&gt; &lt;span class="na"&gt;transition&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    Seguir
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;!image.png&lt;/p&gt;

&lt;h1&gt;
  
  
  Instalação e Configuração
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Método Recomendado — npm/yarn (v3)&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="nx"&gt;postcss&lt;/span&gt; &lt;span class="nx"&gt;autoprefixer&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Gere&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;arquivo&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;configuração&lt;/span&gt;
&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Configure o&amp;nbsp;&lt;code&gt;tailwind.config.js&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {import('tailwindcss').Config} */&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/**/*.{html,js,jsx,ts,tsx,vue}&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="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Suas customizações aqui&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plugins&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;h2&gt;
  
  
  Adicione as diretivas no seu CSS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* src/input.css */&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="cm"&gt;/* Reset e estilos base */&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* Classes de componentes */&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="cm"&gt;/* Classes utilitárias */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Execute o build
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Modo&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;desenvolvimento &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;watch&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Build&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nf"&gt;produção &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;minificado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;minify&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;strong&gt;Anatomia das Classes&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;As classes do Tailwind seguem um padrão consistente. Aprendendo a lógica, você consegue intuir classes que nunca viu antes.&lt;/p&gt;

&lt;p&gt;!image.png&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;text-xl&lt;/code&gt;: font-size: 1.25rem&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bg-blue-500&lt;/code&gt;: background-color: #3b82f6&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mt-4&lt;/code&gt;: margin-top: 1rem&lt;/p&gt;

&lt;p&gt;&lt;code&gt;p-6&lt;/code&gt;: padding: 1.5rem&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rounded-2xl&lt;/code&gt;: border-radius: 1rem&lt;/p&gt;

&lt;p&gt;&lt;code&gt;flex items-center&lt;/code&gt;: display: flex + align-items&lt;/p&gt;

&lt;h2&gt;
  
  
  A escala de espaçamento
&lt;/h2&gt;

&lt;p&gt;Tailwind usa múltiplos de&amp;nbsp;&lt;code&gt;0.25rem (4px)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 = 4px
2 = 8px
4 = 16px
8 = 32px
12 = 48px
16 = 64px
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Design Responsivo
&lt;/h1&gt;

&lt;p&gt;Tailwind usa uma abordagem&amp;nbsp;&lt;strong&gt;mobile-first&lt;/strong&gt;. Classes sem prefixo se aplicam a todas as telas. Para aplicar a telas maiores, use prefixos de breakpoint.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prefixo&lt;/th&gt;
&lt;th&gt;Largura mínima&lt;/th&gt;
&lt;th&gt;Dispositivo&lt;/th&gt;
&lt;th&gt;CSS gerado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(nenhum)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0px&lt;/td&gt;
&lt;td&gt;Mobile&lt;/td&gt;
&lt;td&gt;sem media query&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sm:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;640px&lt;/td&gt;
&lt;td&gt;Tablet pequeno&lt;/td&gt;
&lt;td&gt;
&lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (min-width: 640px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;md:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;768px&lt;/td&gt;
&lt;td&gt;Tablet&lt;/td&gt;
&lt;td&gt;
&lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (min-width: 768px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lg:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1024px&lt;/td&gt;
&lt;td&gt;Desktop pequeno&lt;/td&gt;
&lt;td&gt;
&lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (min-width: 1024px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;xl:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1280px&lt;/td&gt;
&lt;td&gt;Desktop&lt;/td&gt;
&lt;td&gt;
&lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (min-width: 1280px)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2xl:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1536px&lt;/td&gt;
&lt;td&gt;Desktop grande&lt;/td&gt;
&lt;td&gt;
&lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (min-width: 1536px)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;Mobile&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="na"&gt;1&lt;/span&gt; &lt;span class="na"&gt;coluna&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="na"&gt;Tablet&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="na"&gt;2&lt;/span&gt; &lt;span class="na"&gt;colunas&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="na"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="na"&gt;4&lt;/span&gt; &lt;span class="na"&gt;colunas&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  ...
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;Texto&lt;/span&gt; &lt;span class="na"&gt;muda&lt;/span&gt; &lt;span class="na"&gt;de&lt;/span&gt; &lt;span class="na"&gt;tamanho&lt;/span&gt; &lt;span class="na"&gt;com&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt; &lt;span class="na"&gt;tela&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl md:text-4xl lg:text-6xl font-bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Título responsivo
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;Mostrar&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;esconder&lt;/span&gt; &lt;span class="na"&gt;por&lt;/span&gt; &lt;span class="na"&gt;tela&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hidden md:flex"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Nav Desktop&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"md:hidden"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Menu Mobile&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pense&amp;nbsp;&lt;strong&gt;mobile-first&lt;/strong&gt;: projete para telas pequenas, depois adicione prefixos para telas maiores. Classes sem prefixo = para TODAS as telas.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;✅ Vantagens do Tailwind CSS&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;1. Produtividade extremamente alta&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você nunca para para nomear classes, criar arquivos CSS ou alternar contextos. Estiliza diretamente no HTML com classes intuitivas. A maioria dos devs relata velocidade 2–3x maior no desenvolvimento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. CSS de produção minúsculo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O JIT gera apenas o CSS que você realmente usa. Sites típicos chegam com 5–20kb de CSS, versus 200kb+ do Bootstrap. Melhora diretamente performance e Core Web Vitals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Design system incorporado&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paleta de cores, escala tipográfica, espaçamento e breakpoints já vêm coerentes e configuráveis. Você tem um sistema de design embutido desde o primeiro dia, sem precisar criar do zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Sem conflitos de especificidade CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Classes utilitárias têm especificidade idêntica. Acabou o pesadelo de &lt;code&gt;!important&lt;/code&gt; e cascata inesperada. Mudanças têm efeito previsível e localizado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Dark mode, responsividade e estados — tudo integrado&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Essas funcionalidades funcionam com qualquer utilitário via prefixos (&lt;code&gt;dark:&lt;/code&gt;, &lt;code&gt;md:&lt;/code&gt;, &lt;code&gt;hover:&lt;/code&gt;). Sem escrever media queries manualmente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Altamente customizável sem perder o padrão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você adiciona ou sobrescreve apenas o que precisa via &lt;code&gt;theme.extend&lt;/code&gt;. O restante continua disponível, ao contrário de frameworks onde você reescreve tudo do zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Ecossistema e comunidade gigantes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tailwind UI, Headless UI, shadcn/ui, DaisyUI — o ecossistema é vasto. Suporte nativo em Next.js, Nuxt, SvelteKit, Astro e outros frameworks modernos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Curva de aprendizado baixa para quem já sabe CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As classes seguem a nomenclatura do próprio CSS. Quem já conhece CSS aprende Tailwind em 1–2 dias. A documentação oficial é excelente e fácil de pesquisar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. HTML como fonte da verdade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Todo o estilo fica no próprio HTML/componente. Para entender como algo foi estilizado, basta olhar o elemento — sem precisar caçar em arquivos CSS desconexos.&lt;/p&gt;

&lt;h1&gt;
  
  
  ❌ Desvantagens do Tailwind CSS
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;1. HTML verboso e difícil de ler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Classes longas tornam o markup difícil de escanear. Um botão simples pode ter 15+ classes numa linha só, o que polui a leitura do HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Requer aprendizado da nomenclatura específica&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Desenvolvedores que sabem CSS mas não Tailwind precisam decorar os nomes das classes. Sem o plugin IntelliSense no editor, a produtividade cai bastante — o plugin se torna quase obrigatório.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Não é ideal para designs muito fora do padrão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se o seu projeto exige animações complexas, layouts muito únicos ou CSS avançado, você vai lutar contra o framework. CSS puro pode ser mais direto nesses casos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Duplicação sem componentização&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Em HTML puro (sem framework JS), reutilizar estilos fica trabalhoso. O Tailwind foi projetado pensando em componentes (React, Vue, etc.) — sem isso, o &lt;code&gt;@apply&lt;/code&gt; vira muleta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Exige configuração de build&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Requer PostCSS, Vite ou Webpack. Não dá simplesmente um &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; de CDN e começa a usar em produção. Para projetos simples, o Bootstrap é mais plug-and-play.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Sem componentes prontos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tailwind puro não entrega botão, modal, navbar ou dropdown prontos. Você constrói tudo ou depende de uma biblioteca adicional (shadcn/ui, DaisyUI, etc.). Para protótipos rápidos sem design system, outros frameworks podem ser mais ágeis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Não funciona bem com emails HTML&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Templates de email têm restrições severas de CSS inline. O Tailwind não foi projetado para esse caso de uso e exige adaptações significativas.&lt;/p&gt;

</description>
      <category>css</category>
      <category>frontend</category>
      <category>tailwindcss</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Teste de Manutenção</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Fri, 09 Oct 2026 00:34:46 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/teste-de-manutencao-4dmf</link>
      <guid>https://dev.to/yuripeixinho/teste-de-manutencao-4dmf</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;O teste de manutenção é uma atividade fundamental no ciclo de vida do software. Uma vez que o software é implantado, ele deve ser mantido para garantir que continue funcionando conforme o esperado, mesmo após várias modificações. Essas mudanças podem incluir melhorias, correções de bugs ou adaptações ao novo ambiente operacional. A manutenção eficaz do software é essencial para garantir a longevidade e a qualidade contínua dos sistemas.&lt;/p&gt;

&lt;p&gt;O teste de manutenção envolve a verificação de alterações e a garantia de que essas mudanças não introduzam novos problemas. Além disso, é necessário garantir que as funcionalidades existentes ainda funcionem corretamente. Este tipo de teste é crítico para manter a confiança dos usuários no software e para evitar falhas inesperadas que possam causar interrupções significativas.&lt;/p&gt;

&lt;p&gt;Existem diferentes tipos de testes de manutenção, que variam em termos de escopo e complexidade, dependendo do risco associado à mudança, do tamanho do sistema e da extensão da modificação. É importante abordar esses testes de forma estruturada para identificar possíveis impactos e mitigar riscos de regressão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gatilhos típicos que levam a necessidade de um teste de regressão
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modificação&lt;/strong&gt;: é o motivo mais comum. Inclui melhorias (novas funcionalidades), correções de bugs e adaptações causadas por mudanças no ambiente operacional (por exemplo, uma atualização do sistema operacional, do banco de dados ou de uma biblioteca externa).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migração&lt;/strong&gt;: ocorre quando o software passa a ser executado em um novo ambiente suportado — troca de plataforma, de infraestrutura (ex: migração para nuvem) ou de versão de uma tecnologia base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aposentadoria (retirement)&lt;/strong&gt;: acontece quando um subsistema, ou o sistema inteiro, chega ao fim de sua vida útil e precisa ser substituído. Mesmo nesse cenário, testes são necessários — por exemplo, para validar a migração de dados ou garantir que o sistema substituto cobre as funcionalidades do antigo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um ponto importante é que o teste de manutenção não olha apenas para a alteração em si. Ele também precisa verificar &lt;strong&gt;o que não foi alterado e não deveria mudar&lt;/strong&gt; — ou seja, garantir que o restante do sistema permaneça estável. Além disso, o &lt;strong&gt;tamanho da mudança&lt;/strong&gt; influencia diretamente o escopo do teste, mas deve ser tratado com cautela: uma alteração pequena em código pode ter um impacto desproporcionalmente grande no comportamento do sistema, então o tamanho não deve ser o único critério usado para dimensionar o esforço de teste.&lt;/p&gt;

&lt;h1&gt;
  
  
  Risco de Regressão Criado por Modificação
&lt;/h1&gt;

&lt;p&gt;Quando um sistema em produção recebe uma nova versão (por exemplo, da Release 1.0 para a Release 1.1), corre-se o risco de introduzir regressões: falhas que não existiam antes e que surgem como efeito colateral da mudança. Existem três tipos principais de regressão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local: a própria correção cria um novo bug na área em que foi aplicada.&lt;/li&gt;
&lt;li&gt;Exposta (remote exposure): a correção não cria um bug novo, mas acaba revelando um bug que já existia e estava “escondido” até então.&lt;/li&gt;
&lt;li&gt;Remota: o conserto feito em uma área do sistema quebra o funcionamento de outra área, aparentemente não relacionada — geralmente por causa de dependências ocultas entre módulos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um detalhe relevante é que a regressão pode afetar tanto &lt;strong&gt;recursos novos&lt;/strong&gt; (introduzidos pela própria mudança) quanto &lt;strong&gt;recursos existentes&lt;/strong&gt; (que já funcionavam antes). Por isso, o teste de manutenção precisa necessariamente combinar verificação da mudança com testes de regressão sobre o que já estava pronto.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Análise de Impacto&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Antes de decidir o que testar, é preciso entender o alcance da mudança, isso é feito por meio da &lt;strong&gt;Análise de Impacto&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que é:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avaliar a alteração para identificar o que precisa ser testado.&lt;/li&gt;
&lt;li&gt;Antecipar consequências previstas e efeitos colaterais possíveis.&lt;/li&gt;
&lt;li&gt;Mapear as áreas do sistema afetadas pela mudança.&lt;/li&gt;
&lt;li&gt;Entender o impacto sobre os testes já existentes (quais precisam ser atualizados, quais continuam válidos).&lt;/li&gt;
&lt;li&gt;Considerar os efeitos colaterais do próprio teste de regressão e das áreas por ele cobertas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa análise também serve como insumo de decisão: em alguns casos, o impacto identificado pode ser grande o suficiente para influenciar &lt;strong&gt;se a alteração deve ou não ser feita&lt;/strong&gt;, pesando o benefício da mudança contra o risco e o custo de testá-la adequadamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O que torna a análise de impacto difícil:&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Especificações desatualizadas ou inexistentes, que impedem saber o comportamento esperado original.&lt;/li&gt;
&lt;li&gt;Testes não documentados ou desatualizados, que não refletem mais o sistema real.&lt;/li&gt;
&lt;li&gt;Rastreabilidade desatualizada entre requisitos, código e casos de teste.&lt;/li&gt;
&lt;li&gt;Suporte fraco ou inexistente de ferramentas para mapear dependências.&lt;/li&gt;
&lt;li&gt;Equipe sem conhecimento suficiente do domínio ou do sistema (comum quando há rotatividade de pessoas).&lt;/li&gt;
&lt;li&gt;Má manutenção do software ao longo do tempo (código acoplado, sem modularização, dívida técnica acumulada).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esses fatores são cumulativos: quanto pior a documentação e a rastreabilidade, mais a análise de impacto depende do conhecimento tácito de poucas pessoas, o que é arriscado e não escalável.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Teste de Regressão&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;O &lt;strong&gt;teste de regressão&lt;/strong&gt; é a atividade central dentro do teste de manutenção. Seu objetivo é garantir que, mesmo após uma atualização, o software continue funcionando corretamente como um todo. Para isso, parte ou a totalidade dos testes que já haviam sido executados antes da mudança são repetidos, com o propósito de confirmar que tudo continua operando como esperado mesmo após a alteração. Em outras palavras: o teste de regressão não valida a mudança nova em si (isso é feito por testes específicos da modificação), ele protege o que &lt;strong&gt;já funcionava&lt;/strong&gt; contra efeitos colaterais indesejados.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Estratégias de Regressão&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Como repetir testes tem custo (tempo, esforço, infraestrutura), existem diferentes estratégias para decidir &lt;strong&gt;quanto&lt;/strong&gt; e &lt;strong&gt;o quê&lt;/strong&gt; repetir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estratégia 01 — Repetir todos os testes
&lt;/h2&gt;

&lt;p&gt;Se a suíte de testes tiver cobertura completa do sistema, repetir todos os testes deve ser suficiente para capturar as regressões mais importantes. Na prática, essa estratégia só é viável em sistemas grandes e complexos se houver &lt;strong&gt;automação&lt;/strong&gt; — repetir manualmente toda a suíte seria inviável em termos de tempo e custo. Os benefícios e riscos específicos da automação de testes costumam ser tratados em um tópico à parte, já que automatizar também traz custos de manutenção dos próprios scripts de teste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estratégia 02 — Repetir alguns testes
&lt;/h2&gt;

&lt;p&gt;Na prática, a automação total frequentemente não é possível (por limitações de ferramentas, tempo ou complexidade do sistema). Nesses casos, é necessário &lt;strong&gt;selecionar&lt;/strong&gt; um subconjunto de testes a repetir, usando critérios como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rastreabilidade&lt;/strong&gt;: usar o mapeamento entre requisitos/funcionalidades e casos de teste para saber exatamente quais testes cobrem a área alterada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Análise de mudança/impacto&lt;/strong&gt;: usar os resultados da análise de impacto (vista acima) para priorizar as áreas afetadas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Análise de risco&lt;/strong&gt;: priorizar os testes que cobrem as áreas de maior risco (maior probabilidade de falha combinada com maior severidade do impacto).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testes multifuncionais (cross-functional tests)&lt;/strong&gt;: usados para capturar o que se chama de &lt;strong&gt;“regressão acidental”&lt;/strong&gt; — bugs que surgem em pontos de integração entre funcionalidades diferentes, que um teste estritamente focado (“narrow test”) não enxergaria, pois ele percorre apenas o caminho estreito da funcionalidade alterada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cobertura de código&lt;/strong&gt;: pode ser usada como uma métrica auxiliar para avaliar o nível de risco de áreas pouco testadas.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>TanStack React Router</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Wed, 07 Oct 2026 22:25:08 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/tanstack-react-router-ieg</link>
      <guid>https://dev.to/yuripeixinho/tanstack-react-router-ieg</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;É um roteador para React focado em &lt;strong&gt;type-safety de ponta a ponta&lt;/strong&gt;: rotas, parâmetros de URL, query strings e dados carregados por loaders são todos inferidos pelo TypeScript, sem precisar escrever tipos manualmente. Ele também trata &lt;strong&gt;data loading&lt;/strong&gt; como parte do roteamento (parecido com Remix/Next App Router), não como algo à parte (diferente do React Router clássico).&lt;/p&gt;

&lt;h1&gt;
  
  
  Duas formas de declarar rotas
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Code-based&lt;/strong&gt;&amp;nbsp;(tudo em um arquivo, manual)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRootRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRootRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RootLayout&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;indexRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getParentRoute&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="nx"&gt;rootRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HomePage&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;postRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getParentRoute&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="nx"&gt;rootRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts/$postId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostPage&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;routeTree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rootRoute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addChildren&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;indexRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;postRoute&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;routeTree&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;File-based&lt;/strong&gt; (recomendado)
&lt;/h2&gt;

&lt;p&gt;a estrutura de pastas/arquivos em &lt;code&gt;src/routes&lt;/code&gt; define a árvore, e um plugin (Vite/Webpack/etc.) gera o &lt;code&gt;routeTree.gen.ts&lt;/code&gt; automaticamente. Cada arquivo usa &lt;code&gt;createFileRoute('/caminho')({...})&lt;/code&gt; e nunca precisa declarar &lt;code&gt;getParentRoute&lt;/code&gt; — o plugin resolve isso pela posição no filesystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Convenções de nome de arquivo:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arquivo&lt;/th&gt;
&lt;th&gt;Vira rota&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;routes/__root.tsx&lt;/td&gt;
&lt;td&gt;layout raiz (obrigatório)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;routes/index.tsx&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;routes/about.tsx&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/about&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;routes/posts/index.tsx&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/posts/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;routes/posts/$postId.tsx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/posts/:postId&lt;/code&gt; (param dinâmico)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;routes/posts/$postId.edit.tsx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/posts/:postId/edit&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;routes/_authenticated.tsx + pasta &lt;code&gt;routes/_authenticated/&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;layout &lt;strong&gt;sem&lt;/strong&gt; adicionar segmento na URL (pathless layout)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;routes/posts/-components/Card.tsx&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;ignorado&lt;/strong&gt; — prefixo &lt;code&gt;-&lt;/code&gt; é só código auxiliar, não vira rota&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;routes/posts.lazy.tsx&lt;/td&gt;
&lt;td&gt;parte da rota com code-splitting automático&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  O &lt;code&gt;router&lt;/code&gt; e o &lt;code&gt;RouterProvider&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;O &lt;code&gt;Register&lt;/code&gt; é o truque que faz o TypeScript "conhecer" todas as rotas do app em qualquer componente, sem precisar importar nada específico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RouterProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routeTree&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routeTree.gen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;routeTree&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;declare&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Register&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;   &lt;span class="c1"&gt;// isso dá type-safety global pra Link, useNavigate, etc.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RouterProvider&lt;/span&gt; &lt;span class="na"&gt;router&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;strong&gt;&lt;code&gt;Outlet&lt;/code&gt; e layouts aninhados&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Toda rota com filhas renderiza um&amp;nbsp;&lt;code&gt;&amp;lt;Outlet /&amp;gt;&lt;/code&gt;&amp;nbsp;onde a rota filha deve aparecer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRootRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;component&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavBar&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Outlet&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;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;Isso permite layouts aninhados: &lt;code&gt;_authenticated.tsx&lt;/code&gt; pode renderizar uma sidebar + &lt;code&gt;&amp;lt;Outlet /&amp;gt;&lt;/code&gt;, e todas as rotas dentro de &lt;code&gt;_authenticated/&lt;/code&gt; herdam esse layout.&lt;/p&gt;

&lt;h1&gt;
  
  
  Navegação
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useNavigate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/posts/$postId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;Ver&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navigate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useNavigate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts/$postId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se a rota não existir ou o param faltar, é &lt;strong&gt;erro de tipo em tempo de compilação&lt;/strong&gt; — não em runtime.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Params dinâmicos&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/posts/$postId.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFileRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts/$postId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostPage&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;PostPage&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;postId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useParams&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// tipado como string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Search params (query string) validados
&lt;/h1&gt;

&lt;p&gt;Diferente do React Router, aqui a query string é&amp;nbsp;&lt;strong&gt;tipada e validada&lt;/strong&gt;&amp;nbsp;(geralmente com Zod):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFileRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;validateSearch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;searchSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostsList&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;PostsList&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useSearch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// já validado e tipado&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E &lt;code&gt;&amp;lt;Link search={{ page: 2 }}&amp;gt;&lt;/code&gt; também é tipado contra esse schema.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;8. Loaders (carregar dados antes de renderizar)&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFileRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts/$postId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;loader&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="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetchPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostPage&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;PostPage&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;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useLoaderData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// tipo inferido do retorno do loader&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Loaders rodam &lt;strong&gt;antes&lt;/strong&gt; do componente montar (e podem rodar em paralelo com o parent). Combinado com &lt;code&gt;defaultPreload: 'intent'&lt;/code&gt; no &lt;code&gt;createRouter&lt;/code&gt;, os dados já começam a carregar no hover/foco de um &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt;, antes mesmo do clique.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Estados de pending / erro / not-found&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFileRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts/$postId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="na"&gt;pendingComponent&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Spinner&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// enquanto o loader roda&lt;/span&gt;
  &lt;span class="na"&gt;errorComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reset&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="c1"&gt;// se o loader ou render lançar erro&lt;/span&gt;
  &lt;span class="na"&gt;notFoundComponent&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Não encontrado&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esses fallbacks seguem a hierarquia de rotas: se uma rota não define o seu, o pai assume (até chegar no &lt;code&gt;__root.tsx&lt;/code&gt;).&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Contexto de rota&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;beforeLoad&lt;/code&gt;&amp;nbsp;pode popular um contexto tipado compartilhado por toda a árvore (útil pra auth, QueryClient, etc.):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createRootRouteWithContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;queryClient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QueryClient&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="c1"&gt;// em uma rota filha:&lt;/span&gt;
&lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ensureQueryData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postsQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Devtools
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;@tanstack/react-router-devtools&lt;/code&gt; dá um painel visual da árvore de rotas, matches ativos e estado dos loaders — ótimo pra depurar durante o desenvolvimento.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Processo de Teste</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 04 Oct 2026 22:38:02 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/processo-de-teste-3dci</link>
      <guid>https://dev.to/yuripeixinho/processo-de-teste-3dci</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;O ISTQB não prescreve um processo único. Descreve atividades comuns, sem as quais o teste tem menos chance de atingir seus objetivos, e deixa a adaptação para o contexto. Os fatores que mais pesam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modelos de ciclo de vida e metodologia do projeto;&lt;/li&gt;
&lt;li&gt;níveis e tipos de testes considerado;&lt;/li&gt;
&lt;li&gt;riscos de produto e de projeto;&lt;/li&gt;
&lt;li&gt;domínio de negócio;&lt;/li&gt;
&lt;li&gt;restrições operacionais: orçamento e recursos, prazos, complexidade, requisitos constrautias e regulatórios;&lt;/li&gt;
&lt;li&gt;políticas e práticas da organização;&lt;/li&gt;
&lt;li&gt;padrões internos e externos exigidos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As atividades podem rodar em sequência ou de forma iterativa. Em qualquer projeto, podem se sobrepor, ser combinadas, rodar em paralelo ou ser omitidas. Em ágil, o teste acontece de forma contínua, dentro de cada iteração. O que fica estável é a pergunta que cada atividade responde.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;O exemplo que atravessa o texto&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Cenário hipotético.&lt;/em&gt;&amp;nbsp;Um ERP financeiro SaaS vai gerar remessa CNAB 240 de pagamento a fornecedores para um segundo banco (Banco B). Seis semanas, três sprints, dois devs e dois testers. O banco exige homologação do arquivo e seu sandbox cobre só parte dos cenários. Risco central: arquivo rejeitado ou aceito em duplicidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;As sete atividades&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Atividade&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Pergunta&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Papel&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Saída principal&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Planejamento&lt;/td&gt;
&lt;td&gt;Quais objetivos e qual abordagem, dentro das restrições?&lt;/td&gt;
&lt;td&gt;Gestão&lt;/td&gt;
&lt;td&gt;Plano de teste&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoramento e controle&lt;/td&gt;
&lt;td&gt;Estamos no plano? O que corrigir?&lt;/td&gt;
&lt;td&gt;Gestão&lt;/td&gt;
&lt;td&gt;Relatórios de progresso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Análise&lt;/td&gt;
&lt;td&gt;O que testar?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Condições de teste priorizadas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modelagem&lt;/td&gt;
&lt;td&gt;Como testar?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Casos de teste, requisitos de dados e de ambiente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementação&lt;/td&gt;
&lt;td&gt;Está tudo pronto para rodar?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Procedimentos, suítes, cronograma, ambiente, dados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execução&lt;/td&gt;
&lt;td&gt;O resultado real bate com o esperado?&lt;/td&gt;
&lt;td&gt;Teste&lt;/td&gt;
&lt;td&gt;Status por teste, relatórios de defeitos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conclusão&lt;/td&gt;
&lt;td&gt;O que entregamos e aprendemos?&lt;/td&gt;
&lt;td&gt;Gestão&lt;/td&gt;
&lt;td&gt;Relatório de resumo, lições, testware arquivado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Os produtos de trabalho de todas as atividades formam o&amp;nbsp;&lt;em&gt;testware&lt;/em&gt;. Planejamento e monitoramento e controle atravessam o projeto inteiro: o plano é revisto a partir do que o monitoramento mostra.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Planejamento: quais objetivos, e qual abordagem?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Define os objetivos do teste e escolhe a abordagem que os atinge dentro das restrições e do contexto. A saída é o plano de teste. No mínimo ele aponta a base de teste (o material de onde os testes são derivados: requisitos, histórias, layouts, código) e os critérios de saída, também chamados de definição de feito. Um plano completo traz ainda escopo, premissas, partes interessadas, comunicação, riscos, abordagem, orçamento e cronograma.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;objetivos: arquivo aceito pelo banco, zero duplicidade, sem regressão na remessa do Banco A. Abordagem baseada em risco. Critérios de saída: 100% das condições de risco alto executadas, nenhum defeito crítico ou alto aberto, homologação aprovada.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Monitoramento e controle: estamos no plano?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Compara o progresso real com o plano, usando as métricas definidas nele, e toma as ações necessárias para atingir os objetivos. Também avalia os critérios de saída: verifica a cobertura, avalia o nível de qualidade e decide se são necessários mais testes. Produz relatórios de progresso, contínuos, e relatórios de resumo, nos marcos. Relatório bom traz o que o público precisa para decidir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;na semana 4, 55% dos casos executados contra 70% previstos, e 62% das condições de risco alto contra 80%. Causa: sandbox fora do ar por dois dias. Ações de controle: priorizar a suíte de risco alto, alocar mais um tester por três dias e pedir ao banco uma janela dedicada.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Análise: o que testar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Analisa a base de teste para definir e priorizar condições de teste, identificar as funcionalidades a cobrir e avaliar a testabilidade. A análise também procura defeitos na própria base: ambiguidades, omissões, inconsistências, imprecisões, contradições e afirmações supérfluas. Saídas: condições de teste priorizadas, ligadas por rastreabilidade aos elementos da base, e relatórios de defeitos da base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;a história US-09 ("título já enviado não reenvia") gera as condições CT-03 e CT-04. Na mesma análise aparece um defeito: o texto do layout do banco manda data em DDMMAAAA, e o exemplo do PDF usa AAAAMMDD. O defeito vai para o banco antes de existir uma linha de código.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Modelagem: como testar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Transforma condições em casos de teste, priorizados, com apoio de técnicas como partição de equivalência, análise de valor-limite e tabela de decisão. Define os dados necessários, projeta o ambiente e identifica infraestrutura e ferramentas. O ambiente é&amp;nbsp;&lt;em&gt;projetado&lt;/em&gt;&amp;nbsp;aqui; quem o constrói é a implementação. Casos de alto nível, sem valores concretos, são reutilizáveis entre ciclos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;o campo valor tem 13 posições inteiras e 2 decimais. Valor-limite: 0,00 (inválido), 0,01, 9.999.999.999.999,99 e 10.000.000.000.000,00 (inválido). Caso TC-03, de alto nível: "remessa com título já enviado e sem retorno de rejeição não gera segmento A".&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Implementação: está tudo pronto para rodar?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cria ou obtém o que falta para executar: procedimentos de teste priorizados, scripts automatizados, suítes, cronograma de execução, ambiente construído e verificado, dados preparados e carregados. É aqui que os casos de alto nível ganham valores concretos. Também confere e atualiza a rastreabilidade: toda condição tem caso? Todo caso tem condição?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;validador de layout automatizado no pipeline; suítes&amp;nbsp;&lt;em&gt;smoke&lt;/em&gt;,&amp;nbsp;&lt;em&gt;risco alto&lt;/em&gt;&amp;nbsp;e&amp;nbsp;&lt;em&gt;regressão Banco A&lt;/em&gt;; versão do validador fixada no ambiente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. Execução: o resultado real bate com o esperado?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Roda as suítes conforme o cronograma, manualmente ou com ferramentas. Registra IDs e versões do objeto de teste, das ferramentas e do testware; compara resultado real com esperado; analisa as anomalias antes de reportar; registra os resultados (passou, falhou, bloqueado); repete testes por correção, confirmação ou regressão. Saídas: status por teste, relatórios de defeitos e as versões envolvidas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;TC-03 falhou e gerou D-11 (duplicidade, crítico). TC-12 falhou e gerou D-14 (calendário sem feriados municipais). TC-09 também falhou, mas era falso positivo: o ambiente rodava o validador 2.2, com a regra antiga. Atualizado o validador, o teste passou. Não havia defeito no produto, e foi a versão registrada que permitiu descobrir isso.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7. Conclusão: o que entregamos e o que aprendemos?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Acontece nos marcos: fim de um nível de teste, de uma iteração, de uma release. Verifica se os defeitos foram fechados e registra como solicitações de mudança ou itens de backlog os que restaram. Cria o relatório de resumo, finaliza e arquiva ambiente, dados, infraestrutura e testware, e entrega o testware a quem vai mantê-lo. Analisa as lições aprendidas e usa o que aprendeu para melhorar a maturidade do processo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemplo:&lt;/strong&gt;&amp;nbsp;um defeito de severidade média vira item de backlog. Validador, massa de dados e configuração do ambiente vão para a manutenção, reutilizáveis num futuro Banco C. Lições: validar as ambiguidades do layout com o banco antes da modelagem; incluir o calendário de feriados na base de teste desde o planejamento; reservar a janela do sandbox no cronograma.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Rastreabilidade: o que liga as atividades&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Rastreabilidade é o vínculo entre cada elemento da base de teste e o testware associado a ele: condições, casos, procedimentos, suítes, resultados e defeitos. É estabelecido e mantido ao longo de todo o processo. Funciona nos dois sentidos. Da base para o testware, mostra cobertura: requisito sem condição de teste é lacuna. Do testware para a base, mostra por que cada teste existe: teste sem requisito é teste órfão.&lt;/p&gt;

&lt;p&gt;No exemplo, a cadeia é: US-09 → CT-03 → TC-03 → suíte risco alto → ciclo 1: falhou (D-11) → ciclo 2: passou. Além de medir cobertura, ela serve para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;analisar o impacto de mudanças:&lt;/strong&gt;&amp;nbsp;quando o banco esclarece o formato da data, a cadeia lista as condições e os casos a revisar;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tornar o teste auditável:&lt;/strong&gt;&amp;nbsp;a evidência de que título enviado não reenvia é US-09 → TC-03 → log do ciclo 2;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;atender critérios de governança de TI:&lt;/strong&gt;&amp;nbsp;evidência por requisito, sem retrabalho;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;melhorar a compreensão dos relatórios:&lt;/strong&gt;&amp;nbsp;status por requisito (passou, falhou, pendente) em vez de contagem de casos;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;traduzir o aspecto técnico para as partes interessadas:&lt;/strong&gt;&amp;nbsp;"reenvio de título já enviado está bloqueado e verificado", em vez de "TC-03 passou";&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;avaliar produto, processo e projeto:&lt;/strong&gt;&amp;nbsp;qualidade (1 crítico e 2 altos abertos), processo (D-14 aponta falha na base de teste) e projeto (62% do risco alto executado contra meta de 80%).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cadeia pode viver numa ferramenta de gestão de teste ou num sistema próprio. A ferramenta é meio; o que importa é a cadeia existir e ser mantida.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Quem faz o quê&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A gestão de teste responde pelo processo e pela equipe: planejamento, monitoramento e controle, conclusão. O papel de teste responde pela parte técnica: análise, modelagem, implementação e execução. Em times ágeis, a gestão pode ficar no próprio time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cinco erros comuns&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plano sem critério de saída:&lt;/strong&gt;&amp;nbsp;ninguém sabe quando parar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tratar toda anomalia como defeito:&lt;/strong&gt;&amp;nbsp;analisar antes de reportar evita falso positivo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rastreabilidade em um sentido só:&lt;/strong&gt;&amp;nbsp;esconde os testes órfãos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confundir modelagem com implementação:&lt;/strong&gt;&amp;nbsp;uma define como testar, a outra deixa tudo pronto para rodar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pular a conclusão:&lt;/strong&gt;&amp;nbsp;lições e testware se perdem.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>testing</category>
    </item>
    <item>
      <title>Sete princípios dos teste de software</title>
      <dc:creator>Yuri Peixinho</dc:creator>
      <pubDate>Sun, 04 Oct 2026 20:40:23 +0000</pubDate>
      <link>https://dev.to/yuripeixinho/sete-principios-dos-teste-de-software-196o</link>
      <guid>https://dev.to/yuripeixinho/sete-principios-dos-teste-de-software-196o</guid>
      <description>&lt;h1&gt;
  
  
  Introdução
&lt;/h1&gt;

&lt;p&gt;Os sete princípios vêm do syllabus CTFL da ISTQB. São generalizações empíricas sobre o que teste consegue e não consegue fazer, usadas para calibrar expectativa e esforço. A numeração abaixo segue o CTFL 4.0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como agrupar&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1, 2 e 7:&lt;/strong&gt; limites do que teste pode garantir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 e 4:&lt;/strong&gt; onde e quando alocar esforço.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 e 6:&lt;/strong&gt; como manter a abordagem eficaz ao longo do tempo e entre projetos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Teste mostra a presença de defeitos, não a ausência&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Teste reduz a probabilidade de defeitos não descobertos, mas não prova correção. A formulação clássica é de Dijkstra. Passar em 1.000 casos não garante o comportamento no 1.001º.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A suíte de cálculo de juros e multa de boleto passa com 200 casos e quebra num vencimento em 29/02.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Reportar "nenhum defeito encontrado com esta cobertura e estes riscos", nunca "sem bugs".&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Teste exaustivo é impossível
&lt;/h2&gt;

&lt;p&gt;Testar todas as combinações de entradas, estados e pré-condições é inviável fora de casos triviais. Por isso existem técnicas de redução (partição de equivalência, análise de valor limite, tabela de decisão, pairwise) e priorização por risco.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Um formulário com 10 campos e 5 valores relevantes por campo gera 5¹⁰ = 9.765.625 combinações.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apergunta deixa de ser "testei tudo?" e passa a ser "testei o que tem mais risco, com o menor número de casos que cobre as classes de comportamento?".&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Teste antecipado economiza tempo e dinheiro
&lt;/h2&gt;

&lt;p&gt;Defeito achado em requisito ou design custa menos que o achado em produção. Isso inclui teste estático (revisão de requisitos e de código, análise estática), que encontra defeitos sem executar nada: o "shift left". Os multiplicadores clássicos (10x, 100x) vêm de dados antigos e são contestados, mas a direção do argumento se mantém.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Uma ambiguidade na regra de arredondamento, apontada na revisão do requisito, vira uma conversa. Essa mesma descoberta depois do fechamento do mês em produção, vira correção, reprocessamento e acerto de dados.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Defeitos se agrupam&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Poucos módulos concentram a maior parte dos defeitos. Costuma-se descrever isso pelo princípio de Pareto (80/20 como heurística, não como lei).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3 de 40 módulos respondem por mais da metade dos bugs de produção.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Usar histórico de defeitos, churn de código e complexidade para direcionar o esforço (teste baseado em risco). Cuidado com o viés: um módulo pode parecer problemático só por ser o mais testado.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5. Os testes se desgastam&lt;/strong&gt; (versão 3.1: "paradoxo do pesticida")
&lt;/h2&gt;

&lt;p&gt;Repetir os mesmos testes deixa de encontrar defeitos novos, porque os que eles alcançavam já foram corrigidos. Isso não invalida regressão automatizada, cujo objetivo é detectar quebra, não achar defeito novo. O problema é depender só dela.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;30 cenários de checkout verdes há dois anos, sempre com o mesmo usuário e o mesmo cartão. Nenhum exercita cupom + frete grátis + estorno parcial.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Revisar e variar casos e dados periodicamente, complementar com teste exploratório e usar mutation testing para medir se a suíte detecta falhas de fato.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Teste depende do contexto
&lt;/h2&gt;

&lt;p&gt;Não existe abordagem única. O que, quanto e como testar depende de risco, domínio, ciclo de vida, regulação e tecnologia.&lt;/p&gt;

&lt;p&gt;Em aviônica (DO-178C, nível A) exige-se cobertura MC/DC e rastreabilidade formal, enquanto num MVP isso é desperdício. E-commerce com pico sazonal prioriza carga e performance. Sistema sob obrigação regulatória prioriza conformidade e rastreabilidade das regras.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. &lt;strong&gt;A ausência de defeitos é uma falácia&lt;/strong&gt; (versão 3.1: "falácia da ausência de erros")
&lt;/h2&gt;

&lt;p&gt;Achar e corrigir todos os defeitos não adianta se o sistema não atende à necessidade do usuário. É a distinção entre verificação (construímos conforme a especificação?) e validação (construímos a coisa certa?).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O sistema segue a especificação sem desvio algum, mas ela descrevia um fluxo que ninguém usa. Zero bugs, zero valor.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Implicação:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Incluir validação com usuário e negócio (teste de aceite, protótipo, feedback em produção), não só verificação contra requisito.&lt;/p&gt;

</description>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
