Как писать unit тесты си
Перейти к содержимому

Как писать unit тесты си

  • автор:

Написание модульных тестов для C/C++ в Visual Studio

С помощью окна Обозреватель тестов вы можете создавать и выполнять модульные тесты для C++. Делается это так же, как и для других языков. Дополнительные сведения об использовании обозревателя тестов см. в разделе Выполнение модульных тестов с помощью обозревателя тестов.

Некоторые функции, такие как Live Unit Testing, закодированные тесты пользовательского интерфейса и IntelliTest, не поддерживаются для C++.

Visual Studio включает в себя эти платформы тестирования C++ без дополнительных загрузок:

  • Платформа модульного тестирования Майкрософт для C++
  • Google Test
  • Boost.Test
  • CTest

Вы можете использовать установленные платформы или написать свой собственный адаптер теста для любой платформы, который вы хотите использовать в Visual Studio. Адаптер теста интегрирует компонент модульных тестов с окном Обозреватель тестов. В Visual Studio Marketplace доступно несколько адаптеров сторонних поставщиков. Дополнительные сведения см. в разделе Установка платформ модульного тестирования сторонних поставщиков.

Visual Studio 2017 и более поздних версий (Professional и Enterprise)

Проекты модульных тестов для C++ поддерживают CodeLens.

Visual Studio 2017 и более поздних версий (все выпуски)

  • Адаптер Google Test включен по умолчанию в рабочую нагрузку Разработка классических приложений на C++. Он содержит шаблон проекта, который можно добавить в решение. Щелкните правой кнопкой мыши узел решения в Обозревателе решений и выберите Добавить>Новый проект в контекстном меню, чтобы добавить шаблон проекта. Параметры адаптера также можно настроить в окне Сервис>Параметры. Дополнительные сведения см. в статье «Практическое руководство . Использование Google Test в Visual Studio».
  • Компонент Boost.Test включен по умолчанию в рабочую нагрузку Разработка классических приложений на C++. Он интегрирован с обозревателем тестов, но в настоящее время не имеет шаблона проекта. Его необходимо настроить вручную. Дополнительные сведения см. в статье «Практическое руководство. Использование Boost.Test в Visual Studio».
  • Поддержка CTest включена в компонент Средства CMake C++, который входит в рабочую нагрузку Разработка классических приложений на C++. Дополнительные сведения см. в разделе «Практическое руководство. Использование CTest в Visual Studio».

Более ранние версии Visual Studio

Вы можете скачать расширения «Адаптер Google Test» и «Адаптер Boost.Test» в Visual Studio Marketplace. Найти их можно на страницах Test Adapter for Boost.Test (Адаптер теста для Boost.Test) и Test Adapter for Google Test (Адаптер теста для Google Test).

Базовый процесс тестирования

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

Создание тестового проекта в Visual Studio 2022

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

Чтобы добавить новый тестовый проект в существующее решение:

  1. В Обозревателе решений щелкните правой кнопкой мыши узел решения.
  2. Во всплывающем меню выберите пункты Добавить>Новый проект.
  3. Задайте С++ для параметра Язык и введите «тест» в поле поиска. На приведенном ниже рисунке показаны тестовые проекты, доступные при установке рабочей нагрузки Разработка классических приложений на C++ и Разработка для универсальной платформы Windows.

C++ Test Projects in Visual Studio 2022

Создание тестового проекта в Visual Studio 2019

Тесты определяются и выполняются в одном или нескольких тестовых проектах. Проекты создаются в том же решении, что и тестируемый код. Чтобы добавить новый тестовый проект в существующее решение:

  1. В Обозревателе решений щелкните правой кнопкой мыши узел решения.
  2. Во всплывающем меню выберите пункты Добавить>Новый проект.
  3. Задайте С++ для параметра Язык и введите «тест» в поле поиска. На приведенном ниже рисунке показаны тестовые проекты, доступные при установке рабочей нагрузки Разработка классических приложений на C++ и Разработка для универсальной платформы Windows.

C++ Test Projects in Visual Studio 2019

Создание ссылок на другие проекты в решении

