Por que um bug do Cursor não é um bug comum
Uma pessoa que escreve a mesma alteração carrega um contexto que o editor nunca enxerga. Ela lembra que o painel de configurações lê de um cache que precisa ser invalidado, que o botão de upload fica desabilitado até um arquivo ser selecionado, que determinado endpoint devolve um array vazio em vez de um 404 quando nada corresponde. O Cursor trabalha a partir dos arquivos que você abriu e do texto que você digitou. Tudo fora dessa janela é suposição.
Por isso o modo de falha não é sintaxe ruim. É uma alteração localmente correta e globalmente errada. A função faz exatamente o que promete. Só que ela é chamada na hora errada, ou deixa um pedaço de estado para trás, ou assume um formato que a API parou de devolver dois sprints atrás.
Testes unitários não pegam isso, porque são escritos sobre as mesmas premissas com que o código foi escrito. Se o agente escreveu os dois, eles concordam entre si e discordam do seu produto.
De onde os bugs do Cursor realmente vêm
Três lugares respondem pela maior parte deles.
Estado da interface
Um formulário é enviado, mas a lista atrás dele não é atualizada.
Um modal fecha e deixa um bloqueio de rolagem no body.
Um botão continua habilitado enquanto uma requisição já está em andamento, então um clique duplo cria dois registros.
Fluxos assíncronos
A tela renderiza antes de os dados chegarem e nunca renderiza de novo.
Um job em segundo plano é iniciado, mas nada espera por ele, então o passo seguinte lê valores desatualizados.
Um caminho de erro é resolvido silenciosamente e o usuário vê uma mensagem de sucesso para algo que falhou.
Fronteiras de integração
O payload bate com a definição de tipo, mas não com o que o serviço de fato aceita.
Presume-se que a autenticação está lá porque ela estava presente na sessão que o agente viu.
Paginação, estados vazios e rate limits são tratados no sistema de tipos e em nenhum outro lugar.
O que todos eles têm em comum é que só aparecem quando você roda a aplicação e a usa. Ler o diff não revela nenhum deles, e uma suíte de testes que nunca abre um navegador também não.
Como detectar bugs do Cursor antes do merge
A verificação precisa acontecer contra a aplicação publicada, conduzida do jeito que uma pessoa conduziria, e o resultado precisa voltar em um formato sobre o qual o agente consiga agir. Caso contrário, você encontrou o bug, mas quem continua corrigindo é você.
Três coisas precisam ser verdade. Nenhuma delas é difícil; deixar qualquer uma de fora é o que faz o ciclo vazar.
O agente precisa saber como verificar
A configuração instala uma skill de verificação dentro do próprio agente de código, para que ele saiba criar, rodar e fazer a triagem dos testes em vez de adivinhar a partir de um README. Ela escreve um arquivo de instruções no lugar onde seu editor já procura por um, o que significa que o Cursor o encontra em .cursor/rules/ do mesmo jeito que o Claude Code lê o próprio diretório de skills. Oito editores são suportados, o que faz diferença em um time onde nem todo mundo usa o mesmo.
Terminal
npm install -g @testsprite/testsprite-cli
testsprite setup
Você pode fazer o mesmo pelo painel do TestSprite se preferir não instalar nada localmente. Tudo o mais que a CLI consegue fazer está no repositório da CLI.
A verificação precisa bater na aplicação publicada, não em um mock
Aponte uma execução para o ambiente onde a alteração está no ar. O agente abre a aplicação, percorre o comportamento como um usuário e relata o que de fato aconteceu, em vez de dizer se uma asserção em um sandbox foi satisfeita. Mocks não produzem esse sinal, e é por isso que uma suíte unitária verde e uma funcionalidade quebrada convivem tão bem.
A falha precisa voltar como algo que o agente consiga usar
Essa é a parte que decide se o ciclo se fecha. Uma falha que chega como um screenshot em um painel exige que uma pessoa leia, interprete e escreva um prompt. Uma falha que chega como um único pacote coerente contendo o que foi tentado, o que a aplicação fez e onde houve divergência é algo que o agente consegue pegar e usar diretamente. A próxima iteração começa a partir da evidência, e não da sua descrição da evidência.
Faça isso acontecer sem que ninguém precise lembrar
Uma verificação que você roda manualmente é uma verificação que você pula justamente no dia em que está com pressa, que é o dia em que você precisa dela. Existem duas formas de automatizar isso, e qual delas serve melhor depende de quem é dono do seu pipeline.
O GitHub App é um webhook que você configura no painel do TestSprite. Ele escuta o evento de deploy que seu pipeline já produz, então nada no seu repositório muda.
GitHub Actions coloca o passo dentro do seu próprio workflow, configurado pelo terminal.
Vale entender o modelo mesmo que você nunca mexa na configuração. A integração não faz build nem deploy da sua aplicação e não adiciona nem edita arquivos de workflow. Ela escuta o evento de deploy que seu pipeline já produz e trata "o novo build está no ar nesta URL" como o sinal para iniciar uma execução. Os resultados voltam onde o trabalho está acontecendo: como um comentário no pull request ou uma verificação no commit.
Duas decisões determinam se isso é útil, e as duas são questão de critério, não de configuração.
Qual momento conta como pronto. Escolha o evento que dispara depois que o deploy está no ar, não o que dispara quando o build começa. Um evento que chega cedo demais aponta a execução para uma URL que ainda não subiu, e todos os testes falham por um motivo que não tem nada a ver com o seu código. Essa é a forma mais comum de a configuração dar errado.
Se a verificação é apenas informativa ou obrigatória. Um comentário no pull request informa. Uma verificação obrigatória bloqueia o merge. Comece no modo informativo por uma semana para ver o que ela pega e depois decida. Torná-la obrigatória logo no primeiro dia, antes de alguém confiar nela, é a receita para uma verificação útil acabar desativada.
Uma observação prática se seus previews ficam em uma plataforma como Vercel ou Netlify: cada host nomeia as URLs de preview de um jeito, então a integração aceita um padrão em vez de um endereço fixo e preenche a branch ou o pull request a cada execução.
Onde isso se encaixa junto dos seus testes atuais
Isso é verificação de comportamento contra o produto em execução, então complementa os testes unitários locais rápidos em vez de substituí-los. Mantenha os testes unitários para a lógica e deixe que isso cubra aquilo que eles estruturalmente não conseguem enxergar: se a funcionalidade funciona quando um usuário real a utiliza.
Uma observação sobre o padrão mais amplo
Nada disso é específico do Cursor. A mesma lacuna aparece com qualquer assistente que escreve código mais rápido do que uma pessoa consegue ler, e é por isso que vale construir a etapa de verificação uma vez e reaproveitá-la entre os editores. Em um ranking aberto em que agentes construíram a mesma aplicação, o modelo mais barato da disputa entregou a aplicação mais correta quando esse ciclo de verificação estava no lugar, pela metade do custo do participante mais caro. A lição não foi que um modelo é melhor. Foi que um modelo com um sinal de feedback funcionando vence um modelo mais forte sem esse sinal.
Onde o TestSprite se encaixa no ciclo do Cursor
O TestSprite é a metade da verificação. O Cursor escreve a alteração; o TestSprite abre a aplicação publicada, percorre o comportamento como um usuário faria e relata o que realmente aconteceu. Nenhum dos dois tenta fazer o trabalho do outro, e essa separação é justamente o ponto: quem escreveu uma alteração é a parte errada para confirmá-la.
Três coisas decorrem disso para um time que entrega código escrito pelo Cursor. A cobertura deixa de depender de alguém arrumar tempo para escrever testes, porque os casos são gerados a partir do seu produto e refinados em linguagem simples. Redesenhos cosméticos param de deixar a suíte vermelha, porque um passo é uma intenção, e não um caminho pelo DOM. E uma falha volta como um único pacote sobre o qual o agente consegue agir, então a próxima iteração começa a partir da evidência, e não da sua descrição dela.
O que você deve esperar no primeiro dia são os fluxos que seria vergonhoso quebrar rodando em cada pull request, com um resultado que aponta a divergência. O que ele não faz é revisar seu código nem substituir testes unitários locais rápidos, e ele funciona ao lado dos dois.
Por que os próprios testes do Cursor passam quando a funcionalidade está quebrada?
Porque os testes e o código vieram das mesmas premissas. Se o agente acreditou que um endpoint devolve um array vazio e escreveu tanto o handler quanto o teste em cima dessa crença, os dois concordam entre si. Só rodar a aplicação real contra o serviço real desempata.
Preciso de um time de QA para configurar isso?
Não. A configuração é um comando de CLI e a instalação do GitHub App. Ela foi pensada para times em que os desenvolvedores são as únicas pessoas que algum dia vão olhar um resultado de teste.
Ele precisa de acesso ao meu código-fonte?
A verificação roda contra a sua aplicação publicada, pela interface dela. A permissão de escrita no GitHub é usada para publicar resultados de volta em pull requests e commits, não para enviar código ou alterar arquivos de workflow.
O que acontece com os testes quando a interface muda de propósito?
Um teste ligado a um fluxo de negócio, e não a um elemento específico, sobrevive a um redesenho que não muda o fluxo. Quando o próprio fluxo muda, isso é comportamento novo e exige um caso novo ou atualizado, que o agente consegue gerar a partir da alteração.
Dá para rodar isso em uma branch sem afetar a suíte principal?
Os testes pertencem à aplicação, não a uma branch do git, então existe uma única suíte canônica. Escolha o gatilho de pull request se quiser verificações por branch, e o gatilho de push se quiser um único ambiente compartilhado verificado depois de cada merge.
Pare de ler o diff. Rode a aplicação.
Bugs do Cursor se escondem em estado, temporização e fronteiras de integração, que são exatamente os lugares que uma leitura estática e um teste com mocks não alcançam. Coloque a verificação nas mãos do agente, aponte-a para o build publicado e deixe o pull request te dizer se a alteração funciona antes de alguém fazer o merge.