TDD для Embedded.

На своей работе занимаюсь написанием кода для разных микроконтроллером. Но потом приходиться всё тестировать, и тестировать приходиться каждый раз когда идут даже самые простые изменения в прошивке, например смена значения константы и т.д. К примеру изменения в прошивке и компиляцию можно сделать меньше чем за 5 минут, а тестировать нужно примерно часа 5 или больше ( всё завысит от тестплана). Хочу автоматизировать процесс тестирования, так как например делают наши высокоуровневые коллеги — пишут автоматизирование тесты (TDD). Хочется чтобы запустил тестирование и через некоторое время увидел результ — тест такой — pass/fail.

Начал читать книгу: Test Driven Development for Embedded C пока понимаю не много…
Также понемного разбираюсь с библиотекойPySerial — очень просто работать с ком портом.

Само тестирование вижу так:
запустил скрипт или программу на компе, программа конектиться с МК по UART и обмениваеться данными. Программа (скрипт) на компе шлёт данные в МК, а сама знает заведомо правильный результат. МК обрабатывает принятый результат и посылает обратно на комп, программа сравнивает — если сошлось — pass, не сошлось — fail.

Кто нибудь делал подобное?
  • 0
  • 18 августа 2013, 20:53
  • Nemo

Комментарии (24)

RSS свернуть / развернуть
Какое совпадение, мой пост несколько часов назад на ту же тему.

Не так просто, а если важно реальное вермя?
0
C реальным временем будет сложно, или невозможно.
0
действительно совпадение
я тоже вот несколько дней занимаюсь изучением инструментов автоматического тестирования вебприложений
сейчас только что поставил imacros, хочу чтобы макрос постил мои объявления на доску, а то за подъем надо денежку платить, а тут стер и снова выставил автоматом
0
Не, этого мало. Всё, что вы описываете, можно потестить на ПК.
А как будешь тестировать реал-тайм задачи, где скорость отработки не позволяет ни то, чтобы дожидаться ответа от ПК, а даже просто отправить пару байт? Анриал! Увы, но сложные вещи можно отлаживать, делая тесты в самой прошивке, или только осциллом/ лог. анализатором.
Простой пример: usb dongle для rfm22. Как проверить при помощи тестов, успевает ли usb за радимодулем?
0
  • avatar
  • dekar
  • 18 августа 2013, 21:21
Кроме риалтайм есть и меддленные процесы, например автоматика — тест эмулирует превышение термпературы, и смотрим как отрабатывает термическая защита (наприример отключение нагрузки, или включения кулера). А если задача сложнее, несколько датчиков, для теста в железе нужно нагревать каждый датчик, измерять температатуру и смотреть как система работает. + тестом можно протестировать весь рабочий диапазон температур…
0
Если Вас интересуют только медленные процессы, то что мешает сделать именно так, как Вы написали?
А вообще, в идеале, надо отрывать контроллер от всей периферии и втыкать в стенд, который будет эмитировать всю эту самую периферию (причём, самое главное, эмитировать не корректное поведение, которое можно проверить и в приборе, а всевозможные сбои). Но это идеал и вряд ли многие так делают. У меня тупо никогда не хватает времени на разработку подобных стендов (хотя в рамках дипломного проекта как раз нечто такое делал).

