Pilar

Os testes e as simulações por trás do Craft11

Todas as falhas de migração que já vimos noutro software vêm do mesmo sítio: tratar “primeiro limpe os dados” como um problema do cliente em vez de um problema do produto. Não queríamos construir isso. Por isso, cedo, esbarrámos num caso real, e ele ensinou-nos algo que não esperávamos: às vezes a resposta certa a “isto devia ser tratado pela IA?” é não.

A migração que nos ensinou a diferença

Tínhamos uma exportação real de um CRM legado para trazer: 349 empresas, 491 notas, na maioria histórico de chamadas escrito em esloveno, 393 contactos. O movimento óbvio teria sido passar isso pelo Neo, a nossa importação assistida por IA, a mesma que lê uma folha de cálculo desorganizada e propõe registos limpos a partir dela.

Decidimos que não. Os dados de origem já estavam estruturados, já resolvidos, já corretos. Passá-los por uma passagem de IA não teria acrescentado nada além de risco: um modelo a parafrasear ou resumir notas de chamadas reais em esloveno, perdendo silenciosamente precisão num texto que precisava de ficar exatamente como estava escrito. Por isso construímos um segundo caminho, separado, deliberadamente sem IA: cópia exata e determinística, associada por ID de registo legado, preservando os timestamps originais, sem nenhum modelo de linguagem em lado nenhum.

Construir esse caminho revelou lacunas reais que de outra forma não teríamos encontrado: um campo de formulário que o backend andava a descartar silenciosamente sabe-se lá há quanto tempo porque a coluna da base de dados por trás dele nunca tinha existido, contactos que se iam entalando em notas de texto livre por falta de um sítio próprio onde estar. Corrigimos ambos para sempre, não só para esta migração.

Essa é a forma real do Migration Engine agora: o Neo para a confusão honesta, atirem-nos a vossa pior folha de cálculo e diremos claramente o que conseguimos perceber e o que não conseguimos, e um caminho de cópia exata e silenciosa para os dados que já são fiáveis e só precisam de chegar intactos. Dois problemas diferentes. Deixámos de fingir que eram um só.

Chegar a algo que valha a pena testar, sequer

Nada dos testes abaixo importa se não houver nada de real por baixo. Sinceramente, parte de como chegámos aqui começou por acidente. As gravações de ecrã eram sempre adiadas, sobretudo por pura relutância em sentar e gravar algo como deve ser, por isso a verdadeira solução alternativa foi simplesmente ver a IA a clicar pela aplicação ao vivo e tomar notas do que acontecia. Isso revelou-se um dos melhores métodos de depuração em que esbarrámos em todo o projeto, não um plano inteligente, mas um subproduto de não querer fazer outra coisa. Algumas funcionalidades reais existem hoje porque um bug foi apanhado exatamente assim.

A construção maior seguiu uma forma semelhante, menos por grande desígnio e mais por necessidade: uma peça real de cada vez, cada uma testada de ponta a ponta antes de a seguinte começar, porque um projeto deste tamanho não se mantém são de outra forma. O que realmente nos surpreendeu é que o conjunto de testes base acabou por prever coisas que ninguém lhe pediu para prever. Adicione-se uma funcionalidade nova meses depois, e o Velvet por vezes apanhava que uma peça adjacente tinha estado esse tempo todo silenciosamente meio pronta, à espera de ser notada. Não porque quem esteve envolvido seja especialmente perspicaz. Um teste que realmente clica no botão e verifica o resultado real tem, simplesmente, um jeito de encontrar coisas que uma pessoa a percorrer o código com o olhar não encontraria.

Velvet

Algures pelo caminho, o nosso próprio conjunto de testes end-to-end ganhou um nome em vez de continuar a ser apenas “os testes”. Chamamos-lhe Velvet. Cerca de cinco mil linhas de Playwright, divididas em doze conjuntos com nome, smoke, regressão, o Vault, o AI Village, fluxos de action-bus, casos-limite duros, stress, entre outros, executados contra cinco empresas sintéticas e populadas separadas. Ela conduz a aplicação real, em funcionamento, backend e frontend ambos ao vivo, sem substituto simulado para nenhum dos dois.

Dentro dos conjuntos de regressão com nome, as chamadas de IA são simuladas com respostas determinísticas, de propósito, não como atalho. A volume real, as chamadas de IA genuínas esbarram nos limites de ligação do browser e produzem falhas que nada têm a ver com o produto funcionar de facto. Simular ali isola uma pergunta honesta, a canalização funciona, de outra, a resposta real da IA é boa, que é testada separadamente, a sério.

A disciplina por baixo de cada camada

Cinco regras aplicam-se em todo o lado onde se testa neste projeto, não só no Velvet:

Fixar por escrito uma previsão antes de correr o teste, para que um sucesso não possa ser silenciosamente redefinido depois como o que calhou acontecer. Um teste que só confirma que um botão existe não é um teste; tem de clicar no botão, esperar pela resposta real, incluindo a latência real da IA, e verificar o estado resultante efetivo. Cada funcionalidade é experimentada a fazer o que devia fazer, e experimentada da forma como uma pessoa real, por vezes descuidada, por vezes hostil, a usaria mal de facto. Quando uma “falha” se revela ser um bug no script de teste em vez de no produto, isso também é reportado, não corrigido em silêncio e esquecido. E uma correção não está concluída quando o código compila; está concluída quando o cenário exato que falhou foi novamente corrido a sério e passou.