Чтобы обеспечить доступ к функциям в тестируемом проекте, добавьте ссылку на проект в тестовый проект. Щелкните правой кнопкой мыши узел тестового проекта в обозревателе решений. Во всплывающем меню выберите пункты Добавить>Ссылка. В диалоговом окне Добавление ссылки выберите проекты, которые нужно тестировать.

Add reference

Ссылка на объектный файл или файл библиотеки

Если тестовый код не экспортирует функции, которые требуется протестировать, добавьте выходные OBJ-файлы или LIB-файлы в зависимости тестового проекта. Дополнительные сведения см. в разделе Связывание тестов с объектным файлом или файлом библиотеки. Не включать файлы объектов, имеющие main функцию или другую стандартную точку входа, например wmain , WinMain или DllMain . При добавлении новых исходных файлов в проект обновите зависимости тестового проекта, чтобы включить соответствующие файлы объектов.

Добавление директив #include для файлов заголовков

Далее в CPP-файле модульного теста добавьте директивы #include для всех файлов заголовков, в которых объявляются тестируемые типы и функции. Введите #include » и активирует IntelliSense, чтобы помочь вам выбрать. Повторите эти действия для других заголовков.

Screenshot of the Solution Explorer showing an #include directive being added with IntelliSense highlighting a header file for inclusion.

Чтобы не вводить полный путь в каждой инструкции include в исходном файле, можно добавить необходимые папки в разделе Проект>Свойства>C/C++>Общие>Дополнительные каталоги включаемых файлов.

Написание методов теста

В этом разделе представлен синтаксис при использовании платформы модульного тестирования Майкрософт для C/C++. Он задокументирован в справочнике по API Microsoft.VisualStudio.TestTools.CppUnitTestFramework. Документацию по Google Test см. на странице Google Test Primer (Начало работы с Google Test). Сведения о Boost.Test см. на странице Boost Test Library: The Unit Test Framework (Библиотека Boost.Test: платформа модульного тестирования).

В CPP-файле в тестовом проекте определены класс-заглушка и метод-заглушка. Они служат примером того, как следует писать код теста. В сигнатурах используются макросы TEST_CLASS и TEST_METHOD, что позволяет обнаруживать методы в окне обозревателя тестов.

Screenshot of the Test Explorer window that shows the unittest1.cpp code file containing a stub class and method using the TEST_CLASS and TEST_METHOD macros.

TEST_CLASS и TEST_METHOD являются частью собственной платформы тестирования Microsoft. Обозреватель тестов обнаруживает методы теста в других поддерживаемых платформах аналогичным образом.

TEST_METHOD возвращает пустое значение. Чтобы получить результат теста, используйте статические методы класса Assert для сравнения фактических результатов с ожидаемыми. В приведенном ниже примере предполагается, что MyClass имеет конструктор, принимающий std::string . В этом примере показано, как можно проверить, что конструктор инициализирует класс так, как ожидается:

TEST_METHOD(TestClassInit)

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

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

Запуск тестов

Test Explorer before running tests

  1. В меню Тест выберите пункт Windows>, а затем пункт Обозреватель тестов. На рисунке ниже показан тестовый проект, тесты которого еще не выполнялись.

Примечание. Интеграция CTest с обозревателем тестов пока не доступна. Запустите тесты CTest в главном меню CMake.

