{"id":1233,"date":"2026-09-10T04:01:13","date_gmt":"2026-09-10T07:01:13","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/como-validar-testar-codigo-escrito-pela-ia\/"},"modified":"2026-09-10T04:01:20","modified_gmt":"2026-09-10T07:01:20","slug":"como-validar-testar-codigo-escrito-pela-ia","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/como-validar-testar-codigo-escrito-pela-ia\/","title":{"rendered":"O C\u00f3digo Chegou Pronto, e Agora? Um Roteiro B\u00e1sico para Testar o que a IA Escreveu Antes de Confiar Nele"},"content":{"rendered":"<p>Voc\u00ea pede para a IA implementar uma fun\u00e7\u00e3o de valida\u00e7\u00e3o de CPF. Ela responde em segundos, o c\u00f3digo parece limpo, tem at\u00e9 coment\u00e1rios explicando cada etapa. Voc\u00ea copia, cola no projeto, roda uma vez com um CPF de teste, funciona, e segue para a pr\u00f3xima tarefa. Duas semanas depois, um cliente reporta que o sistema aceitou um CPF inv\u00e1lido no cadastro. Voc\u00ea abre o c\u00f3digo, olha para aquela fun\u00e7\u00e3o &#8220;pronta&#8221; e percebe que ela nunca validou o c\u00e1lculo dos d\u00edgitos verificadores de verdade \u2014 apenas checava se a string tinha onze caracteres num\u00e9ricos.<\/p>\n<p>Essa cena se repete todos os dias em equipes de desenvolvimento que adotaram assistentes de IA como Claude Code, GitHub Copilot ou ChatGPT. O problema n\u00e3o \u00e9 a IA escrever c\u00f3digo ruim \u2014 na maioria das vezes ela escreve c\u00f3digo plaus\u00edvel, bem formatado e com apar\u00eancia de correto. O problema \u00e9 que &#8220;parecer correto&#8221; e &#8220;estar correto&#8221; s\u00e3o coisas diferentes, e sem um processo de valida\u00e7\u00e3o, o desenvolvedor s\u00f3 descobre a diferen\u00e7a quando o erro j\u00e1 causou dano.<\/p>\n<p>Este artigo apresenta, do zero, um roteiro b\u00e1sico para voc\u00ea testar e validar qualquer c\u00f3digo gerado por IA antes de integr\u00e1-lo ao seu projeto. Vamos explicar cada conceito, mostrar exemplos de c\u00f3digo completos e funcionais, e construir junto um checklist que voc\u00ea pode aplicar j\u00e1 na pr\u00f3xima tarefa.<\/p>\n<h2>Por que c\u00f3digo gerado por IA exige um cuidado diferente<\/h2>\n<p>Quando um colega de equipe escreve c\u00f3digo, voc\u00ea tem um contexto impl\u00edcito: sabe o n\u00edvel de experi\u00eancia dele, sabe se ele testou localmente, pode perguntar &#8220;por que voc\u00ea fez assim?&#8221; e receber uma resposta fundamentada. Com a IA, esse contexto n\u00e3o existe da mesma forma. O modelo gera a resposta mais prov\u00e1vel estatisticamente para o seu pedido, n\u00e3o necessariamente a mais correta para o seu caso espec\u00edfico.<\/p>\n<p>Segundo o <a href=\"https:\/\/about.gitlab.com\/pt-br\/topics\/devops\/ai-code-generation-guide\/\" target=\"_blank\" rel=\"noopener\">guia da GitLab sobre gera\u00e7\u00e3o de c\u00f3digo com IA<\/a>, os desenvolvedores devem trabalhar em conjunto com os sistemas de IA para validar o c\u00f3digo gerado, apresentar contexto adicional e requisitos, em vez de simplesmente aceitar a primeira resposta como definitiva. Essa ideia \u00e9 o ponto central deste artigo: a IA \u00e9 uma colaboradora que precisa de revis\u00e3o, n\u00e3o uma fonte de verdade.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> Existe at\u00e9 discuss\u00e3o sobre se \u00e9 poss\u00edvel identificar que um trecho de c\u00f3digo foi escrito por IA. Uma thread da comunidade <a href=\"https:\/\/www.reddit.com\/r\/learnpython\/comments\/10o413v\/is_it_possible_to_detect_if_a_code_is_written_by\/?tl=pt-br\" target=\"_blank\" rel=\"noopener\">r\/learnpython no Reddit<\/a> discute exatamente isso, e ferramentas como o <a href=\"https:\/\/www.pangram.com\/pt\/blog\/ai-code-detector\" target=\"_blank\" rel=\"noopener\">detector de c\u00f3digo de IA da Pangram<\/a> tentam automatizar essa identifica\u00e7\u00e3o. Mas isso \u00e9 uma curiosidade lateral: o que realmente importa para voc\u00ea, desenvolvedor, n\u00e3o \u00e9 saber quem escreveu o c\u00f3digo, e sim se ele funciona corretamente.<\/p><\/blockquote>\n<h2>O primeiro passo: leia o c\u00f3digo antes de rodar<\/h2>\n<p>Antes de qualquer teste automatizado, existe uma etapa manual e obrigat\u00f3ria: a leitura cr\u00edtica. Muitos desenvolvedores pulam essa etapa porque o c\u00f3digo &#8220;parece certo&#8221; \u00e0 primeira vista. Mas ler o c\u00f3digo com aten\u00e7\u00e3o \u00e9 o que revela decis\u00f5es escondidas, como usar uma biblioteca desatualizada, ignorar um caso de borda ou simplificar demais uma regra de neg\u00f3cio.<\/p>\n<p>Vamos usar um exemplo simples em Python. Suponha que voc\u00ea pediu \u00e0 IA uma fun\u00e7\u00e3o para calcular o desconto de um pedido:<\/p>\n<pre><code class=\"language-python\">def calcular_desconto(valor_total, quantidade_itens):\n    if quantidade_itens &gt; 10:\n        return valor_total * 0.9\n    return valor_total\n<\/code><\/pre>\n<p>\u00c0 primeira vista, parece razo\u00e1vel: pedidos com mais de dez itens recebem 10% de desconto. Mas ao ler com aten\u00e7\u00e3o, surgem perguntas que s\u00f3 um humano que conhece o neg\u00f3cio consegue responder: e se <code>valor_total<\/code> for negativo? E se <code>quantidade_itens<\/code> for zero ou negativo? O desconto deveria ser aplicado apenas sobre parte do valor, ou sobre o total? Essas perguntas n\u00e3o aparecem no c\u00f3digo \u2014 elas aparecem na sua cabe\u00e7a, durante a leitura cr\u00edtica.<\/p>\n<h3>Perguntas que voc\u00ea deve se fazer ao ler c\u00f3digo de IA<\/h3>\n<ul>\n<li>Esse c\u00f3digo trata valores nulos, vazios ou negativos?<\/li>\n<li>As mensagens de erro fazem sentido para quem vai depurar isso depois?<\/li>\n<li>A biblioteca ou fun\u00e7\u00e3o usada ainda \u00e9 a recomendada, ou est\u00e1 obsoleta?<\/li>\n<li>Essa l\u00f3gica reflete exatamente a regra de neg\u00f3cio que eu pedi, ou \u00e9 uma vers\u00e3o simplificada?<\/li>\n<li>Existe algum caso de borda \u00f3bvio que n\u00e3o foi tratado?<\/li>\n<\/ul>\n<h2>O segundo passo: escreva testes automatizados para o c\u00f3digo gerado<\/h2>\n<p>Ler o c\u00f3digo ajuda a levantar suspeitas, mas testes automatizados confirmam ou refutam essas suspeitas com evid\u00eancia concreta. Um <strong>teste automatizado<\/strong> \u00e9 um trecho de c\u00f3digo que executa outro trecho de c\u00f3digo e verifica se o resultado \u00e9 o esperado, sem que voc\u00ea precise repetir esse processo manualmente toda vez.<\/p>\n<p>Continuando o exemplo anterior, vamos escrever testes usando a biblioteca padr\u00e3o de testes do Python, o <a href=\"https:\/\/docs.python.org\/3\/library\/unittest.html\" target=\"_blank\" rel=\"noopener\">unittest<\/a> \u2014 mas se voc\u00ea preferir, o mesmo racioc\u00ednio vale para pytest, Jest, JUnit ou qualquer framework de testes da sua linguagem.<\/p>\n<pre><code class=\"language-python\">import unittest\n\ndef calcular_desconto(valor_total, quantidade_itens):\n    if quantidade_itens &gt; 10:\n        return valor_total * 0.9\n    return valor_total\n\nclass TestCalcularDesconto(unittest.TestCase):\n\n    def test_sem_desconto_com_poucos_itens(self):\n        resultado = calcular_desconto(100, 5)\n        self.assertEqual(resultado, 100)\n\n    def test_desconto_aplicado_com_muitos_itens(self):\n        resultado = calcular_desconto(100, 11)\n        self.assertEqual(resultado, 90)\n\n    def test_valor_total_negativo_deveria_ser_rejeitado(self):\n        with self.assertRaises(ValueError):\n            calcular_desconto(-50, 15)\n\n    def test_quantidade_zero_nao_gera_erro(self):\n        resultado = calcular_desconto(100, 0)\n        self.assertEqual(resultado, 100)\n\nif __name__ == \"__main__\":\n    unittest.main()\n<\/code><\/pre>\n<p>Ao rodar esses testes, o terceiro caso \u2014 <code>test_valor_total_negativo_deveria_ser_rejeitado<\/code> \u2014 vai falhar, porque a fun\u00e7\u00e3o original da IA n\u00e3o lan\u00e7a nenhuma exce\u00e7\u00e3o para valores negativos. Isso \u00e9 exatamente o ponto: o teste automatizado transformou uma suspeita (&#8220;ser\u00e1 que isso trata valores negativos?&#8221;) em um fato verific\u00e1vel (&#8220;n\u00e3o trata, e aqui est\u00e1 a prova&#8221;).<\/p>\n<p>Com essa evid\u00eancia em m\u00e3os, voc\u00ea corrige a fun\u00e7\u00e3o \u2014 sozinho ou pedindo \u00e0 pr\u00f3pria IA que ajuste, agora com o requisito expl\u00edcito:<\/p>\n<pre><code class=\"language-python\">def calcular_desconto(valor_total, quantidade_itens):\n    if valor_total  10:\n        return valor_total * 0.9\n    return valor_total\n<\/code><\/pre>\n<p>Rodando os testes novamente, todos passam. Esse ciclo \u2014 escrever teste, rodar, corrigir, rodar de novo \u2014 \u00e9 a base de qualquer processo de valida\u00e7\u00e3o s\u00e9rio, e funciona da mesma forma seja o c\u00f3digo escrito por voc\u00ea, por um colega ou por uma IA.<\/p>\n<h2>O terceiro passo: teste os casos de borda, n\u00e3o apenas o caminho feliz<\/h2>\n<p>Um erro comum de quem est\u00e1 come\u00e7ando \u00e9 testar apenas o &#8220;caminho feliz&#8221; \u2014 o cen\u00e1rio em que tudo d\u00e1 certo. Mas a maioria dos bugs em produ\u00e7\u00e3o acontece nos casos de borda: entradas vazias, valores extremos, tipos inesperados, condi\u00e7\u00f5es de rede inst\u00e1veis.<\/p>\n<p>Vamos ilustrar isso com um exemplo em JavaScript, uma fun\u00e7\u00e3o que a IA poderia gerar para validar um e-mail:<\/p>\n<pre><code class=\"language-javascript\">function validarEmail(email) {\n  const regex = \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/;\n  return regex.test(email);\n}\n\n\/\/ Testes manuais r\u00e1pidos no console\nconsole.log(validarEmail(\"adriano@exemplo.com\")); \/\/ true\nconsole.log(validarEmail(\"email-invalido\"));       \/\/ false\nconsole.log(validarEmail(\"\"));                      \/\/ false\nconsole.log(validarEmail(null));                    \/\/ ERRO: Cannot read properties of null\n<\/code><\/pre>\n<p>Perceba que os tr\u00eas primeiros casos funcionam bem, e \u00e9 f\u00e1cil parar por a\u00ed, satisfeito com o resultado. Mas o quarto caso \u2014 passar <code>null<\/code> como argumento \u2014 quebra a aplica\u00e7\u00e3o inteira com um erro n\u00e3o tratado. Se essa fun\u00e7\u00e3o receber dados de um formul\u00e1rio onde o campo de e-mail pode chegar vazio ou nulo, o sistema vai falhar silenciosamente ou, pior, derrubar a aplica\u00e7\u00e3o inteira.<\/p>\n<p>A corre\u00e7\u00e3o \u00e9 simples, mas s\u00f3 aparece quando voc\u00ea pensa deliberadamente nos casos de borda:<\/p>\n<pre><code class=\"language-javascript\">function validarEmail(email) {\n  if (typeof email !== \"string\" || email.trim() === \"\") {\n    return false;\n  }\n  const regex = \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/;\n  return regex.test(email);\n}\n<\/code><\/pre>\n<h3>Uma checklist pr\u00e1tica de casos de borda<\/h3>\n<ul>\n<li>Entrada vazia (string vazia, lista vazia, objeto vazio)<\/li>\n<li>Entrada nula ou indefinida<\/li>\n<li>Valores num\u00e9ricos extremos (zero, negativos, muito grandes)<\/li>\n<li>Caracteres especiais ou acentua\u00e7\u00e3o em textos<\/li>\n<li>Concorr\u00eancia: o que acontece se a fun\u00e7\u00e3o for chamada duas vezes ao mesmo tempo?<\/li>\n<\/ul>\n<h2>O quarto passo: valide o comportamento, n\u00e3o apenas a sintaxe<\/h2>\n<p>C\u00f3digo gerado por IA quase sempre compila, roda e n\u00e3o gera erro de sintaxe \u2014 afinal, o modelo foi treinado com enormes volumes de c\u00f3digo sintaticamente correto. O problema real est\u00e1 no comportamento: a l\u00f3gica de neg\u00f3cio implementada \u00e9 a l\u00f3gica que voc\u00ea realmente precisa?<\/p>\n<p>Para validar comportamento, \u00e9 \u00fatil escrever os testes <strong>antes<\/strong> de pedir o c\u00f3digo \u00e0 IA, ou logo em seguida, descrevendo em termos concretos o que o sistema deveria fazer. Essa pr\u00e1tica se aproxima do conceito de especifica\u00e7\u00e3o antes da implementa\u00e7\u00e3o, algo que j\u00e1 discutimos aqui no blog em outro artigo sobre desenvolvimento orientado por especifica\u00e7\u00e3o, e que se aplica muito bem \u00e0 valida\u00e7\u00e3o de c\u00f3digo de IA: voc\u00ea define o comportamento esperado em forma de teste, e s\u00f3 depois confirma se a implementa\u00e7\u00e3o atende a esse contrato.<\/p>\n<p>Veja um exemplo em Delphi, \u00fatil para quem trabalha com sistemas legados ou aplica\u00e7\u00f5es desktop, mostrando como validar o comportamento de uma fun\u00e7\u00e3o que a IA poderia ter sugerido para calcular juros simples:<\/p>\n<pre><code class=\"language-pascal\">function CalcularJurosSimples(Capital, Taxa: Double; Periodo: Integer): Double;\nbegin\n  Result := Capital * (Taxa \/ 100) * Periodo;\nend;\n\n\/\/ Teste usando DUnit ou DUnitX\nprocedure TestCalcularJurosSimples;\nbegin\n  Assert(CalcularJurosSimples(1000, 5, 12) = 600,\n    'Juros de 5% ao m\u00eas sobre 1000 por 12 meses deveria ser 600');\n\n  Assert(CalcularJurosSimples(0, 5, 12) = 0,\n    'Capital zero deveria gerar juros zero');\nend;\n<\/code><\/pre>\n<p>Rodar esse teste confirma se a f\u00f3rmula implementada corresponde \u00e0 f\u00f3rmula financeira correta de juros simples. Sem esse teste, a \u00fanica forma de descobrir um erro na f\u00f3rmula seria um relat\u00f3rio financeiro incorreto chegando \u00e0s m\u00e3os de um cliente \u2014 um custo muito mais alto do que alguns segundos rodando um teste automatizado.<\/p>\n<h2>O quinto passo: use ferramentas de teste que j\u00e1 existem, n\u00e3o reinvente tudo<\/h2>\n<p>Voc\u00ea n\u00e3o precisa construir sua pr\u00f3pria infraestrutura de testes do zero. Existem ferramentas maduras, algumas delas j\u00e1 incorporando intelig\u00eancia artificial para gerar e validar testes automaticamente. O <a href=\"https:\/\/www.testsprite.com\/use-cases\/pt\/the-most-reliable-AI-end-to-end-tests\" target=\"_blank\" rel=\"noopener\">material da TestSprite sobre testes de ponta a ponta com IA<\/a> lista op\u00e7\u00f5es como Testim, Functionize, Katalon e Applitools, voltadas justamente para validar aplica\u00e7\u00f5es inteiras, incluindo c\u00f3digo gerado por IA, de forma automatizada.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> Se voc\u00ea est\u00e1 come\u00e7ando agora, n\u00e3o precisa adotar essas ferramentas de teste de ponta a ponta imediatamente. Comece pelo b\u00e1sico: testes unit\u00e1rios simples, como os exemplos deste artigo, usando o framework de testes nativo da sua linguagem. Ferramentas mais sofisticadas fazem sentido quando o projeto cresce e o volume de cen\u00e1rios a testar manualmente se torna invi\u00e1vel.<\/p><\/blockquote>\n<p>Vale destacar tamb\u00e9m que essa preocupa\u00e7\u00e3o n\u00e3o \u00e9 exclusiva de quem escreve c\u00f3digo sozinho. Em um v\u00eddeo sobre o ritmo acelerado da gera\u00e7\u00e3o de c\u00f3digo por IA, dispon\u00edvel no <a href=\"https:\/\/www.youtube.com\/watch?v=hNyR6ol9wAI\" target=\"_blank\" rel=\"noopener\">canal do YouTube sobre IA e testes de software<\/a>, \u00e9 discutida a ideia de manter uma biblioteca de valida\u00e7\u00e3o pr\u00f3pria, reutiliz\u00e1vel entre projetos, exatamente para n\u00e3o depender de testar tudo manualmente toda vez que a IA gera um novo trecho de c\u00f3digo.<\/p>\n<h2>Montando seu checklist b\u00e1sico de valida\u00e7\u00e3o<\/h2>\n<p>Reunindo tudo o que vimos at\u00e9 aqui, este \u00e9 um checklist simples que voc\u00ea pode aplicar sempre que a IA gerar c\u00f3digo para o seu projeto:<\/p>\n<ul>\n<li><strong>Leia antes de rodar:<\/strong> identifique decis\u00f5es impl\u00edcitas, bibliotecas usadas e poss\u00edveis simplifica\u00e7\u00f5es indevidas.<\/li>\n<li><strong>Escreva testes automatizados:<\/strong> pelo menos um teste para o caminho feliz e um para cada caso de borda \u00f3bvio.<\/li>\n<li><strong>Teste valores extremos:<\/strong> nulo, vazio, negativo, zero, muito grande.<\/li>\n<li><strong>Confirme o comportamento contra a regra de neg\u00f3cio real<\/strong>, n\u00e3o apenas contra a sintaxe.<\/li>\n<li><strong>Rode os testes de regress\u00e3o existentes<\/strong> no projeto, para garantir que o novo c\u00f3digo n\u00e3o quebrou nada que j\u00e1 funcionava.<\/li>\n<li><strong>Documente o motivo de qualquer ajuste feito<\/strong> no c\u00f3digo gerado, para que o pr\u00f3ximo desenvolvedor (ou a pr\u00f3xima sess\u00e3o de IA) entenda o contexto.<\/li>\n<\/ul>\n<h2>Convite para aprofundar o assunto<\/h2>\n<p>Validar c\u00f3digo gerado por IA \u00e9 uma habilidade que se desenvolve com pr\u00e1tica e com troca de experi\u00eancias reais entre desenvolvedores que enfrentam os mesmos desafios todos os dias. Se voc\u00ea quer discutir casos concretos, compartilhar scripts de teste e aprender com quem j\u00e1 passou por situa\u00e7\u00f5es parecidas com as deste artigo, participe da <a href=\"https:\/\/adrianosantos.link\/ComunidadeDevAI\" target=\"_blank\" rel=\"noopener\">Comunidade Dev&#8217;s AI<\/a>. \u00c9 um espa\u00e7o para quem desenvolve software no dia a dia e quer usar IA de forma respons\u00e1vel, sem abrir m\u00e3o da qualidade.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>A intelig\u00eancia artificial mudou a velocidade com que o c\u00f3digo \u00e9 escrito, mas n\u00e3o mudou a responsabilidade de quem assina o commit. Um c\u00f3digo gerado em segundos pode economizar horas de trabalho, ou pode custar dias de corre\u00e7\u00e3o em produ\u00e7\u00e3o \u2014 a diferen\u00e7a est\u00e1 inteiramente no processo de valida\u00e7\u00e3o que voc\u00ea aplica antes de integr\u00e1-lo ao projeto.<\/p>\n<p>Comece pelo b\u00e1sico: leia com aten\u00e7\u00e3o, escreva testes automatizados simples, pense nos casos de borda e confirme se o comportamento implementado \u00e9 realmente o comportamento que voc\u00ea precisa. Esse h\u00e1bito, praticado de forma consistente, transforma a IA de uma fonte de risco silencioso em uma ferramenta genuinamente produtiva \u2014 exatamente o papel que ela deveria cumprir no seu fluxo de trabalho.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Voc\u00ea pede para a IA implementar uma fun\u00e7\u00e3o de valida\u00e7\u00e3o de CPF. Ela responde em segundos, o c\u00f3digo parece limpo, tem at\u00e9 coment\u00e1rios explicando cada etapa. Voc\u00ea copia, cola no projeto, roda uma vez com um CPF de teste, funciona, e segue para a pr\u00f3xima tarefa. Duas semanas depois, um cliente reporta que o sistema [&hellip;]<\/p>\n","protected":false},"author":127,"featured_media":1234,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/users\/127"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/comments?post=1233"}],"version-history":[{"count":1,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1233\/revisions"}],"predecessor-version":[{"id":1235,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1233\/revisions\/1235"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/1234"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}