Добавляем Unit-тестирование в проекты STM32CubeIDE

от автора

А именно, мы будем добавлять отличную систему Сeedling. Данная система содержит в себе сразу два инструмента – Unity – непосредственно для проведения и написания тестов и CMock для генерации объектов-заглушек. Но самая большая заслуга данного пакета – простота во всех аспектах – начиная от генерации тестируемых модулей и до релиза проекта. Использование Сeedling превращает рутинное TDD (Разработка через тестирование) или TLD(если захочется так) в обычный рабочий процесс.

Как именно использовать данные инструменты:

  • Свежее переиздание Test Driven Development for Embedded C (Pragmatic Programmers) от James W. Grenning

  • Немного устаревшая(Ceedling уже не генерирует rake в тестируемом проекте и некоторые команды изменились), но все еще хорошая статья от Dmitry Frank

  • Конечно же, GIT разработчиков. Там найдется самая всеобъемлющая информация по использованию их инструментов, например, CMock, Ceedling.

Ну, и конечно, когда-то я соберусь с силами написать небольшую заметку

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

Как инициализировать тестирование в уже существующем проекте


Настройка окружения

Терминал

У Eclipse, на базе которой построен STM32CubeIDE, есть сложность с вызовом терминала в рабочей директории – он может открыть терминал, но он будет в папке с установленным STM32CubeIDE. Для удобства советую установить TM Terminal (А лучше работать в VSCode, где уже терминал поддерживается, а IDE использовать для генерации и построения исходников)

Он позволяет вызвать терминал в любой папке.

Инициализация

Для примера буду показывать на тестовом проекте, который назван programel_prj. Для инициализации системы тестирования введем следующие команды в открывшимся терминале

E:\programel_prj>cd ../ E:\>ceedling new programel_prj Welcome to Ceedling!       create  programel_prj/project.yml Project 'programel_prj' created!  - Execute 'ceedling help' from programel_prj to view available test & build task

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

Был создан файл project.yml и папка src. Папку src можно удалить. Если файлы не отобразились в окне с проектом можно обновить через F5.

Правка автогенератора

После инициализации проекта Ceedling, стоит произвести некоторые изменения в файле project.yml. Зачем? (Предположим, что инициализация проекта производится с помощью кодогенератора)

Структура проекта в STM32CubeIDE генерируется сама. После завершения настройки пинов, интерфейсов и т.д. в *.ioc-файле следует запуск кодогенератора. После чего будет произведено построение проекта с определенной структурой. Мы же хотим применить TDD подход при разработке новых модулей в проекте. Удобно, если сам Ceedling будет создавать заголовочные файлы и исходники в нужных местах.

В первую очередь добавим следующее в project.yml после секции с :project::

:project:   :use_exceptions: FALSE   :use_test_preprocessor: TRUE   :use_auxiliary_dependencies: TRUE   :build_root: build #  :release_build: TRUE   :test_file_prefix: test_   :which_ceedling: gem   :ceedling_version: 0.31.1   :default_tasks:     - test:all :module_generator:   :project_root: ./   :source_root: Core/Src/   :inc_root: Core/Inc/   :test_root: test/

Значит, мы добавили :module_generator: в котором определили где именно будут создаваться новые файлы модуля. Можно и название у папки test сменить, но меня это название устроило. Необходимо сообщить об этом и в секции :paths:

:paths:   :test:     - +:test/**     - -:test/support   :source:     - Core/Inc/**     - Core/Src/**

(Необязательно) В секции :cmock: с добавим дополнительный заголовочный файл с определением стандартных типов (uint8_t, int32_fast_t и т.д.)

:cmock:   :mock_prefix: mock_   :when_no_prototypes: :warn   :enforce_strict_ordering: TRUE   :plugins:     - :ignore     - :callback   :treat_as:     uint8:    HEX8     uint16:   HEX16     uint32:   UINT32     int8:     INT8     bool:     UINT8   :includes:    - <stdint.h>

Создание модуля

Создадим модуль module_sample. Для этого введем в TM Terminal следующее:

E:\programel_prj>ceedling module:create[module_sample] File Core/Src/module_sample.c created File Core/Inc/module_sample.h created File test/test_module_sample.c created Generate Complete

Отлично, все файлы создались в нужных местах!

Прям почти настоящее TDD!

В сгенерированных файлах весь код инактивирован проверкой определенного макроса. Чтобы это исправить – в настройках сборки, например, Debug определим макрос TEST.

И ещё – добавим заголовочный файл от Unity(unity.h) в папку Inc. Это позволит нам использовать автодополнение при написании непосредственно самих тестов.

Данный файл у меня располагается по следующему адресу – E:\Ruby30-x64\lib\ruby\gems\3.0.0\gems\ceedling-0.31.1\vendor\unity\src\


Автоматический прогон тестов при сборке

Чтобы тестирование прогонялось автоматически при каждой сборке – нужно добавить пару комманд в build steps. Все команды в мэйкфайлах выполняться в папках Debug или Relase – в зависимости от выбранной целевой сборки. Чтобы выполнить тестирование – нужно перейти выше по каталогу (в основную папку с проектом) и выполнить команду ceedling. Для добавления пользовательских команд, которые должны быть выполнены до или после сборки есть специальные поля ввода – pre/post build steps. Команды можно объединять в цепочки через специальные знаки (см. Chaining Commands в поисковике).

Мне было бы удобнее в post-build, но в моей версии STM32CubeIDE встроены специфичные генераторы make-файлов. Они форматируют строку post-build, всегда разделяя команды друг от друга. У меня не одного такие проблемы возникли – об этой гадости подробнее тут:

Eclipse Community Forums: C / C++ IDE (CDT) » Post-Build Step

cd ../; ceedling test;

В файле test_module_sample.c теперь все хорошо и весь необходимый синтаксис корректно подсвечивается. Изменений вносить в файл не будем, оставим как есть – один игнорируемый тест.

Запустим сборку Debug версии

Что мы видим в окне Console:

15:59:53 **** Build of configuration Debug for project programel_prj **** make -j12 all  cd ../; ceedling test; Test 'test_module_sample.c' --------------------------- Generating runner for test_module_sample.c... Compiling test_module_sample_runner.c... Compiling test_module_sample.c... Compiling unity.c... Compiling module_sample.c... Compiling cmock.c... Linking test_module_sample.out... Running test_module_sample.out... -------------------- IGNORED TEST SUMMARY -------------------- [test_module_sample.c]   Test: test_module_sample_NeedToImplement   At line (17): "Need to Implement module_sample" -------------------- OVERALL TEST SUMMARY -------------------- TESTED:  1 PASSED:  0 FAILED:  0 IGNORED: 1   arm-none-eabi-gcc "../Drivers/STM32F0xx_HAL_D..............

Отлично! Выполнился(был проигнорирован) один тест. Мы прикрутили тестирование к нашему проекту, теперь можно достаточно удобно пользоваться инструментом тестирования при разработке своих проектов в STM32CubeIDE.


ссылка на оригинал статьи https://habr.com/ru/articles/789202/


Комментарии

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

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