Модульное тестирование кода C ++ - Инструменты и методология [закрыто]


134

Я работаю над большой системой C ++, которая находится в разработке уже несколько лет. В рамках усилий по улучшению качества существующего кода мы приняли участие в крупном долгосрочном проекте по рефакторингу.

Знаете ли вы хороший инструмент, который может помочь мне написать модульные тесты на C ++? Может быть, что-то похожее на Junit или Nunit?

Может ли кто-нибудь дать хороший совет по методологии написания модульных тестов для модулей, которые были написаны без учета модульного тестирования?


1
Проверьте этот вопрос: stackoverflow.com/questions/3150/…
Aardvark

Ответы:


83

Применение модульных тестов к унаследованному коду было той самой причиной, по которой была написана « Эффективная работа с устаревшим кодом» Автором является Майкл Фезерс - как уже упоминалось в других ответах, он участвовал в создании как CppUnit, так и CppUnitLite .

альтернативный текст


4
Добавил миниатюру - проголосовал за. Книга помогает больше, чем любой инструмент.
Гишу

2
Я думаю, что CPPUnit может упростить написание тестов. Мы используем CPPUnit, но я не удовлетворен. Мне нужно обновить два файла для каждого теста, и, по моему мнению, тест должен быть таким же простым, как: 'TEST ("testname") {ASSERT (1 == 1);}' Книга с другой стороны обязательно для всех, не только для тех, кто работает с унаследованным кодом, но и для тех, кто его создает;)
daramarak

9
С каких пор С ++ унаследован ?!
Нильс

9
Дело не в том, что C ++ является унаследованным - если я правильно помню, эта книга определяет унаследованный проект как проект, для которого нет ни одного, или очень мало модульных тестов. Такие проекты, как правило, / сложны / для написания модульных тестов, потому что разработка, управляемая тестами, никогда не влияла на базу кода, так что писать их тривиально.
Арафангион

7
@Nils: Как упоминает один из обозревателей Amazon в этой книге, «унаследованный код - это код без юнит-тестов», и именно об этом и идет речь.
Дэвид Джонстон

40

Google недавно выпустил собственную библиотеку для модульного тестирования приложений на C ++, которая называется Google Test.

Проект на Google Code


1
Можно ли использовать это с VC ++
yesraaj

Кажется довольно хорошо, особенно то, как они должны добавить описание к каждому утверждению. С другой стороны, я лично предпочитаю иметь класс Unit Test вместо макросов, которые действительно не похожи на классы.
Wernight

3
Еще один приятный момент - возможности насмешки: code.google.com/p/googlemock
Филипп,

Я нахожу это НАМНОГО лучше, чем CPPUNIT, для которого требуются тонны макросов и магических файлов, чтобы тесты работали
Пол

30

Проверьте отличное сравнение между несколькими доступными наборами. Автор этой статьи позже разработал UnitTest ++ .

Что мне особенно нравится в этом (кроме того факта, что он хорошо обрабатывает исключения и т. Д.), Так это то, что существует очень ограниченное количество «администрирования» вокруг тестовых случаев и определения тестовых креплений.


2
Разве это не наша основная ошибка? У него есть хорошее представление о доступных проектах - но вместо того, чтобы улучшать их, он начинает свои собственные.
peterchen

@peterchen: да; но тогда UnitTest ++ настолько мал и легок, что имеет смысл быть отдельным проектом - его очень легко запустить и запустить.
TimStaley

24

Boost имеет библиотеку Testing, которая содержит поддержку модульного тестирования. Возможно, стоит проверить.


4
Я могу рекомендовать этот отличный инструментарий.
Роб

1
Да, повышение это путь. Никаких накладных расходов, просто попробуйте! Я на самом деле работал над своим собственным фреймворком в отчаянии, когда повышение пришло мне на помощь. Спасибо за повышение (за все!)
Дарамарак

Вы можете ознакомиться со статьей, которую я написал, для ознакомления с Boost Unit Testing. Beroux.com/english/articles/boost_unit_testing
Wernight

21

Ноэль Ллопис из Games From Within - автор книги « Изучение фреймворка юнит тестирования C ++» , комплексной (но уже устаревшей) оценки различных платформ модульного тестирования C ++, а также книги по программированию игр.

Некоторое время он использовал CppUnitLite, исправляя различные вещи, но в итоге объединился с другим автором библиотеки модульных тестов и создал UnitTest ++ . Мы используем UnitTest ++ здесь, и мне это пока очень нравится. Он имеет (для меня) точный правильный баланс сил с небольшим следом.

