Conjuntos de testes para aplicativos numéricos em C ++?

13

Recentemente, tenho pressionado meu grupo a incluir mais testes ao escrever seu código. Houve vários bugs importantes que levaram muito mais tempo para serem detectados do que provavelmente era necessário falar, porque não tínhamos um bom regime de teste.

No entanto, suspeito que ter as ferramentas apropriadas para automatizar (ou ajudar a otimizar) o processo certamente seria útil. Por outro lado, não conheço as várias opções para os conjuntos de testes em C ++ e como decidir entre eles?

Existem diretrizes para o que procurar - e existem algumas especificamente voltadas para aplicativos numéricos?

aeismail
fonte

Respostas:

11

O problema com o teste de códigos numéricos é que (i) você nem sempre sabe a saída exata e só poderá salvar o resultado de uma computação agora para comparar com posterior - ou seja, fazer testes de regressão e (ii) esses resultados podem diferir em pequenas quantidades em máquinas diferentes devido a diferentes arredondamentos.

Para ver como o deal.II faz isso, dê uma olhada aqui: http://www.dealii.org/developer/development/testsuite.html#regression_tests

Wolfgang Bangerth
fonte
Bons pontos sobre as limitações do teste de unidade. O teste de regressão é uma coisa boa (certamente melhor do que não testar, porque a saída é desconhecida; pode dar sinais de aviso sobre bugs). Quanto ao problema de arredondamento da máquina, a mitigação se dedica à escolha de uma boa tolerância por tentativa e erro?
Geoff Oxberry
2
É uma dor constante. Em mais de 10 anos de testes, nunca chegamos a uma estratégia realmente boa para lidar com isso. Usar numdiff em vez de diff pode ajudar, mas, em última análise, é necessário designar uma máquina para a qual você armazena "0,3987" em vez de "0,3988", que você encontra em outra máquina quando o número correto é 0,3975. Não importa onde você defina o limite, você sempre cortará um número de outro no local errado.
Wolfgang Bangerth
@WolfgangBangerth. Existem certos sinalizadores específicos do compilador que tornam o comportamento do ponto flutuante mais determinístico. Por exemplo, / fp: strict | precision e / Qimf-arch-consistency: true (compilador Intel) ou -fnounsafe-math-optimizations, -ffloat-store (GCC) podem tornar seu código mais consistente e reproduzível em várias plataformas, com o custo de desempenho . Com alguns ajustes, isso fornece uma compilação "reproduzível" especial, que pode ser usada especificamente para testes.
André André
@ André - oh sim, nós tentamos tudo isso. Ainda é difícil :-)
Wolfgang Bangerth
10

Recentemente, tenho usado o googletest para testar algumas bibliotecas numéricas nas quais trabalho e fiquei muito feliz com isso. Você pode escrever testes bastante simples com muita rapidez ou testes complicados que requerem inicialização de dados e assim por diante. Ele também fornece (como eu tenho certeza que muitos outros fazem) maneiras de fazer comparações de ponto flutuante com facilidade, em vez de bit a bit.

skillman
fonte
Uma coisa boa do googletest é que eles facilitam a inclusão do código-fonte em um aplicativo, para que você não precise torná-lo uma dependência.
Geoff Oxberry
4

Se você estiver criando seu código com o CMake, o mecanismo ctest seria a escolha óbvia. Ele permite que você teste seu código manualmente por meio do comando cteste também oferece suporte a testes noturnos extensos via CDash .

Nico Schlömer
fonte
1

Para nossa biblioteca C ++ de biologia computacional ( Chaste ), usamos http://cxxtest.com/ . Isso é bastante simples de usar, funciona bem, fornece algumas macros para testar com assert()instruções de estilo. Para a computação científica, essas geralmente são comparações diretas simples TS_ASSERT_EQUALS(a,b)ou comparações numéricas com TS_ASSERT_DELTA(a,b,tolerance).

Macros extras podem ser facilmente escritas usando esses básicos para comparar também seus próprios vetores / matrizes de escolha. De maneira útil, você também pode verificar se o seu código lança avisos e mensagens de erro apropriados em determinadas situações. Você pode procurar alguns exemplos nas testpastas do nosso código-fonte aqui: https://chaste.cs.ox.ac.uk/trac/browser/trunk

mirams
fonte