С другой стороны, прогонять весь набор тестов после каждого мелкого изменения особого смысла нет — надо гонять только те тесты, на которые оно должно было повлиять (например, зачем проверять коммуникационный стек, если изменились формулы в измерительной части, а вот тайминги проверить не лишне). Полный набор тестов надо прогонять перед релизом очередной версии. ИМХО.
0
У нас есть прибор, прошивка написана, работает. Так вот, через некоторое время заказчик хочет что нибуть изменить, например диапазон срабатывания защиты, или яркость — после смены от хочет результаты полного тестирования, как при первом релизе. Согласен, смысла в полном тестировании нет. Но как правило заказчик очень далек от инжиннерии и программирования… и в большинстве случаев с ним не спорят…
0
в итоге получаеться добавил пробел и полностью перетестируй…
0
Как программист не смог удержаться от ответа. Так вот, то, о чем вы говорите — это интеграционное тестирование. Оно необходимо на этапе интеграции в железку. TDD же предполагает так называемое Unit-тестирование, когда код проверяется тестами на корректность и отсутствие логических ошибок. Как правило unit-тесты пишутся для наименьшего возможного блока кода — в идеале для каждой функции. Взаимодействие же нескольких модулей, а уж тем более в железе — это уже функциональное и интеграционное тестирование.
+1
Я не знаю как правильно называються термыни, но смысл в тому чтобы сделать ручное тестирование минимальным. Представте, сменил константу 10 на 20 и пол дня эмулируеш перегрев, низкое или критическое напряжение и другое…
0
Как правило unit-тесты пишутся для наименьшего возможного блока кода — в идеале для каждой функции
Тоесть, например, можно не менять название функции, а в теле фунции сменить что нибудь и быстро протестировать, не поменялся ли функционал, правильно?
0
Тоесть, например, можно не менять название функции, а в теле фунции сменить что нибудь и быстро протестировать, не поменялся ли функционал, правильно?
Ну по сути да, так и делается. В книге как раз и раскрывается эта идея.
Насчет полдня эмулировать перегрев. Во первых, если я правильно вас понял, это уже относится к интеграционному тестированию,gпоскольку эмулировать в коде такое невозможно, и тестируется уже используя либо спец. оборудование (стенд, который будет нагревать и менять напряжение), либо по старинке — ручками.
Во вторых о подходе. Есть фанатики TDD которые стремятся автоматизировать все на свете и написать тесты для всего. В итоге когда немного меняются требования — нужно переписать половину тестов. Тут я (как и многие) предпочитают руководствоваться здравым смыслом — некоторые вещи достаточно сложно симулировать и тестировать, и на придумывание и написание тестов уйдет больше времени, чем это понадобилось бы на просто пошаговый дебаг.
+1
Кстати, на тему фанатиков — интересное чтиво eao197.blogspot.ru/2011/12/progtesting-sqlite.html
И примечание с хабра —
>>Ни в каком другом open-source проекте такой помешанности на тестах не встречал. В sqlite кода тестов в 1000+ раз больше, чем собственно кода проекта, даже с учетом того, что многие тесты написаны на более высокоуровневом Tcl. (C)
+1
Благодарю, читал уже. Там кстати это оправдано, учитывая сколько всего завязано на этот sqlite — и андроид, и ios, и на десктопе много, и еще б.г знает где…
+1
Добавлю как пример: используется в Mozilla Thunderbird/Seamonkey, Opera.
0
Почитал и впечатлился.
Оказывается, всё же есть положительные примеры, когда в open-source делается через не через пень-колоду.
0
Ddesideria прав, это не совсем TDD, это просто тестирование. TDD — это методология разработки (хоть она и ставит тест-кейсы в приоритет).

программа конектиться с МК по UART и обмениваеться данными. Программа (скрипт) на компе шлёт данные в МК

Ели все функции устройства сводятся к общению по UART — то да, так можно. В некоторых случаях можно даже дробиться 100% покрытия. Но вот только не всегда функциональность к этому сводится.

Из того что я видел, либо для конкретного устройства делают тестовый стенд (а уже стендом управляет скрипт). Либо, более бюджетный (но менее правильный) вариант — залезать в устройство через отладочный интерфейс.
0
Ели все функции устройства сводятся к общению по UART — то да, так можно. В некоторых случаях можно даже дробиться 100% покрытия. Но вот только не всегда функциональность к этому сводится.
почему же, можно по уарту передавать параметры в функцию, например чтения результата АЦП.(тем самим тестировать функцию обработки АЦП)

Из того что я видел, либо для конкретного устройства делают тестовый стенд (а уже стендом управляет скрипт). Либо, более бюджетный (но менее правильный) вариант — залезать в устройство через отладочный интерфейс.
Где можно почитать подробнее?
0
почему же, можно по уарту передавать параметры в функцию, например чтения результата АЦП

Можно, но ведь в реальном коде параметры не передаются из UART  а читаются из АЦП. Следовательно Вам, для тестирования, придется писать специальный код, который будет читать параметры из UART  а не из АЦП. И тестировать вы будете не «боевой» код, а этот, тестовый. Это, однозначно, лучше чем ничего, но тест получится синтетический. В идеале, тестироваться должен тот код, который будет работать у заказчика и в реальных условиях. В Вашем случае — мы получаем unit-тесты, которые выполняются непосредственно на устройстве. Это хорошо, но это синтетический тест на специальном коде.

