Graças a Deus pelos testes de regressão. Lá estava eu, no início desta semana, me sentindo muito bem com algum novo código que eu havia escrito e (eu pensei) depurado. Estou no processo de melhorar as funções do OpenVOS POSIX que convertem valores de tempo binários para a estrutura de tempo decomposta ("struct tm" para vocês especialistas em C). Em 1998, quando modifiquei originalmente estas rotinas para trabalhar no ambiente POSIX, tomei um atalho e chamei as sub-rotinas subjacentes do kernel VOS. Esta abordagem era rápida e simples, mas significava que nosso POSIX não podia lidar com datas entre 1970 e 1980, porque o VOS não lidava com essas datas. Ultimamente, tenho portado vários pacotes novos e importantes de código aberto para o OpenVOS 17.0. Descobri que estávamos fracassando em um monte de testes porque não podíamos lidar com esta gama de datas. Então, comecei a tarefa de modificar o código para lidar com todas as datas tanto no VOS como no UNIX Epochs (1970 a 2048). Eu sabia que esta tarefa seria passível de erros, e estava determinado a encontrar uma maneira de moer todos os erros do código. Uma das coisas boas de se trabalhar com datas é que o conjunto é finito. Além disso, como os computadores modernos são bastante rápidos, não é tão difícil simplesmente tê-los esmagados em todas as combinações possíveis e ver o que acontece. Eu queria ter certeza de testar a área do código que tratou de 1970 e 1971, por razões que não vou entrar aqui. Então escrevi um teste que se converteu 2 vezes por dia, começando em 1 de janeiro de 1970 e se estendendo até o presente. Ele usou apenas uma fração de segundo do tempo da CPU. Com certeza, encontrei um erro de posicionamento da cerca em meu código. Eu corrigi o erro e depois o teste passou. Eu estava me sentindo muito bem sobre este processo, e meus auditores assinaram as mudanças, e eu pensei que tinha terminado. Então, um colega meu fez o teste de regressão sobre minhas mudanças. Fazemos isso após cada mudança nos compiladores e seus tempos de execução, só para ter certeza de que não quebramos nada acidentalmente. Infelizmente para mim, vários dos testes de regressão falharam. Quando descobri por que meus testes não haviam conseguido, apesar da aparente minuciosidade do teste, descobri que os problemas não surgiram até 2038. Embora eu tivesse acrescentado a década de 1970 a 1980 às rotinas do tempo, eu tinha desistido da década de 2038 a 2048. Com certeza, quando voltei e testei todos os dias na faixa, provei que meu teste teria pegado o problema, se ao menos eu tivesse pedido.
Qual é a lição aqui? Suponho que a mais óbvia é que se você pode testar todas as combinações, então tenha certeza de que você realmente testa todas as combinações. Talvez uma lição mais importante seja dedicar um tempo para construir um conjunto de testes de regressão. Elas valem o tempo e o esforço. Eles podem cortar o custo e encurtar o tempo de encontrar e corrigir problemas à medida que você aprimora seu código. Você não precisa evitar muitos problemas relatados pelo cliente para justificar o custo de criar uma suíte de teste de regressão. Eu estimo que o custo de consertar um problema de software aumenta por uma ordem de magnitude a cada fase adicional do processo. Como há pelo menos 4 fases em qualquer processo (projeto, código, teste, implantação), as coisas se tornam caras muito rapidamente.