Я являюсь членом клуба робототехники моей средней школы и отвечаю за программирование робота. Одно предложение, которое я постоянно слышу от разных взрослых, заключается в том, что я должен писать модульные тесты, чтобы помочь подтвердить свой код. Кодовая база становится немного больше, и я согласен, что модульные тесты были бы очень полезны, чтобы помочь мне быстрее обнаруживать ошибки.
Тем не менее, я не совсем уверен, как я мог сделать это. Насколько мне известно, модульное тестирование выполняется путем взятия функции (или подсистемы кода) и подачи ей набора входных данных, чтобы убедиться, что он каждый раз выдает один и тот же результат. Код, который у меня есть в настоящее время, не выполняет каких-либо сложных операций с данными, а напрямую управляет аппаратными компонентами робота. Большая часть сложности заключается в том, чтобы убедиться, что электроника исправна, что код в данный момент соответствует фактическому оборудованию робота и т. Д. Часто я могу только видеть, есть ли проблема, загружая код в самого робота, и пытается запустить его.
Таким образом, как можно написать модульные тесты для кода, предназначенного для работы с любым механическим устройством? Мне кажется, что вы можете ловить ошибки, только наблюдая за работой машины.
Или я просто неправильно понимаю, как должны работать модульные тесты?
( Если это имеет значение, вот код , он написан на C ++, и я участвую в FRC )
источник
Я могу придумать пару вещей, которые вам нужно будет рассмотреть. Первый - сделать аппаратный слой доступа максимально тонким, даже если это означает создание базового слоя типа оболочки для него. Это дает вам пару преимуществ. Во-первых, это позволяет вам изолировать поведение вашего кода от аппаратного обеспечения от самого доступа к аппаратному обеспечению, что означает, что вы можете тестировать все до самого конца ваших аппаратных коммуникаций без необходимости доступа к самому оборудованию.
Например, если вам нужно разработать протокол сигнализации на основе I2C, вы можете проверить, что ваш код генерирует правильные сигналы I2C без необходимости подключать аппаратное обеспечение к вашим тестам.
Для обращений к реальному оборудованию вы можете проверить их правильное поведение, высмеивая ваш аппаратный уровень, и именно здесь поддержание очень тонкого аппаратного уровня действительно окупается, потому что вы можете уменьшить свой макет до необходимости обрабатывать только минимальные функции, необходимые для на самом деле относятся к аппаратному обеспечению, но вам не обязательно проверять отдельные сигналы, так как все ваши сигналы должны были быть проверены на более высоком уровне. Это означает, что вы используете свою макет для проверки того, что звонки выполняются на определенные аппаратные методы, которые заставляют ваши сигналы отправляться на аппаратные средства. Если вам нужно опросить ваше аппаратное обеспечение, тогда ваш макет должен иметь возможность инициировать события или методы только в вашем коде, потому что, опять же, ваша обратная сигнализация должна обрабатываться на более высоком уровне.
Это в основном соответствует тому, что Олекси сказал в своем ответе , в том смысле , что обычно надо больше надсматривать вещи на аппаратном уровне, однако это не так сложно, если вы придерживаетесь минимально возможного уровня минимального кода / вызова, который вы можете сделать для аппаратное обеспечение.
Когда у вас есть код, который проходит все его тесты, вам все равно нужно будет выполнить серию ручных тестов, чтобы убедиться, что вы все правильно подключили на своем аппаратном уровне.
Другая вещь, которая приходит на ум, кроме насмешек и наслоений, - это использование практики разработки в тестовом режиме. По сути, вы кодируете свои требования в качестве критериев тестирования и основываете свою реализацию на своих тестах. Это поможет вам свести код реализации к минимуму, а все ваши тестовые примеры будут направлять ваши усилия на разработку. Не тратя слишком много времени на другой потенциально некритический код, который вы можете испытать «просто потому, что», тестирование сначала поможет вам оставаться сосредоточенным и упростит изменение кода при отладке, как и использование. из ваших юнит-тестов и издевательств. Отладка программных ошибок с помощью аппаратного обеспечения общеизвестно сложна и отнимает много времени, которое вы бы лучше потратили на другие задачи.
источник
Я могу рассказать вам, как они делают это на Flight Simulator
Во-первых, вы получите половину ответа только в том случае, если зададите этот вопрос только программистам, поэтому вам, вероятно, стоит опубликовать этот вопрос на http://electronics.stackexchange.com, пока вы на нем.
Я не работал с роботами, но я потратил 5 лет, занимаясь аппаратными средствами на симуляторах полета, чтобы я мог рассказать вам, как работает их архитектура.
Аппаратный слой тупой
Он содержит базовый интерфейс, в котором вы можете настраивать простые значения ввода / вывода и устанавливать точки прерывания интерполяции для аналоговых сигналов. Когда вы работаете со «свежим» оборудованием, все будет работать как положено, практически без калибровки, но со временем детали будут подвергаться механическому износу и должны быть отрегулированы.
Калибровка представляет собой простую таблицу, которая содержит разбитые по размерам значения между минимальными и максимальными значениями. Для измерения входного сигнала обычно используется сервопривод (например, линейный потенциометр, преобразователь, акселерометр и т. Д.). Или в случае приборов, вы просто судите о точности визуально и настраиваете до калибровки.
Уровень программного обеспечения является противоположным
Все сложно и взаимосвязано, поэтому важно изолировать некоторые переменные для проверки функциональности. Не нужно думать о сценариях с головной болью, потому что намного проще запустить некоторые реалистичные сценарии, в которых вы можете собирать данные. Когда вы запускаете тесты, вы в основном измеряете сохраненные данные по отношению к текущему выводу.
На имитаторе полета это называется QTG (Руководство по квалификационным испытаниям). По своей сути он выводит данные на двумерную сетку, где одно измерение является временем, а другое - выходным.
Хотите верьте, хотите нет, но это суть того, как они разрабатывают модели. Настоящий самолет оснащен кучей датчиков и управляется по управляемым сценариям. Поскольку все элементы управления могут управляться без участия человека, тесты запускаются (то есть, сим летит сам) компьютером и сравниваются данные.
Хотя робототехника создается в очень разных масштабах, принципы одинаковы. Традиционный подход состоит в том, чтобы полностью разделить аппаратные и программные уровни, чтобы оба можно было протестировать по отдельности. Аппаратный ввод собирается через сервоприводы и устанавливается через независимый интерфейс. Входной сигнал программного обеспечения может быть установлен / считан путем независимого измерения и сравнения сигналов, которые в противном случае поступали бы на аппаратные средства, и построения их графика с известными «хорошими» данными.
Сами тесты не обязательно должны быть сложными, если результаты предсказуемы, измеримы и воспроизводимы.
источник
Как уже было сказано, макет и заглушить детали оборудования. Например, если у вас есть интерфейс к роботу, вы можете наследовать от этого интерфейса, а затем сделать его простые реализации-заглушки. Затем вы можете проверить, что реализация заглушки была вызвана, как и ожидалось. Если это ожидаемые функции или ожидаемые параметры.
источник