Descobri que boa parte da minha programação de ciências computacionais tem requisitos de teste que não são cobertos pelas estruturas de teste padrão:
Teste de tempo de computação
- Para garantir que os algoritmos não fiquem mais lentos. Eu poderia fazer algo parecido,
assureSmallerEqual(RuntimeWrapper(algorithm),53)
mas gostaria que o limite de 53 segundos fosse reduzido continuamente, enquanto trabalho no algoritmo, ou seja, algo comoassureSmallerEqual(RuntimeWrapper(algorithm),'previousbest+noisetolerance')
- Para garantir que os algoritmos não fiquem mais lentos. Eu poderia fazer algo parecido,
Teste de performance
- Para garantir que um algoritmo que encontrou anteriormente uma boa aproximação a uma solução analítica ainda encontre uma solução que seja pelo menos tão boa ou melhor. Novamente, isso pode ser emulado por um teste de integração padrão, mas eu gostaria que a tolerância diminuísse continuamente à medida que o algoritmo se tornasse cada vez melhor. Pense em substituir
assureAlmostEqual(foo(),1,places=3)
porassureAlmostEqual(foo(),1,places='previousbest')
- Para garantir que um algoritmo que encontrou anteriormente uma boa aproximação a uma solução analítica ainda encontre uma solução que seja pelo menos tão boa ou melhor. Novamente, isso pode ser emulado por um teste de integração padrão, mas eu gostaria que a tolerância diminuísse continuamente à medida que o algoritmo se tornasse cada vez melhor. Pense em substituir
Teste de requisitos físicos
- Para garantir que os algoritmos não precisem repentinamente de mais memória / espaço no disco rígido. Muito parecido com 1.
Teste de requisitos abstratos
- Para garantir que um algoritmo que funcionou bem com aproximações quadráticas não precise subitamente de aproximações cúbicas, ou que um algoritmo que funcionou bem com o tempo da etapa 0.1 não precise de 0,01 para estabilidade. Novamente, eles podem ser emulados por testes de integração padrão, mas o objetivo é lembrar qual foi o menor parâmetro de requisito que atingiu um determinado objetivo; portanto, isso exigiria muita atualização manual. Por exemplo, se
foo(10)
anteriormente não houvesse exceções, gostaria que a estrutura certificasse quefoo(10)
ainda funcionasse e também tentasse sefoo(9)
funcionasse agora (nesse caso, todos os testes futuros garantiriam quefoo(9)
ainda funcionem).
- Para garantir que um algoritmo que funcionou bem com aproximações quadráticas não precise subitamente de aproximações cúbicas, ou que um algoritmo que funcionou bem com o tempo da etapa 0.1 não precise de 0,01 para estabilidade. Novamente, eles podem ser emulados por testes de integração padrão, mas o objetivo é lembrar qual foi o menor parâmetro de requisito que atingiu um determinado objetivo; portanto, isso exigiria muita atualização manual. Por exemplo, se
Alguém poderia argumentar que o que estou pedindo não descreve testes no sentido de teste de unidade / integração, já que tempos de execução maiores, por exemplo, podem ser aceitáveis em troca de outras melhorias.
Na prática, no entanto, sei que economizaria muito tempo de depuração se tivesse a funcionalidade de teste acima, porque em 95% dos casos os requisitos e o desempenho foram incorretos devido a erros que introduzi. De fato, sei que muitos erros que encontrei (depois de muito tempo desperdiçado na verificação de meu próprio código) com bibliotecas de software numéricas externas poderiam ter sido evitados trivialmente se os testes acima fossem aplicados rigorosamente.
PS
A pergunta de nome semelhante /programming/34982863/framework-for-regression-testing-of-numerical-code não é uma duplicata, pois descreve a funcionalidade que é mais facilmente alcançável com estruturas de teste de regressão padrão.
A pergunta Estratégias para teste de unidade e desenvolvimento orientado a teste pede estratégias em oposição a uma estrutura que ajude a implementá-las (e as estratégias solicitadas / fornecidas nas respostas são diferentes do que descrevo aqui, na minha opinião).