Para além do Velvet: sete camadas, não uma

O Velvet é uma camada entre sete. A verificação de IA real, não simulada, corre separadamente, um script pontual contra a app ao vivo com chamadas genuínas ao modelo, limpo depois, especificamente para apanhar a classe de bug que só aparece porque a resposta de um modelo real varia de execução para execução. A simulação de horizonte longo corre histórias empresariais simuladas, um mês, um ano, cinco anos, contra inquilinos reais com chamadas de IA ao vivo durante todo o processo, colocando as mesmas perguntas canónicas em vários pontos para verificar se as respostas realmente ficaram mais afiadas à medida que a história se acumulava, não só se voltavam de todo. Uma camada adversarial deliberada, oito testes hostis a que chamamos Pista de Obstáculos, tenta quebrar diretamente as afirmações de honestidade e segurança do produto: injeção de prompts, fuga de dados entre inquilinos, instruções conflituantes, resistência a eliminação, reconciliação financeira real, tratamento de contas duplicadas. Os testes unitários e de integração do backend cobrem a Sacred Spine e a ingestão de documentos de ponta a ponta. Percursos guiados testam a interface real em tamanhos de ecrã reais, desktop e um viewport móvel genuíno, com capturas de ecrã como prova, não uma simples marcação numa lista. Até os vídeos promocionais de apresentação serviram como camada de teste: cada um é um script real a correr contra a app real e ao vivo, e cada momento que parecia ligeiramente estranho na revisão foi rastreado individualmente até um bug real ou um problema de sincronização do script, nunca presumido como sendo um ou outro sem verificação.

Ao todo, cerca de vinte e cinco anos simulados de atividade empresarial, vários setores, mais de nove mil entradas reais do Vault geradas pelo caminho, onze bugs reais encontrados e corrigidos. Despesa real total em API para todo o programa: 9,57 dólares.

O que não vamos afirmar

Não testámos a escala empresarial, milhares de inquilinos simultâneos de uma vez. Não testámos sob carga o que acontece ao custo da IA num chat diário genuinamente intenso e aberto, ao contrário da atividade empresarial com guião em torno da qual a maior parte destes testes foi construída. Durante o trabalho acima, encontrámos um risco real de escalabilidade no nosso próprio preenchimento retroativo de embeddings, uma atualização pontual de um Vault grande a aproximar-se desconfortavelmente de um timeout de pedido, e estamos a dizer-vos isso em vez de o corrigir em silêncio e não dizer nada.

Nada aqui é perfeito, porque nada é. O que podemos realmente defender é que olhámos, a fundo, para as nossas próprias afirmações antes de vo-las apresentarmos, e que vos dizemos o que encontrámos, seja qual for o resultado. É essa a disciplina toda. Vamos continuar a fazê-lo.

Perguntas que as pessoas realmente fazem

O Craft11 usa IA para migrar dados antigos, ou isso é arriscado?

Ambos, dependendo da fonte. Dados desorganizados e não estruturados, uma folha de cálculo sem cabeçalhos, uma lista de preços digitalizada, passam pelo Neo, o Migration Engine assistido por IA, que propõe registos limpos e é honesto sobre o que não conseguiu preencher. Exportações de sistemas legados já estruturadas seguem um caminho separado, deliberadamente sem IA: cópia exata e determinística. Construímos os dois porque uma migração real nos ensinou que não são o mesmo problema.

O que é o Velvet?

O nome do nosso próprio conjunto de testes end-to-end em Playwright, cerca de cinco mil linhas divididas em doze conjuntos com nome, executados contra empresas sintéticas reais e populadas, que conduz a aplicação real em funcionamento e não uma versão simulada dela.

Há alguma coisa aqui que seja perfeita, ou totalmente concluída?

Não, e preferimos dizê-lo com clareza a deixar um número grande sugerir o contrário. A escala empresarial, milhares de inquilinos simultâneos, não foi testada. O custo real de um uso diário de IA intenso e aberto não foi testado sob carga em grande volume. Encontrámos um risco real de escalabilidade no nosso próprio processo de preenchimento retroativo de embeddings durante os testes, e reportámo-lo em vez de o corrigir em silêncio e seguir em frente. Testar, aqui, significa que verificámos a fundo e dissemos a verdade sobre o resultado, não que não haja mais nada por encontrar.

Junte-se à Early Crew →← Voltar a todos os artigos

Recorded on a live database and a live screen, but run by automated scripts standing in for a human's clicks and typing, not performed live. When Stark answers faster than the script expects, the screen can hold still for a beat before the next step starts. That's left in on purpose. The goal was never a polished demo reel, it was proof the feature actually works. Dejan's own verdict, after watching the raw footage: rough, but the best demo video we've made.