Я ищу некоторые передовые стратегии для кода модульного тестирования, написанного для встроенной системы. Под встроенной системой я подразумеваю код, такой как драйверы устройств, обработчики ISR и т. Д., Вещи, которые очень близки к металлу.
Большинство модульных тестов невозможно без тестирования на оборудовании с помощью ICE. Иногда встроенный блок также необходимо подключить к другим раздражителям, таким как механические переключатели, шаговые двигатели и лампочки. Это обычно происходит в ручном режиме, автоматизация была бы замечательной, но трудной и дорогой для достижения.
Обновить
Я наткнулся на фреймворк для тестирования на Си, который, похоже, довольно успешно тестирует встроенные проекты. Он использует идеи насмешливого оборудования. Проверьте Unity , CMock и, возможно, Ceedling .
Обновление 06 июля 2016
источник
Ответы:
Я хотел бы абстрагироваться от аппаратных зависимостей на самом раннем этапе и построить систему на основе программной эмуляции / тестирования, обеспечивающих всевозможные тестовые среды. Часто мой ПК для разработки использовался для тестирования целых 95% или более всей системы. Стоимость дополнительных издержек (еще один уровень абстракции) была легко компенсирована более чистым кодом, сгенерированным в результате этой абстракции.
Тестирование по-настоящему голых металлических деталей встроенной системы - это, как правило, отдельное приложение (модульный тест?), Которое сильно забивает прошивку за пределы того, что приложения могут даже надеяться достичь. Автоматизация может быть сделана - за плату, но это не типично.
Если, конечно, у вас нет бюджета для создания аппаратного обеспечения модульного тестирования, включая полный ICE. Это абсолютно нормально, так как обычно функциональные тесты небольшие.
источник
Необходимым инструментом для разработки является инжектор сигнала. Встроенная система будет иметь некоторый способ взаимодействия с хост-системой (обычно через последовательный порт, зарезервированный для отладки). Используйте это для отправки тестовых данных (лучший вариант - краткий формат ascii, поэтому его легко смоделировать и людям).
Я полностью не согласен с этой частью вашего вопроса: «автоматизация была бы прекрасной, но трудной и дорогой для достижения».
Используя TeraTerm в качестве инжектора сигналов последовательного порта и написание некоторых макросов TeraTerm (занимает около 20 минут), существует огромный набор автоматических тестов, которые можно запускать на любой части встроенной системы - будь то уровень драйвера, O / S, слой 4-5 и т. д. TeraTerm: http://en.sourceforge.jp/projects/ttssh2/
Если последовательный порт недоступен во встроенной системе, используйте аппаратный инструмент для преобразования данных через USB / последовательный порт в цифровые сигналы (также недорогие и легко доступные ). Когда вы читаете это, я использую плату микроконтроллера за 30 долларов США (UBW: http://www.schmalzhaus.com/UBW32/ ) для тестирования встроенной системы для производства, вводя стимул с помощью макросов TeraTerm, который отправляется через USB / serial на микроконтроллер, который выполняет модифицированную прошивку, которая осуществляет цифровые входы и контролирует цифровые выходы целевой встроенной системы. В связи с этим мы разработали скрипт на python (использует pyserial и pexpect) для автоматизации ввода и проверки данных. Ничего из этого не сложно и не дорого, По моему опыту, менеджеры тратят большие деньги (например, испытательное оборудование за 30 000 долларов США), когда команда тестировщиков неопытна и не может придумать эти простые решения - к сожалению, оборудование общего назначения большого чугуна часто не включает в себя контрольные примеры которые ловят наихудший случай времени / и т. д. целевой системы. Поэтому недорогой метод предпочтительнее для тестового покрытия. Хочешь верь, хочешь нет.
источник
Это очень сложная проблема.
На самом деле я спроектировал модуль модульного тестирования для встроенной системы, который позволял бы имитировать аппаратные события / прерывания и контролировать время выполнения (чтобы мы покрывали все возможные чередования из-за параллелизма), и потребовалась команда программисты более 2-х лет, чтобы реально реализовать это и запустить его в работу. Этот проект является частной разработкой, но похожий (более простой по дизайну) проект доступен здесь .
Так что да, автоматизация была бы великолепна. Да, это очень трудно и дорого достичь. Да, иногда ты должен это сделать. Тем не менее, по моему опыту, в большинстве случаев быстрее и дешевле использовать шаговые двигатели и лампочки и заставить все это работать вручную.
источник
Редактировать: мой ответ близок к Mattnz, я думаю ...
Я хочу связать эту проблему с другими, со всеми тестами, которые зависят от чего-то внешнего по отношению к вашему коду (например, системные часы, постоянная файловая система или база данных, связь с внешним веб-сервисом ...). Я предлагаю одинаковую политику для всех из них, изолировать два уровня в двух уровнях кода.
Тестирование одной внешней операции
Возможно, вы захотите физически проверить каждую операцию. Убедитесь, что системные часы показывают правильное время, проверьте, действительно ли файл запоминает записанное, проверьте, что устройство получает одну операцию ...
Эти тесты:
Тестирование логики (кода, алгоритма), которая связывает внешние операции
Имея слой кода для выполнения реальных внешних операций, скрывая их за интерфейсом, который вы легко можете смоделировать, ваша логика больше не зависит от реальных физических устройств ...
Вы можете просто протестировать, как любой обычный проект, вы больше не находитесь во встроенном, трудном для тестирования коде .
источник
Имитаторы встроенных процессоров, как правило, могут быть запрограммированы на симуляцию аппаратного обеспечения. Все технологии виртуализации, кроме Xen, делают это. Но вам нужно написать код, который претендует на наличие некоторых регистров по какому-то физическому адресу или, на x86, по адресу шины ввода-вывода, а затем вам нужно реагировать на чтение и запись по этим адресам, как если бы ваше программное обеспечение было физическим микросхема, чьи регистры управления и состояния были доступны.
Если вы хотите сделать это, я бы предложил изменить QEMU. Но это было бы нелегко. Подобные вещи обычно выполняются только тогда, когда вы разрабатываете специализированный чип с микроконтроллером и некоторыми другими ядрами для ввода / вывода.
Система разработки, продаваемая ARM Holdings, обеспечивает это и, вероятно, с ней легче работать, чем взламывать QEMU, но это очень дорого.
Существует несколько эмуляторов Open Source ARM, которые запускают одну подпрограмму, которая сама может вызывать другие подпрограммы, которые вы можете использовать для отладки настройки производительности подпрограмм, которые не зависят от аппаратного доступа. Я использовал один из них с большим успехом для оптимизации шифратора AES для ARM7TDMI.
Вы можете написать простой модуль модульного тестирования на C или C ++, связать с ним тестируемый класс или подпрограмму, а затем запустить его в симуляторе.
В течение многих лет я размышлял над подобной проблемой - как выполнить модульное тестирование кода ядра Linux или Mac OS X. Это должно быть возможно, но я никогда не пробовал. Возможно, стоит создать полное ядро, а не тестировать свой код изолированно, с модульным тестовым фреймворком, напрямую связанным с вашим ядром. Затем вы запускаете юнит-тесты с какого-то внешнего интерфейса.
Возможно, было бы более продуктивно использовать инструмент покрытия кода, а затем протестировать свою прошивку как полный пакет через ее внешний интерфейс. Инструмент покрытия найдет пути кода, которые еще не были протестированы, поэтому вы можете добавить дополнительные внешние тесты, чтобы получить больше покрытия.
источник
Как и в случае не встроенного TDD, фиктивные объекты , безусловно, ваш друг.
Сохраняйте интерфейс к своему базовому оборудованию чистым и простым, чтобы можно было смоделировать все, что находится ниже самого нижнего уровня, и вам будет намного проще - если вы разрабатываете встраиваемое приложение с учетом тестируемости, тогда тестирование всегда будет проходить гораздо более гладко ,
Кроме того, если вы не сможете проводить тестирование в режиме онлайн до тех пор, пока не опоздаете в проекте, это не означает, что вам также не следует готовить набор онлайн-тестов.
Они должны (первоначально) должны только проверить биты, которые не могли быть проверены в автономном режиме. Конечно, это не TDD (так как вы создаете тесты заранее), но ваша автономная разработка TDD должна дать вам хорошее представление о том, как должен выглядеть ваш аппаратный интерфейс и, следовательно, какие онлайн-тесты вам нужно выполнить.
Кроме того, если онлайн-разработка стоит намного дороже, чем оффлайн-разработка (как это происходит там, где я работаю), то это может сэкономить вам много времени в Интернете, имея хорошо понятный набор тестов для прохождения.
источник
Во встроенной разработке вы часто выполняете граничное сканирование, чтобы убедиться, что все приложение (включая оборудование) работает. Также см. JTAG для отладки системы.
Тестирование программных подпрограмм без привязки к оборудованию может быть выполнено с помощью стандартной среды модульного тестирования C, такой как Check . Но остерегайтесь ограничений памяти (особенно стекового пространства и т. Д. На небольших устройствах). Знай свои контракты! Вы также можете попытаться абстрагировать программные подпрограммы от аппаратного обеспечения, чтобы получить больший охват тестированием, но это обычно является дорогостоящим с точки зрения производительности на встроенных устройствах, таких как небольшие PIC или AVR. Тем не менее, вы можете макетировать аппаратные порты, чтобы добиться большего охвата (и, конечно, вы можете протестировать и этот макет).
Вы также можете попробовать использовать эмуляторы для микросхем или схемных симуляторов, но эти виды инструментов дороги (особенно в сочетании) и сложны.
источник