Библиотеки модульного тестирования C++

Я сталкивался с cppunit, но он не выглядел супер-простым в использовании (может быть, я не выглядел жестко, может быть, потому что C++ не работает как Java/C#). Есть ли широко используемые простые альтернативы?

Фактически, является ли cppunit стандартной структурой модульного тестирования для C++?

8 ответов

Решение

Для C++ нет стандартной библиотеки модульного тестирования. Есть много вариантов на выбор; Cppunit является одним из них.

В моей компании мы используем Google Test вместе со своим партнером Google Mock для модульного тестирования и моделирования объектов. Я нахожу их обоих более простыми в использовании и намного более мощными, чем cppunit.

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

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

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

В качестве примера, вот как вы бы написали эквивалент примера gtest, который цитировал @dmeister:

TEST_CASE( "Factorial/Handles zero input", "Tests factorial of 0.") 
{
  REQUIRE( Factorial(0) == 1 );
}

TEST_CASE( "Factorial/Handles positive input", "Tests factorial of positive numbers.") 
{
  REQUIRE( Factorial(1) == 1 );
  REQUIRE( Factorial(2) == 2 );
  REQUIRE( Factorial(3) == 6 );
  REQUIRE( Factorial(8) == 40320 );
}

Если тест не пройден, вы все равно получите значения LHS и RHS, записанные независимо.

Google Test Framework является альтернативой.

Вот простой пример из документации:

// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(1, Factorial(0));
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
}

Это также хорошо работает с gmock, фиктивной платформой Google для C++.

Я создал набор тестов под названием saru ( http://github.com/mikeando/saru) для своего собственного кода разработчика. Это лицензионный код BSD. Я разработал его, так как мне не нравились некоторые особенности других наборов тестирования. Он не очень широко используется, но я использовал его в нескольких коммерческих проектах, распределенных между двумя компаниями.

  1. Мне не нравится, когда все мои тесты собираются в один бинарный файл. Мои причины для этого состоят в том, что если компиляция не проходит, все тесты не выполняются, если один тест выполняет неопределенное поведение, вывод программы не определен.
  2. Я хочу контролировать, какие тесты запускаются. Я хочу иметь возможность группировать тесты и запускать подмножества.
  3. Я хочу, чтобы о сбое компиляции теста сообщалось как о неудаче теста, а не о прекращении всех моих тестов.
  4. Я хочу иметь возможность запускать тесты на разных языках
  5. Я хочу, чтобы система была достаточно гибкой, чтобы я мог запускать определенные тесты под valgrind (пока нет в saru:()

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

//SARU : dummy dummy
int main() { return (1==2)?0:1; }

Все, что действительно волнует saru - это возвращаемое значение двоичного файла, который он компилирует. Затем он анализирует выходные данные, чтобы определить, какие тесты не пройдены и так далее. У него есть заголовки, чтобы сделать работу с C++ немного лучше, чем приведенный выше тривиальный пример:

//SARU : dummy dummy
#include "MyStruct.h"
#include "saru_cxx.h"

class Fixture
{
  MyStruct s_;
  Fixture() : s_() {}
  void test_A_is_B()
  {
     SARU_ASSERT_EQUAL( s_.A(), s_.B() );
  }

  void test_C_is_7()
  {
     SARU_ASSERT_EQUAL( 7, s_.C() );
  }
};

int main()
{
   saru::TestLogger logger;
   SARU_TEST( Fixture:: test_A_is_B, logger );
   SARU_TEST( Fixture:: test_C_is_7, logger );
   logger.printSummary();
   return logger.allOK()?0:1;
}

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

Но он также будет запускать тесты, написанные на PHP и Python. Таким образом, вы можете настроить полные функциональные тесты с SARU. Или вы можете запустить что-то вроде lint поверх своего кода как часть набора тестов.

CppUnit, вероятно, является первым модульным тестовым фреймворком для C++. Это прямой порт Junit, знаменитой платформы Java. Это облегчает переход с Junit, но за счет довольно тяжелой среды, которая не использует возможности C++, такие как RAII. Вот почему были созданы легкие версии, такие как CppUnitLite, NanoCppUnit. CppUnit2 должен был улучшить это, среди других улучшений.

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

Что касается "стандартного" фреймворка, то его нет, и C++1X не определяет его.

Вот минимальная библиотека модульного тестирования C++: https://github.com/vahidk/minimal-cpp-test

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

Вот минимальный юнит-тест:

#define DEFINE_TEST_MAIN    
#include "test.h"
TEST(GroupName, TestName) {
  EXPECT_EQ(1 + 2, 3);
}

И минимальное крепление:

class ClassName : public cyrus:Test {
public:
  void Setup() override { 
    x = 5;
  }
  int x;
}

Test_F(ClassName, Test1) {
  EXPECT_EQ(x, 5);
}

Надеюсь это поможет.

Вот один заголовочный файл, включающий только решение для модульного тестирования C++: https://gitlab.com/cppocl/unit_test_framework

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

#include "test/Test.hpp"

TEST(MyTest)
{
    int a = 1;
    int b = 2;
    CHECK_EQUAL(a + b, 3);
}

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

http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks

Однако, насколько я знаю, cppunit - самый популярный.

Другие вопросы по тегам