{"id":1248,"date":"2026-09-17T04:01:42","date_gmt":"2026-09-17T07:01:42","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/harness-de-testes-arquitetura-codigo-gerado-por-ia\/"},"modified":"2026-09-17T04:01:51","modified_gmt":"2026-09-17T07:01:51","slug":"harness-de-testes-arquitetura-codigo-gerado-por-ia","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/harness-de-testes-arquitetura-codigo-gerado-por-ia\/","title":{"rendered":"O Per\u00edmetro de Confian\u00e7a: Arquitetando Harnesses de Teste que Isolam o Risco do C\u00f3digo Gerado por IA"},"content":{"rendered":"<p>Voc\u00ea j\u00e1 revisou um pull request gerado por um agente de IA que passou em 100% da su\u00edte de testes existente e, ainda assim, introduziu uma regress\u00e3o sutil em produ\u00e7\u00e3o tr\u00eas semanas depois? O padr\u00e3o \u00e9 conhecido por quem trabalha com gera\u00e7\u00e3o autom\u00e1tica de c\u00f3digo em escala: os testes que voc\u00ea j\u00e1 tinha foram escritos para validar o comportamento que humanos costumavam implementar, n\u00e3o para capturar as formas espec\u00edficas \u2014 e recorrentes \u2014 pelas quais um modelo de linguagem erra. A su\u00edte &#8220;verde&#8221; deu falsa seguran\u00e7a porque nunca foi desenhada para pegar aquele tipo de falha.<\/p>\n<p>Esse \u00e9 o problema central que um harness de testes para c\u00f3digo gerado por IA precisa resolver, e \u00e9 diferente do problema que uma su\u00edte de testes tradicional resolve. N\u00e3o se trata apenas de &#8220;ter mais testes&#8221;. Trata-se de reconhecer que c\u00f3digo gerado por IA tem uma distribui\u00e7\u00e3o de erros distinta \u2014 alucina\u00e7\u00e3o de APIs inexistentes, edge cases plaus\u00edveis mas nunca testados, padr\u00f5es copiados de contextos incompat\u00edveis, depend\u00eancias impl\u00edcitas que o modelo assumiu sem verificar \u2014 e construir uma infraestrutura de verifica\u00e7\u00e3o desenhada especificamente para essa distribui\u00e7\u00e3o. Neste artigo, vamos al\u00e9m do &#8220;escreva mais testes&#8221; e entramos em decis\u00f5es de arquitetura: como estruturar camadas de conten\u00e7\u00e3o, que tipo de verifica\u00e7\u00e3o automatizada realmente pega o que review humano n\u00e3o pega, e onde o custo de manter esse harness supera o benef\u00edcio.<\/p>\n<h2>Por que a su\u00edte de testes que voc\u00ea j\u00e1 tem n\u00e3o \u00e9 suficiente<\/h2>\n<p>A maioria dos times trata &#8220;testar c\u00f3digo gerado por IA&#8221; como sin\u00f4nimo de &#8220;rodar a su\u00edte existente contra o novo c\u00f3digo&#8221;. Isso \u00e9 necess\u00e1rio, mas est\u00e1 longe de ser suficiente, por um motivo estrutural: sua su\u00edte de testes atual foi constru\u00edda incrementalmente, ao longo do tempo, cobrindo os bugs que humanos historicamente introduziram naquele c\u00f3digo-base. Ela reflete o perfil de erro dos seus desenvolvedores, n\u00e3o o perfil de erro do modelo que est\u00e1 gerando c\u00f3digo agora.<\/p>\n<p>Segundo a <a href=\"https:\/\/www.nxcode.io\/pt\/resources\/news\/harness-engineering-complete-guide-ai-agent-codex-2026\" target=\"_blank\" rel=\"noopener\">NxCode, em seu guia sobre harness engineering<\/a>, a disciplina de projetar ambientes, restri\u00e7\u00f5es e loops de feedback \u00e9 o que efetivamente torna agentes de codifica\u00e7\u00e3o produtivos e seguros \u2014 n\u00e3o a qualidade isolada do modelo. Isso implica uma mudan\u00e7a de postura: o harness n\u00e3o \u00e9 um acess\u00f3rio de QA, \u00e9 parte da arquitetura do sistema de desenvolvimento assistido por IA.<\/p>\n<h3>O perfil de erro espec\u00edfico de c\u00f3digo gerado por IA<\/h3>\n<p>Antes de desenhar qualquer harness, vale mapear as categorias de falha que efetivamente aparecem com gera\u00e7\u00e3o por IA, porque cada categoria exige uma estrat\u00e9gia de detec\u00e7\u00e3o diferente:<\/p>\n<ul>\n<li><strong>Alucina\u00e7\u00e3o de interface:<\/strong> o modelo chama um m\u00e9todo que n\u00e3o existe naquela vers\u00e3o da biblioteca, ou inventa uma assinatura plaus\u00edvel baseada em padr\u00f5es de outras linguagens.<\/li>\n<li><strong>Contrato impl\u00edcito quebrado:<\/strong> o c\u00f3digo funciona no caminho feliz, mas viola um invariante que nunca estava documentado explicitamente (ordem de chamadas, estado mut\u00e1vel compartilhado, transa\u00e7\u00f5es).<\/li>\n<li><strong>Edge case plaus\u00edvel, nunca testado:<\/strong> o modelo produz uma implementa\u00e7\u00e3o gen\u00e9rica que ignora casos de borda espec\u00edficos do seu dom\u00ednio (fuso hor\u00e1rio, moeda, unicode, concorr\u00eancia).<\/li>\n<li><strong>Copy-paste sem\u00e2ntico:<\/strong> um padr\u00e3o correto em outro contexto (outro servi\u00e7o, outra stack) aplicado de forma incompat\u00edvel ao seu sistema.<\/li>\n<li><strong>Regress\u00e3o silenciosa em refatora\u00e7\u00e3o:<\/strong> a IA reescreve uma fun\u00e7\u00e3o &#8220;melhorando&#8221; o c\u00f3digo, mas altera comportamento de borda que nenhum teste cobria.<\/li>\n<\/ul>\n<p>Um harness bem desenhado ataca essas categorias uma a uma, com ferramentas distintas \u2014 n\u00e3o com &#8220;mais testes unit\u00e1rios gen\u00e9ricos&#8221;.<\/p>\n<h2>Arquitetura em camadas: o modelo de conten\u00e7\u00e3o<\/h2>\n<p>A abordagem mais robusta que tenho visto funcionar em produ\u00e7\u00e3o \u00e9 tratar o harness como um pipeline de camadas de conten\u00e7\u00e3o, cada uma com uma responsabilidade \u00fanica e um custo de execu\u00e7\u00e3o crescente. A ideia \u00e9 que c\u00f3digo gerado por IA passe por filtros progressivamente mais caros e mais espec\u00edficos, e falhe o mais cedo poss\u00edvel.<\/p>\n<h3>Camada 1 \u2014 Verifica\u00e7\u00e3o est\u00e1tica e de contrato<\/h3>\n<p>Antes de qualquer teste de comportamento, valide que o c\u00f3digo gerado respeita os contratos est\u00e1ticos do projeto: tipagem, assinatura de interfaces, aus\u00eancia de s\u00edmbolos inexistentes. Isso pega alucina\u00e7\u00e3o de API antes mesmo de rodar qualquer coisa.<\/p>\n<pre><code class=\"language-typescript\">\/\/ verify-contracts.ts\nimport ts from \"typescript\";\n\ninterface ContractViolation {\n  file: string;\n  message: string;\n  line: number;\n}\n\nfunction verifyGeneratedFile(filePath: string): ContractViolation[] {\n  const program = ts.createProgram([filePath], {\n    strict: true,\n    noImplicitAny: true,\n    target: ts.ScriptTarget.ES2022,\n  });\n\n  const diagnostics = ts.getPreEmitDiagnostics(program);\n  const violations: ContractViolation[] = [];\n\n  for (const diag of diagnostics) {\n    if (diag.file &amp;&amp; diag.start !== undefined) {\n      const { line } = diag.file.getLineAndCharacterOfPosition(diag.start);\n      violations.push({\n        file: diag.file.fileName,\n        message: ts.flattenDiagnosticMessageText(diag.messageText, \"\\n\"),\n        line: line + 1,\n      });\n    }\n  }\n\n  return violations;\n}\n\nconst violations = verifyGeneratedFile(process.argv[2]);\nif (violations.length &gt; 0) {\n  console.error(`Bloqueado: ${violations.length} viola\u00e7\u00e3o(\u00f5es) de contrato encontradas.`);\n  violations.forEach(v =&gt; console.error(`  ${v.file}:${v.line} \u2014 ${v.message}`));\n  process.exit(1);\n}\n<\/code><\/pre>\n<p>O mesmo princ\u00edpio se aplica em outras linguagens: em C#, o compilador com <code>TreatWarningsAsErrors<\/code> e analisadores Roslyn customizados; em Java, checkers do Error Prone; em Delphi, a an\u00e1lise est\u00e1tica do compilador combinada com ferramentas como o Pascal Analyzer para detectar chamadas a m\u00e9todos inexistentes ou assinaturas incompat\u00edveis introduzidas por gera\u00e7\u00e3o autom\u00e1tica.<\/p>\n<h3>Camada 2 \u2014 Testes de propriedade, n\u00e3o apenas de exemplo<\/h3>\n<p>Testes unit\u00e1rios tradicionais verificam exemplos espec\u00edficos: &#8220;dado X, espero Y&#8221;. Isso \u00e9 fraco contra c\u00f3digo gerado por IA porque o modelo tende a acertar exatamente os exemplos \u00f3bvios e falhar nos casos que ningu\u00e9m pensou em escrever manualmente. Testes de propriedade (property-based testing) invertem a l\u00f3gica: voc\u00ea declara invariantes que devem valer para qualquer entrada, e a ferramenta gera centenas de casos, incluindo os patol\u00f3gicos.<\/p>\n<pre><code class=\"language-python\">from hypothesis import given, strategies as st\n\n# C\u00f3digo gerado por IA a ser validado\ndef parse_currency(value: str) -&gt; int:\n    \"\"\"Converte string de moeda para centavos (inteiro).\"\"\"\n    cleaned = value.replace(\"R$\", \"\").replace(\".\", \"\").replace(\",\", \".\").strip()\n    return round(float(cleaned) * 100)\n\n@given(st.decimals(min_value=\"0.01\", max_value=\"999999.99\", places=2))\ndef test_parse_currency_is_reversible(amount):\n    formatted = f\"R$ {amount:,.2f}\".replace(\",\", \"X\").replace(\".\", \",\").replace(\"X\", \".\")\n    result = parse_currency(formatted)\n    expected = round(float(amount) * 100)\n    assert result == expected, f\"Falhou para {formatted}: esperado {expected}, obtido {result}\"\n\n@given(st.text())\ndef test_parse_currency_never_crashes_silently(garbage_input):\n    try:\n        parse_currency(garbage_input)\n    except (ValueError, AttributeError):\n        pass  # Falha esperada e controlada\n    except Exception as e:\n        raise AssertionError(f\"Exce\u00e7\u00e3o n\u00e3o tratada para entrada '{garbage_input}': {type(e)}\")\n<\/code><\/pre>\n<p>Esse tipo de teste \u00e9 particularmente eficiente contra c\u00f3digo gerado por IA porque exp\u00f5e rapidamente os edge cases que o modelo simplesmente n\u00e3o considerou \u2014 no exemplo acima, valores negativos, separadores decimais inconsistentes ou entradas vazias tendem a quebrar implementa\u00e7\u00f5es geradas automaticamente que &#8220;parecem&#8221; corretas no caminho feliz.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> vale a pena assistir ao epis\u00f3dio <a href=\"https:\/\/www.youtube.com\/watch?v=3-1dqJ5fxS4\" target=\"_blank\" rel=\"noopener\">Harness Engineering: O futuro da engenharia de software com IA<\/a>, que discute exatamente essa mudan\u00e7a de mentalidade \u2014 de &#8220;revisar o output&#8221; para &#8220;projetar o ambiente que restringe o output&#8221;.<\/p><\/blockquote>\n<h3>Camada 3 \u2014 Testes de comportamento (behaviour harness)<\/h3>\n<p>Property-based testing pega falhas de l\u00f3gica isolada, mas n\u00e3o pega falhas de comportamento em rela\u00e7\u00e3o ao sistema como um todo \u2014 regress\u00f5es de fluxo, quebra de contratos entre servi\u00e7os, efeitos colaterais inesperados. Para isso, a abordagem de &#8220;behaviour harness&#8221; ganhou tra\u00e7\u00e3o recentemente: voc\u00ea define especifica\u00e7\u00f5es de comportamento execut\u00e1veis, desacopladas da implementa\u00e7\u00e3o, e roda o c\u00f3digo gerado contra elas antes de aceitar o merge.<\/p>\n<p>Conforme mostrado em <a href=\"https:\/\/www.youtube.com\/watch?v=wPXm-iS60lc\" target=\"_blank\" rel=\"noopener\">este v\u00eddeo sobre behaviour harness para c\u00f3digo gerado por IA<\/a>, a velocidade de gera\u00e7\u00e3o de c\u00f3digo pela IA n\u00e3o \u00e9 o gargalo \u2014 o gargalo \u00e9 garantir que essa velocidade n\u00e3o introduza regress\u00f5es silenciosas em fluxos cr\u00edticos de neg\u00f3cio.<\/p>\n<pre><code class=\"language-csharp\">\/\/ BehaviourSpec.cs \u2014 especifica\u00e7\u00e3o execut\u00e1vel independente da implementa\u00e7\u00e3o\npublic class PedidoBehaviourSpec\n{\n    [Theory]\n    [InlineData(0, false)]      \/\/ pedido sem itens n\u00e3o pode ser confirmado\n    [InlineData(1, true)]\n    public void PedidoSoPodeSerConfirmadoComItens(int quantidadeItens, bool esperado)\n    {\n        var pedido = new Pedido();\n        for (int i = 0; i &lt; quantidadeItens; i++)\n            pedido.AdicionarItem(new ItemPedido(&quot;SKU-001&quot;, 1, 10.0m));\n\n        var podeConfirmar = pedido.PodeSerConfirmado();\n\n        Assert.Equal(esperado, podeConfirmar);\n    }\n\n    [Fact]\n    public void ConfirmarPedidoDuasVezesDeveSerIdempotente()\n    {\n        var pedido = new Pedido();\n        pedido.AdicionarItem(new ItemPedido(&quot;SKU-001&quot;, 1, 10.0m));\n\n        pedido.Confirmar();\n        var estadoAposConfirmarUmaVez = pedido.Status;\n\n        pedido.Confirmar(); \/\/ c\u00f3digo gerado por IA \u00e0s vezes n\u00e3o trata reentr\u00e2ncia\n        var estadoAposConfirmarDuasVezes = pedido.Status;\n\n        Assert.Equal(estadoAposConfirmarUmaVez, estadoAposConfirmarDuasVezes);\n    }\n}\n<\/code><\/pre>\n<p>O ponto cr\u00edtico aqui: essas especifica\u00e7\u00f5es de comportamento devem ser escritas \u2014 ou pelo menos revisadas linha a linha \u2014 por humanos, antes de o c\u00f3digo ser gerado, seguindo l\u00f3gica de especifica\u00e7\u00e3o pr\u00e9via. Deixar a pr\u00f3pria IA gerar tanto o c\u00f3digo quanto os testes de comportamento que o validam cria um ciclo fechado onde os mesmos vieses e alucina\u00e7\u00f5es do modelo passam despercebidos dos dois lados.<\/p>\n<h3>Camada 4 \u2014 Sandbox de execu\u00e7\u00e3o isolada<\/h3>\n<p>A \u00faltima camada de conten\u00e7\u00e3o, e a mais cara operacionalmente, \u00e9 rodar o c\u00f3digo gerado em um ambiente isolado antes de qualquer merge \u2014 sem acesso a rede externa, com sistema de arquivos ef\u00eamero, limites de CPU e mem\u00f3ria, e captura completa de syscalls. Isso n\u00e3o substitui os testes anteriores; complementa-os, porque pega comportamentos que nenhuma asser\u00e7\u00e3o prev\u00ea, como uma chamada de rede n\u00e3o autorizada que o modelo &#8220;achou&#8221; que era necess\u00e1ria, ou um loop que consome recursos de forma desproporcional.<\/p>\n<pre><code class=\"language-yaml\"># harness-sandbox.yml \u2014 configura\u00e7\u00e3o de execu\u00e7\u00e3o isolada\nversion: \"1\"\nsandbox:\n  network: none\n  filesystem: ephemeral\n  timeout_seconds: 30\n  limits:\n    cpu: \"1\"\n    memory: \"512Mi\"\n  capture:\n    - syscalls\n    - stdout\n    - stderr\n    - exit_code\n  fail_conditions:\n    - network_attempt_detected\n    - filesystem_write_outside_tmp\n    - exit_code_nonzero\n    - timeout_exceeded\n<\/code><\/pre>\n<p>Ferramentas de orquestra\u00e7\u00e3o de CI como containers ef\u00eameros com pol\u00edticas de seccomp, ou solu\u00e7\u00f5es dedicadas de sandboxing, cumprem esse papel. O importante na decis\u00e3o arquitetural \u00e9: essa camada s\u00f3 deve rodar depois que as camadas 1 a 3 j\u00e1 filtraram o volume \u00f3bvio de falhas, porque o custo de infraestrutura de sandboxing isolado \u00e9 significativamente maior que rodar uma su\u00edte de testes unit\u00e1rios.<\/p>\n<h2>Onde o harness ganha intelig\u00eancia: sinais espec\u00edficos de gera\u00e7\u00e3o por IA<\/h2>\n<p>Al\u00e9m das quatro camadas de conten\u00e7\u00e3o, um harness maduro para c\u00f3digo gerado por IA incorpora verifica\u00e7\u00f5es que n\u00e3o fazem sentido em um pipeline tradicional, porque s\u00e3o desenhadas especificamente para os vieses do modelo.<\/p>\n<p>De acordo com o <a href=\"https:\/\/www.cortex-intelligence.com\/blog\/inteligencia\/harness-ai\" target=\"_blank\" rel=\"noopener\">guia da Cortex Intelligence sobre harness e plataformas de IA<\/a>, o conceito de harness em contexto de IA est\u00e1 diretamente ligado a transformar intelig\u00eancia artificial em execu\u00e7\u00e3o controlada \u2014 e controle, nesse sentido, significa tamb\u00e9m instrumenta\u00e7\u00e3o de sinais que humanos normalmente n\u00e3o precisariam checar.<\/p>\n<h3>Verifica\u00e7\u00e3o de depend\u00eancias fantasma<\/h3>\n<p>Um script simples, rodado antes mesmo da camada est\u00e1tica, elimina boa parte das alucina\u00e7\u00f5es de API mais grosseiras: comparar todo import ou using declarado no c\u00f3digo gerado contra o que realmente existe no lockfile ou manifesto de depend\u00eancias do projeto.<\/p>\n<pre><code class=\"language-bash\">#!\/usr\/bin\/env bash\n# check-phantom-deps.sh\nset -euo pipefail\n\nGENERATED_FILE=\"$1\"\nLOCKFILE=\"package-lock.json\"\n\n# Extrai imports do arquivo gerado\nIMPORTS=$(grep -oP \"(?&lt;=from [&#039;\\&quot;])[^&#039;\\&quot;]+(?=[&#039;\\&quot;])&quot; &quot;$GENERATED_FILE&quot; | grep -v &quot;^\\.\/&quot; | sort -u)\n\nfor pkg in $IMPORTS; do\n  ROOT_PKG=$(echo &quot;$pkg&quot; | cut -d&#039;\/&#039; -f1)\n  if ! grep -q &quot;\\&quot;$ROOT_PKG\\&quot;&quot; &quot;$LOCKFILE&quot;; then\n    echo &quot;ALERTA: pacote &#039;$ROOT_PKG&#039; importado mas n\u00e3o encontrado no lockfile.&quot;\n    exit 1\n  fi\ndone\n\necho &quot;Nenhuma depend\u00eancia fantasma detectada.&quot;\n<\/code><\/pre>\n<h3>Diff sem\u00e2ntico contra a vers\u00e3o anterior<\/h3>\n<p>Quando a IA \u00e9 usada para refatorar c\u00f3digo existente, comparar apenas o diff textual esconde mudan\u00e7as de comportamento. Um harness maduro roda a su\u00edte de testes de comportamento tanto na vers\u00e3o antiga quanto na nova, e compara os resultados byte a byte antes de aceitar que a refatora\u00e7\u00e3o \u00e9 comportamentalmente equivalente \u2014 a menos que a mudan\u00e7a de comportamento seja explicitamente o objetivo da tarefa.<\/p>\n<pre><code class=\"language-python\"># semantic-diff-runner.py\nimport subprocess\nimport json\n\ndef run_test_suite(commit_ref: str) -&gt; dict:\n    subprocess.run([\"git\", \"checkout\", commit_ref], check=True)\n    result = subprocess.run(\n        [\"pytest\", \"--json-report\", \"--json-report-file=report.json\"],\n        capture_output=True\n    )\n    with open(\"report.json\") as f:\n        return json.load(f)\n\nbefore = run_test_suite(\"HEAD~1\")\nafter = run_test_suite(\"HEAD\")\n\nbefore_outcomes = {t[\"nodeid\"]: t[\"outcome\"] for t in before[\"tests\"]}\nafter_outcomes = {t[\"nodeid\"]: t[\"outcome\"] for t in after[\"tests\"]}\n\nregressions = [\n    nodeid for nodeid, outcome in before_outcomes.items()\n    if outcome == \"passed\" and after_outcomes.get(nodeid) == \"failed\"\n]\n\nif regressions:\n    print(f\"Regress\u00e3o comportamental detectada em {len(regressions)} teste(s):\")\n    for r in regressions:\n        print(f\"  - {r}\")\n    exit(1)\n<\/code><\/pre>\n<h2>Trade-offs: onde esse investimento vale a pena e onde n\u00e3o vale<\/h2>\n<p>Construir as quatro camadas descritas tem custo real de implementa\u00e7\u00e3o e de manuten\u00e7\u00e3o cont\u00ednua. Vale a pena discutir abertamente quando o investimento se paga e quando \u00e9 excesso de engenharia.<\/p>\n<h3>Quando vale a pena<\/h3>\n<ul>\n<li>Times que j\u00e1 delegam gera\u00e7\u00e3o de c\u00f3digo a agentes de forma recorrente e em volume \u2014 n\u00e3o um uso pontual, mas parte do fluxo di\u00e1rio.<\/li>\n<li>Sistemas com dom\u00ednio de neg\u00f3cio complexo, onde edge cases de moeda, concorr\u00eancia ou regras regulat\u00f3rias s\u00e3o caros de errar.<\/li>\n<li>Bases de c\u00f3digo legadas sendo refatoradas por IA, onde regress\u00f5es silenciosas s\u00e3o particularmente perigosas por falta de contexto hist\u00f3rico documentado.<\/li>\n<\/ul>\n<h3>Quando n\u00e3o vale a pena<\/h3>\n<ul>\n<li>Prot\u00f3tipos e provas de conceito descart\u00e1veis \u2014 o custo de manter quatro camadas de verifica\u00e7\u00e3o supera em muito o valor de um c\u00f3digo que ser\u00e1 jogado fora em semanas.<\/li>\n<li>Times pequenos sem capacidade de manter a infraestrutura de sandboxing e os testes de propriedade atualizados \u2014 um harness mal mantido gera mais falsos positivos que confian\u00e7a real, e a equipe passa a ignor\u00e1-lo.<\/li>\n<li>C\u00f3digo gerado em dom\u00ednios de baix\u00edssimo risco, onde um bug custa uma corre\u00e7\u00e3o r\u00e1pida e n\u00e3o um incidente com impacto financeiro ou de seguran\u00e7a.<\/li>\n<\/ul>\n<p>O erro mais comum que vejo \u00e9 aplicar o harness completo indiscriminadamente a todo tipo de c\u00f3digo gerado, o que cria atrito desproporcional e leva desenvolvedores a contornar o processo. A decis\u00e3o de quais camadas ativar deveria ser proporcional ao risco do componente sendo gerado \u2014 um harness de teste para um script de migra\u00e7\u00e3o de dados n\u00e3o precisa da mesma sandbox isolada que um servi\u00e7o de pagamento.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> para um roteiro mais detalhado, passo a passo, de constru\u00e7\u00e3o de um harness aplicado especificamente a c\u00f3digo Java, C# ou Delphi, veja o artigo <a href=\"https:\/\/adrianosantostreina.com.br\/blog\/harness-de-testes-para-codigo-gerado-por-ia\/\" target=\"_blank\" rel=\"noopener\">Como Criar um Harness de Testes para C\u00f3digo Gerado por IA<\/a>, que complementa a discuss\u00e3o arquitetural feita aqui com exemplos de implementa\u00e7\u00e3o mais extensos.<\/p><\/blockquote>\n<h2>O custo de manuten\u00e7\u00e3o que a documenta\u00e7\u00e3o oficial n\u00e3o menciona<\/h2>\n<p>Um ponto raramente discutido \u00e9 que o harness em si precisa de manuten\u00e7\u00e3o cont\u00ednua, e essa manuten\u00e7\u00e3o tem um perfil diferente da manuten\u00e7\u00e3o de uma su\u00edte de testes tradicional. Testes de propriedade exigem revis\u00e3o peri\u00f3dica das faixas de valores geradas conforme o dom\u00ednio de neg\u00f3cio evolui. Especifica\u00e7\u00f5es de comportamento precisam ser atualizadas manualmente sempre que uma regra de neg\u00f3cio muda \u2014 e se voc\u00ea delegar essa atualiza\u00e7\u00e3o \u00e0 mesma IA que gera o c\u00f3digo de produ\u00e7\u00e3o, perde a independ\u00eancia que d\u00e1 valor ao harness.<\/p>\n<p>H\u00e1 tamb\u00e9m o custo de falsos positivos: sandboxes excessivamente restritivas bloqueiam opera\u00e7\u00f5es leg\u00edtimas (uma chamada de rede necess\u00e1ria, uma escrita em diret\u00f3rio tempor\u00e1rio fora do esperado), e cada falso positivo corr\u00f3i a confian\u00e7a da equipe no processo. A calibra\u00e7\u00e3o dessas pol\u00edticas de conten\u00e7\u00e3o \u00e9 trabalho cont\u00ednuo, n\u00e3o configura\u00e7\u00e3o de uma vez.<\/p>\n<h3>M\u00e9trica que importa: taxa de escape, n\u00e3o taxa de cobertura<\/h3>\n<p>Cobertura de c\u00f3digo continua sendo uma m\u00e9trica pobre para medir a efic\u00e1cia de um harness contra c\u00f3digo gerado por IA, porque cobertura mede linhas executadas, n\u00e3o comportamentos verificados. A m\u00e9trica mais reveladora \u00e9 a taxa de escape: quantos bugs originados em c\u00f3digo gerado por IA chegaram a produ\u00e7\u00e3o apesar de terem passado por todas as camadas do harness. Rastrear essa m\u00e9trica ao longo do tempo, e fazer um post-mortem de cada escape para identificar qual camada deveria ter pego aquele erro, \u00e9 o que realmente amadurece o harness \u2014 n\u00e3o adicionar testes gen\u00e9ricos.<\/p>\n<h2>Junte-se \u00e0 Comunidade Dev&#8217;s AI<\/h2>\n<p>\n","protected":false},"excerpt":{"rendered":"<p>Voc\u00ea j\u00e1 revisou um pull request gerado por um agente de IA que passou em 100% da su\u00edte de testes existente e, ainda assim, introduziu uma regress\u00e3o sutil em produ\u00e7\u00e3o tr\u00eas semanas depois? O padr\u00e3o \u00e9 conhecido por quem trabalha com gera\u00e7\u00e3o autom\u00e1tica de c\u00f3digo em escala: os testes que voc\u00ea j\u00e1 tinha foram escritos [&hellip;]<\/p>\n","protected":false},"author":127,"featured_media":1249,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1248","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\/1248","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=1248"}],"version-history":[{"count":1,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1248\/revisions"}],"predecessor-version":[{"id":1250,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1248\/revisions\/1250"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/1249"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}