Я использовал собственные решения, CxxTest (для которого требуется Perl) и boost :: test. Когда я реализовал модульное тестирование здесь, на моей нынешней работе, это в значительной степени сводилось к UnitTest ++ против boost :: test.

Мне действительно нравятся большинство библиотек boost, которые я использовал, но имхо, boost :: test немного слишком сложен. Особенно мне не понравилось, что от вас (AFAIK) требуется реализовать основную программу тестового жгута, используя макрос boost :: test. Я знаю, что это не «чистый» TDD, но иногда нам нужен способ запуска тестов из приложения с графическим интерфейсом, например, когда в командной строке передается специальный флаг теста, а boost :: test не может поддерживать этот тип сценария.

UnitTest ++ был самой простой тестовой средой для настройки и использования, с которой я столкнулся в моем (ограниченном) опыте.


17

Я использую отличную библиотеку Boost.Test в сочетании с гораздо менее известной, но о, офигенной черепахой библиотекой : библиотекой фиктивных объектов, основанной на boost.

Поскольку пример кода говорит лучше, чем слова, представьте, что вы хотите протестировать calculatorобъект, который работает на viewинтерфейсе (это вводный пример Turtle):

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

Видите, насколько это легко и многословно, объявлять ли вы ожидание для фиктивного объекта? Очевидно, что тест не пройден, если ожидания не оправдались.


14

Я только что выдвинул свою собственную структуру, CATCH , там. Он все еще находится в стадии разработки, но я считаю, что он уже превосходит большинство других структур. У разных людей разные критерии, но я старался охватить большинство вопросов без слишком большого количества компромиссов. Взгляните на мою ссылку в блоге для дегустатора. Мои пять основных функций:

  • Только заголовок
  • Автоматическая регистрация функциональных и методических тестов
  • Разлагает стандартные выражения C ++ на LHS и RHS (поэтому вам не нужно целое семейство макросов assert).
  • Поддержка вложенных секций в функциональном приспособлении
  • Проверка имен с использованием естественного языка - генерируются имена функций / методов

Он также имеет привязки Objective-C.


4
doctest - это мое переопределение Catch с огромным акцентом на скорость компиляции - посмотрите FAQ, чтобы увидеть, как они отличаются
onqtam 10.10.16

9

CxxTest - это легкий, простой в использовании и кроссплатформенный JUnit / CppUnit / xUnit-подобный фреймворк для C ++.




6

В настоящее время я ищу модульное тестирование и макет фреймворка, который можно использовать в нашей компании для долговечной кодовой базы. Как вы знаете, список структур модульного тестирования для c ++ длинный, поэтому я применил некоторые фильтры, чтобы сократить его до полного набора, который можно рассмотреть более внимательно. Первым критерием фильтра было то, что он должен быть бесплатным. Вторым критерием была активность проекта. Я также искал фальшивые фреймворки, потому что они вам нужны, если вы хотите написать юнит-тесты.

Я придумал следующий список (приблизительно), отсортированный по активности, самая высокая активность вверху:

  • GoogleTest / GoogleMock: многие авторы используют Google. Это, вероятно, будет здесь некоторое время и получать обновления. Для моей собственной кодовой базы я переключусь на эту комбинацию в надежде запрыгнуть на самый быстрый поезд.

  • BoostTest + Turtle: не так часто обновляется, но среда тестирования является частью надстройки, поэтому ее следует поддерживать. С другой стороны, черепаха поддерживается главным образом одним парнем, но она негодует, поэтому она не мертва. Я использовал почти все свои возможности тестирования с этой комбинацией, потому что мы уже использовали библиотеку наддува на моей предыдущей работе, и в настоящее время я использую ее для своего личного кода.

  • CppUTest: обеспечивает тестирование и макетирование . Этот проект был активен с 2008 по 2015 год и имеет довольно много недавних действий. Эта находка была немного неожиданной, потому что многие проекты со значительно меньшей активностью появляются чаще при поиске в Интернете (например, CppUnit, последнее обновление которого было в 2013 году). Я не стал вдаваться в подробности, поэтому не могу ничего сказать о деталях. Редактировать (16.12.2015): Недавно я попробовал это и обнаружил, что этот фреймворк немного неуклюжий и "C-стильный", особенно при использовании фиктивных классов. Кроме того, казалось, что он имеет меньшее количество утверждений, чем другие структуры. Я думаю, что его главная сила в том, что его можно использовать с проектами на чистом Си.

  • QTest: библиотека тестов, которая поставляется с каркасом Qt. Техническое обслуживание должно быть гарантировано в течение некоторого времени, но я использую его скорее как вспомогательную библиотеку, потому что регистрация тестов является IMO более неуклюжей, чем в других средах. Насколько я понимаю, это заставляет вас иметь один тест-exe на тестовый прибор. Но вспомогательные функции тестирования могут быть полезны при тестировании кода Qt-Gui. У него нет насмешек.

  • Поймать: он имеет недавнюю активность, но в основном разработан одним парнем. Приятной особенностью этого фреймворка является альтернативный подход к фикстурам, который позволяет писать повторно используемый код фикстуры в самом тесте. Это также позволяет вам задавать имена тестов в виде строк, что хорошо, когда вы склонны писать целые предложения в виде имен тестов. Я желаю, чтобы этот стиль был разорван и помещен в googleTest ;-)

Макет Рамок

Количество фальшивых фреймворков намного меньше, чем количество тестовых фреймворков, но вот те, которые я обнаружил в последнее время.

  • Hippomock : активен с 2008 года, но только с низкой интенсивностью.

  • FakeIt : Активен с 2013 года, но более или менее разработан одним парнем.

Вывод

Если ваша кодовая база рассчитана на долгое время, выберите между BoostTest + Turtle и GoogleTest + GoogleMock . Я думаю, что эти два будут иметь долгосрочное обслуживание. Если у вас только недолговечная кодовая база, вы можете попробовать Catch с хорошим синтаксисом. Тогда вам нужно будет дополнительно выбрать насмешливый каркас. Если вы работаете с Visual Studio, вы можете загрузить адаптеры для запуска тестов для BoostTest и GoogleTest, что позволит вам запускать тесты с графическим интерфейсом тестера, который интегрирован в VS.


3

См. Также ответы на тесно связанный вопрос «Выбор инструмента / инфраструктуры модульного тестирования c ++», здесь


3

Также есть TUT , Template-Unit-Test, основанный на шаблонах фреймворк. Его синтаксис неудобен (некоторые называют это злоупотреблением шаблоном), но его главное преимущество заключается в том, что он содержится в одном заголовочном файле. .

Вы найдете пример модульного теста, написанного с TUT здесь.


2
Я создал библиотеку только для заголовков, обеспечивающую обертывание макросов, функцию проверки TUT и тестовый код декларации, чтобы упростить ее и предоставить информацию о номерах файлов и строк в случае сбоев. Вот ссылка на пост с примерами различий в выводе и коде, а также ссылка на проект на github: codecrafter.wordpress.com/2012/12/19/tutadapter1
Джош Хейтцман,

2

Я пробовал CPPunit, и это не очень удобно для пользователя.

Единственная альтернатива, которую я знаю, - это использование C ++. NET для упаковки ваших классов C ++ и написание модульных тестов с одной из платформ модульного тестирования .NET (NUnit, MBUnit и т. Д.)


2

CppUTest - это превосходный и легкий фреймворк для модульного тестирования на C и C ++.


1

Майкл Фезерс из ObjectMentor сыграл важную роль в разработке как CppUnit, так и CppUnitLite.

Теперь он рекомендует CppUnitLite



1

Взгляните на cfix ( http://www.cfix-testing.org ), он специализируется на разработке для Windows C / C ++ и поддерживает как пользовательский режим, так и модульное тестирование в режиме ядра.


Спасибо, что поделился. Я недавно начал использовать cfix для тестирования. Я искал способ просмотра стека вызовов как в случае пройденных, так и неудачных тестов. Есть ли способ в cfix для достижения этой цели?
tryToLearn

1

Если вы используете Visual Studio 2008 с пакетом обновления 1 (SP1), я настоятельно рекомендую использовать MSTest для написания модульных тестов. Затем я использую Google Mock для написания издевательств. Интеграция с IDE идеальна и позволяет и не несет накладных расходов CPPunit с точки зрения редактирования трех мест для добавления одного теста.


1

Я думаю, что VisualAssert отлично справляется с интеграцией VS. Это позволяет запускать и отлаживать тесты из VS, и вам не нужно создавать исполняемый файл для запуска тестов.


0

Проверьте фруктозу: http://sourceforge.net/projects/fructose/

Это очень простая структура, содержащая только заголовочные файлы и, следовательно, легко переносимая.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.