Test Explorer after tests are run

  • Если в окне видны не все тесты, выполните сборку тестового проекта, щелкнув правой кнопкой мыши его узел в Обозревателе решений и выбрав Сборка или Перестроить.
  • В обозревателе тестов нажмите Запустить все или выберите тесты, которые следует запустить. Щелкните тест правой кнопкой мыши, чтобы получить доступ к другим командам, включая запуск в режиме отладки с включенными точками останова. После выполнения всех тестов в окне отображаются тесты, которые прошли и которые завершились сбоем.
  • Для завершившихся сбоем тестов приводятся подробные сведения, которые могут помочь установить причину. Щелкните неудачный тест правой кнопкой мыши. Во всплывающем меню выберите команду Отладить для пошагового выполнения функции, в которой произошел сбой.

    Дополнительные сведения об использовании Обозревателя тестов см. в разделе Выполнение модульных тестов с помощью Обозревателя тестов.

    Дополнительные сведения о модульном тестировании см. в статье Основные сведения о модульных тестах.

    Использование CodeLens

    Visual Studio 2017 и более поздних версий (выпуски Professional и Enterprise)

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

    Инициализировать CodeLens для проекта модульного теста C++ можно любым из перечисленных ниже способов.

    • Отредактировать и собрать тестовый проект или решение.
    • Перестроить проект или решение.
    • Запустить тесты из окна обозревателя тестов.

    После инициализации значки состояния тестов отобразятся над каждым модульным тестом.

    C++ CodeLens Icons

    Щелкните значок для получения дополнительных сведений или выполните или отладите модульный тест:

    C++ CodeLens Run and Debug

    Связанный контент

    Как писать юнит-тесты. Рабочие примеры и подробное руководство

    Lorem ipsum dolor

    Прежде чем искать , как написать юнит — тест, нужно определиться, а нужен ли он вашему приложению? Ведь написание unit — тестов — это дополнительные работа и время, поэтому это не всегда эффективно в небольших разработках.

    С другой стороны, есть мнение , что сложные разработки лучше начинать с написания тестов, а не с самой программы. И в этом есть свои преимущества, к примеру, в таком случае у вас будет уже готовая структура будущего приложения и вы точно не сделаете спагетти-код в своей будущей разработке.

    Если вы определили, что ва м необходимо написание unit — тестов, то относитесь к этому процессу так же серьезно, как и к самой разработке — это сэкономит вам в дальнейшем кучу времени.

    Мы будем очень благодарны

    если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

    Как писать юнит-тесты. Рабочие примеры и подробное руководство

    Lorem ipsum dolor

    Прежде чем искать , как написать юнит — тест, нужно определиться, а нужен ли он вашему приложению? Ведь написание unit — тестов — это дополнительные работа и время, поэтому это не всегда эффективно в небольших разработках.

    С другой стороны, есть мнение , что сложные разработки лучше начинать с написания тестов, а не с самой программы. И в этом есть свои преимущества, к примеру, в таком случае у вас будет уже готовая структура будущего приложения и вы точно не сделаете спагетти-код в своей будущей разработке.

    Если вы определили, что ва м необходимо написание unit — тестов, то относитесь к этому процессу так же серьезно, как и к самой разработке — это сэкономит вам в дальнейшем кучу времени.

    Мы будем очень благодарны

    если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

    Юнит тесты на Си — нет ничего проще

    Прочитав статью «Тестирование встроенных систем» и комментарии к ней я был несколько поражен тем фактом, что многие хабровчане знакомы с книгой «Test Driven Development for Embedded C (Pragmatic Programmers)» и framework-ом Unity, но не используют весь арсенал средств, которые предлагают ребята из throwtheswitch.org.

    Хочу кратко поделится опытом использования этих самых средств.

    О себе

    Так получилось, что я нарабатывал свой опыт в программировании встраиваемых систем через тесты (Unit, Integration, System, Stress). За три года мне посчастливилось пройти путь от Junior’a и написания тестов, покрывающих код других специалистов, до Senior’a с опытом разработки систем с использованием TDD методологии.

    Обещанное

    Упомянутый выше framework Unity очень прост и удобен в использовании. Но это всего лишь вершина айсберга. На странице throwtheswitch.org есть следующие инструменты.

    CMock — инструмент позволяющий автоматически генерировать Си-код mock-ов для Ваших тестов. Написан на Ruby. Утверждаю, как человек, который на протяжении трех лет «генерировал» mock-и руками — это просто подарок для Си-разработчика. Но использовать его автономно без следующего инструмента, на мой взгляд, не рационально.

    Ceedling — это целая билд-система, как утверждают сами авторы. Но по сути — это все, что Вам нужно для работы. Данный пакет содержит в себе все необходимое: Unity («тест-раннеры» и «чекалки» значений), CMock (генератор моков) и поддержку командной строки через ruby make.

    Other — под этим странным заголовком находится очень, полезный, на мой взгляд инструмент — CException. Невероятно маленькая библиотека для Си позволяющая получить некое подобие исключений. Но дезинформировать не буду. В проектах использовать не довелось.

    Единственное, что оставляет желать лучшего в этом многообразии прекрасных вещей, так это tutorial. Его, как бы, и нет. Все понятно, но с чего новичку начать — большой вопрос. Попробую исправить ситуацию.

    Прежде всего, Ceedling должен быть корректно установлен и проверен на работоспособность как указано тут.

    После установки создаем папку и тестовое окружение проекта командой:

    ceedling new MyNewProject 
    • build — сюда будут помещаться все артефакты при сборке и прогоне тестов
    • src- это место для нашего «боевого» кода, который подлежит тестированию
    • test — будут лежать все наши тесты
    • vendor — собственно сам framework, с документацией и плагинами
    • project.yml — конфигурационный файл тестового проекта. Позволяет делать хороший тюнинг, но это с опытом

    Пора писать первый тест.

    Поместим в папку test файл test_calc.c следующего содержания:

    #include "unity.h" #include "calc.h" void setUp(void) < >void tearDown(void) < >void test_add( void )

    Запускаем тест командой:

    ceedling test:test_calc.c 

    Результат ожидаемый. Тест есть, кода нет. Проект не может быть собран.

    Добавляем код.
    В папку src помещаем два файла:

    #ifndef CALC_H #define CALC_H int calc_add(int a, int b); #endif 
    #include "calc.h" int calc_add(int a, int b)

    Повторяем сборку и попытку прогнать тест:

    ceedling test:test_calc.c 

    Если все сделано правильно, то в консоли должны быть результаты теста:

    Test 'test_calc.c' ------------------ Compiling test_calc_runner.c. Compiling test_calc.c. Compiling calc.c. Compiling unity.c. Compiling cmock.c. Linking test_calc.out. Running test_calc.out. ------------------------- OVERALL UNIT TEST SUMMARY ------------------------- TESTED: 1 PASSED: 1 FAILED: 0 IGNORED: 0 

    Этот короткий пример показывает, что test-runner был сгенерирован и добавлен в сборку автоматически. Его код можно найти в папке build/test/runners.

    Попробуем усложнить задачу и предположим, что наш «боевой» файл должен уметь считать только при определенном условии, проверка которого осуществляется в другом программном модуле (например, rules.c). Модифицируем код, для иллюстрации:

    #include "calc.h" #include "rules.h" int calc_add(int a, int b) < if (rules_is_addition_allowed()) < return a + b; >return 0; > 

    Добавим еще один файл в папку src:

    #ifndef RULES_H #define RULES_H int rules_is_addition_allowed(void); #endif 

    Попытка запустить тест будет неудачной, так как нет определения для функции rules_is_addition_allowed().

    Самое время воспользоваться CMock.
    Изменим тест следующим образом:

    #include "unity.h" #include "calc.h" #include "mock_rules.h" void setUp(void) < >void tearDown(void) < >void test_add( void ) < int result = 0; rules_is_addition_allowed_ExpectAndReturn(1); result = calc_add(2,2); TEST_ASSERT_EQUAL_INT( 4, result ); >void test_add_off_nominal( void )

    Таким образом, мы получили автоматически сгенерированный mock одним лишь указанием «#include «mock_rules.h». Исходный код данного файла можно найти в директории build/test/mocks. Его изучение даст хорошее представление о том, каким образом можно менять поведение подменяемого модуля.

    Оговорочки

    1. Я использую данный framework только для тестирования кода на PC. Это диктует определенные правила к архитектуре разрабатываемого ПО. Прогонять юнит тесты на реальном железе смысла не вижу. HAL — он либо работает либо нет и тестируется мануально (мое видение ситуации);
    2. Я не использую данный framework для тестирования нескольких потоков. Потокобезопастность данного инструмента мной не исследовалась;
    3. Данная статья не учит как правильно писать код и/или тесты, а всего-лишь дает краткое представление об упомянутых выше инструментах разработки.

    • Тестирование IT-систем
    • TDD

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *