
Программируешь микроконтроллеры? Начитался про TDD или просто устал искать баги и переписывать код заново?
Друг, попробуй тесты.
В данной статье будет показано как интегрировать Ceedling в Eclipse/SW4STM32, чтобы при каждой сборке код проходил через тесты.
Инструкция по интеграции ceedling'a в eclipse от разработчиков весьма скудная а единственная найденная инструкция оказалась платной (это стало последней каплей):

Установка
На примере OS Windows, CubeMX и SW4STM32.
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

choco install mingw
choco install ruby
Открываем PowerShell.exe и выполняем:
gem install ceedling
cd /
ceedling new test_ceedling
cd test_ceedling
ceedling test:all

Создание проекта
Запуск CubeMX производить от имени администратора для создания проекта в директории диска С:/
Application structere -> advanced (иначе сходу не собирается проект).

Инициализируем ceedling в проект:
cd /
ceedling new test_ceedling
Создадим в проекте следующие структуру и c./h. файлы, добавим пути в project.yml:



Создадим новый Builder:

Arguments -> test:all

Запуск
Создадим ещё одно окно консоли для тестов:

Переключим его на отображение результатов Ceedling builder'a:

Нажимаем ctrl+B и видим результаты тестов в консоли:

Добавим периферию
Зачастую результат выполнения функции зависит от внешних составляющих.
Помимо инструмента для генерации тестов — Unity утилита Ceedling поддерживает CMock — генератор mock-объектов и заглушек.
Представим, что наш калькулятор при вычислении разницы,
a - b
если кнопка нажата, считает её иначе.
b - a
То в этом случае наши тесты могут выглядеть следующим образом:

Функция проверки нажатия кнопки была объявлена, но не реализована(не написана).
Нажимаем ctrl+B и видим результаты тестов в консоли:

В данном случае мы создали имитацию кнопки, на месте которой может быть UART, SPI, I2C и пр.
Заключение
Теперь при каждой сборке приложения справа в уголке можно будет наблюдать результат выполненных тестов:

Комментарии (7)
batman12345
23.02.2019 11:26Я не профессиональный программист. Несколько раз пытался понять, что же такое — тесты, но безуспешно. Из статьи получается, что программист должен вообразить и прописать все возможные и невозможные ошибочные сценарии, но как??? Они же ошибочные, а стал быть, при программировании о них даже не думаешь, а если думаешь, то уже не такие они и ошибочные…
lingvo
23.02.2019 12:04По идее правильные тесты должен писать не тот, кто написал код, а другой человек. Тогда результат обычно превосходит ожидания.
AndreyNagih
23.02.2019 15:38Немного не так. Вы пишете программу, которая должна выдавать требуемый результат, при правильных входных данных. А также, должна коректно обрабатывать ошибочные входные данные.
Вы пишете тесты с корректными входными данными, в них проверяете что результат требуемый. Также, вы пишете тесты с невалидными входными данными, и в них проверяете, что программа не упала и корректно залогировала ошибку, например.
Как придумать с какими данными запускать вашу программу? Об это суть есть наука о тестировании ПО. Там придумали ряд методик и подходов, позволяющих с одной стороны покрыть всевозможные граничные случаи, а с другой стороны не наплодить миллион тестов.
Гарантирует ли это то, что вы покроете все возможные ошибочные сценарии и в продакшене ошибки не произойдет? Конечно же нет. И конечно же всё зависит от вашего опыта.
Как приблизиться к идеальному результату? Изучать тестирование. Практиковаться в написании тестов. Ну и писать новые тесты на те баги, которые у вас нашлись в продакшене.
Главная ценность модульных тестов в том, что вы автоматизируете регрессионное тестирование, а это значит, что вы сможете быстрее выкатывать релизы, и не бояться менять существующий код, например для рефакторинга.
helicopter91
25.02.2019 12:48Мне когда-то на тему модульного тестирования для embedded очень понравилась вот эта книга: Test Driven Development for Embedded C by James W. Grenning. В целом, тестировать какие-то инкапсулироавнные модули при наличии нормального HAL вполне возможно. А вот если речь идёт об управлении каким-то физическим процессом в реальном времени, причём алгоритм работает по прерываниям от нескольких разных аппаратных блоков, то тут уже сложнее. Хотя всё-равно можно, например, проверить математику на предмет корректности и каких-нибудь целочисленных переполнений.
lingvo
Вообще-то в этом-то и заключается основная проблема тестов ПО для МК — вы должны имитировать железо полностью, со всеми сопутствующими эффектами, типа дребезга контактов и т.д. Если писать имитаторы для этого — можно замучаться и поэтому часто железное тестирование предпочитают софтверному.
Но вот с автоматизацией железного тестирования проблема стоит уже совсем в другой области.
ukt
Причем на эту самую имитацию тоже нужно написать тест.
lingvo
Угу. Причем часто этот тест — это инструкция для людей, а не для процессоров, что многократно усложняет задачу. :)