Тестирование комплектов для числовых приложений в C ++?

13

Недавно я подталкивал свою группу к включению большего количества тестирования при написании их кода. Было несколько серьезных ошибок, которые требовались намного дольше, чем, вероятно, было необходимо, потому что у нас не было хорошего режима тестирования.

Однако я подозреваю, что наличие соответствующих инструментов для автоматизации (или для упрощения) процесса, безусловно, было бы полезно. С другой стороны, я не знаю различных вариантов комплектов тестирования C ++ и как выбирать между ними?

Существуют ли руководящие принципы для того, что искать, и есть ли какие-либо, специально предназначенные для численных приложений?

aeismail
источник

Ответы:

11

Проблема с тестированием числовых кодов заключается в том, что (i) вы не всегда можете знать точный результат, и вы сможете сохранить результаты вычислений только сейчас, чтобы сравнить их с более поздними, то есть выполнить регрессионные тесты, и (ii) что результаты могут отличаться в небольших количествах на разных машинах из-за разного округления.

Чтобы увидеть, как сделка deal.II, посмотрите здесь: http://www.dealii.org/developer/development/testsuite.html#regression_tests

Вольфганг Бангерт
источник
Хорошие замечания об ограничениях юнит-тестирования. Регрессионное тестирование - это хорошо (конечно, лучше, чем вообще не тестировать, потому что вывод неизвестен; он может давать предупреждающие знаки об ошибках). Что касается вопроса округления машины, то сводит ли это снижение к выбору хорошего допуска путем проб и ошибок?
Джефф Оксберри
2
Это постоянная боль. За более чем 10 лет тестирования мы никогда не придумали действительно хорошую стратегию для решения этой проблемы. Использование numdiff вместо diff может помочь, но в конечном итоге вам нужно указать одну машину, для которой вы храните «0.3987» вместо «0.3988», которую вы получаете на другой машине, когда правильное число равно 0.39875. Независимо от того, где вы устанавливаете порог, вы всегда будете отрезать одно число от другого в неправильном месте.
Вольфганг Бангерт
@WolfgangBangerth. Существуют определенные специфичные для компилятора флаги, которые делают поведение с плавающей точкой более детерминированным. Например: / fp: строгий | точный и / Qimf-arch-consistency: true (компилятор Intel) или -fnounsafe-math-optimizations, -ffloat-store (GCC) могут сделать ваш код более согласованным и воспроизводимым на разных платформах за счет производительности , При некоторой настройке это обеспечивает специальную «воспроизводимую» сборку, которую можно использовать специально для тестирования.
Андре
@ Андре - о да, мы попробовали все это. Это все еще трудно :-)
Вольфганг Бангерт
10

Недавно я использовал googletest для тестирования нескольких числовых библиотек, над которыми я работаю, и был очень доволен этим. Вы можете написать довольно простые тесты очень быстро или вы можете написать сложные тесты, которые требуют инициализации данных и так далее. Он также предоставляет (как я уверен, что многие другие делают) способы простого сравнения с плавающей запятой, а не побитового.

Скиллман
источник
Хорошая вещь о googletest заключается в том, что они позволяют легко включать его исходный код в приложение, поэтому вам не нужно делать его зависимым.
Джефф Оксберри
4

Если вы создаете свой код с помощью CMake, то механизм ctest будет очевидным выбором. Он позволяет вам тестировать ваш код вручную с помощью команды ctest, а также поддерживает обширное ночное тестирование через CDash .

Нико Шлёмер
источник
1

Для нашей библиотеки C ++ по вычислительной биологии ( Chaste ) мы используем http://cxxtest.com/ . Это довольно простой в использовании, хорошо работает, он предоставляет несколько макросов для тестирования с помощью assert()операторов стиля. Для научных вычислений это, как правило, простые прямые сравнения TS_ASSERT_EQUALS(a,b)или численные сравнения с TS_ASSERT_DELTA(a,b,tolerance).

Дополнительные макросы могут быть легко написаны с использованием этих основных, чтобы сравнить ваши собственные векторы / матрицы по вашему выбору. Полезно также проверить, что ваш код выдает соответствующие предупреждения и сообщения об ошибках в определенных ситуациях. Вы можете просмотреть некоторые примеры в testпапках нашего исходного кода здесь: https://chaste.cs.ox.ac.uk/trac/browser/trunk

mirams
источник