Где можно почитать подробнее?

Честно говоря — даже не знаю. На этом принципе было построено тестирование в одной из компаний, где я кода-то работал. Не самый удобный механизм, там есть куча подводных камней. Но он был дешев и относительно эффективен. Во сути, писались тестовые сценарии, которые для общения с чипом использовали GDB.
+1
для серьезных вещей собираются тестовые стенды. там уже в реальном времени эмулируются данные с датчиков и исполнительные механизмы (при чем не всегда автоматизированно). данные потом сбрасываются на комп по необходимости
0
  • avatar
  • xar
  • 18 августа 2013, 23:44
В общем, что-то подобное я делал. Есть такой старый комбаин под названием Symantec ProComm (поищите, сейчас под рукой нет). В нем в том числе есть эмулятор терминала. Так вот в нем можно запускать самописные скрипты. Например: дать команду Х, подождать Y секунд, если в ответе есть Y, то сделать то-то, если нет то вывести диалоговое окно с таким-то содержанием пользователю… Там есть переменные, циклы, разные константы типа даты и времени и т.д. Вполне нормально. Я делал как раз систему автоматического тестирования pass/fail, в конце вылетало окно с результатом и даже с примерным местом возникновения ошибок, если таковые были. Если у вас система команд не будет меняться от версии к версии (а судя по тому, что вы будете менять по мелочи, то она меняться не должна), то и тесты переделывать не надо.
Ясно, что внешнее воздействие на систему — это уже совсем другое.
0
У меня на текущем проекте тестирование строится примерно по такой схеме:
1) Тесты разработчика — модульные, интеграционные, функциональные (unit, integrational, functional). Они для разработчика, т.е. для меня и кроме меня до них никому дела нет. 90% автоматизировано.
2) Приёмочные (acceptance) — запускаются сразу после прошивки для каждого, техником, который эту прошивку осуществляет. На выходе результат — годно/негодно. Полностью автоматизировано.
3) Типовые — самые суровые, испытание во всём диапазоне температур, напряжений питания и т.д., проверяется каждый параметр из ТЗ. Проводится для 1-2 изделий из партии.

Модульные тесты покрывают почти весь код, выполняются автоматизированно на ПК при каждой сборке. Объем кода тестов примерно в 2 раза больше тестируемого кода.
Тесты HAL — частично автоматизированны, выполняются, естественно, в железе.
Для интеграционных тестов я в последнее время использую dual targeting. Подменяется HAL уровень и боевая прошивка полностью запускается на ПК. Коммуникационные интерфейсы МК имитируются через Pipe-ы — благо практически любая программа, рассчитанная на работу с КОМ портом, прекрасно будет работать и с Pipe-ом. Объект «управления» подменяется математической моделью. Для различных внешних устройств тоже не сложно сделать виртуальную реализацию. Например тут это сделано для графического дисплея.
+2
Специфика использования микроконтроллеров такова, что очень небольшую часть кода можно протестировать юнит-тестами, и обычно эту часть можно протестировать и на компьютере, например стек GSM. Огромное количество проблем связано с аппаратными особенностями интерфейсов и периферии. У меня статистика такова что на один баг в логике программы приходится 2-3 связанных с периферией (неточно рассчитанный таймер, неучтенная особенность протокола по интерфейсу SPI/I2C/etc, хитрые глюки с задержками в ожидании данных и переключении задач). Всё это можно полностью проверить лишь вживую, альтернатива это предвидеть ВСЕ возможные задержки и ошибки данных, написать под них тесты и написать интерфейс для тестов. Но тогда уж проще сразу писать хороший код.
Я стараюсь писать раздельно низкоуровневое АРІ и тестировать его на контроллере с эррратой, и отдельно на компьютере логическую платформонезависимую часть кода. Если есть тяжелая математика — дополнительно тестирую математику на контроллере, но это более актуально для 8 бит. Самый гемморой это сведение этих двух частей, если используется ОСРВ или планировщик с критическими задачами.
0
Другое дело это писать на компьютере автоматические тесты для консоли контроллера. Это очень полезно, когда вместо чтения километровых логов с ночи тест сразу пишет когда и какой был сбой.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.