Как сделать TDD с оборудованием - PullRequest
12 голосов
/ 25 февраля 2009

Все проекты, над которыми я работаю, связаны с какой-либо аппаратной частью, и это часто является основной целью программного обеспечения. Существуют ли эффективные способы применения TDD к коду, который работает с оборудованием?

Обновление: Извините, что не уточнил мой вопрос.

Аппаратное обеспечение, которое я использую, представляет собой фрейм-граббер, который захватывает изображения с камеры. Затем я обрабатываю эти изображения, отображаю их и сохраняю на диск. Я могу смоделировать всю обработку, которая происходит после захвата изображений, с использованием ранее снятых изображений, которые хранятся на диске.

Но это фактическое взаимодействие с оборудованием, которое я хочу проверить. Например, правильно ли работает мое программное обеспечение, когда не подключена камера, правильно ли оно запускается и прекращает захват и т. Д. Но это так сильно связано с аппаратным обеспечением, что я не знаю, как это проверить, когда аппаратного обеспечения нет или если бы я даже пытался это сделать?

2-е обновление: Я также ищу конкретные примеры того, как именно люди справились с этой ситуацией.

Ответы [ 7 ]

7 голосов
/ 25 февраля 2009

Создайте тонкий слой для управления оборудованием и используйте системные тесты (ручные или автоматические) с полным оборудованием, чтобы убедиться, что уровень управления работает должным образом. Затем создайте ложную / фиктивную реализацию уровня управления, которая ведет себя внешне, как интерфейс с реальным оборудованием, и используйте ее при выполнении TDD для остальной части программы.


Несколько лет назад я писал программное обеспечение для проведения измерений на СКВИД-магнитометре. Аппаратные средства были большими, неподвижными и дорогими ( видео ), поэтому не было возможности всегда иметь доступ к оборудованию. У нас была документация о протоколе связи с устройствами (через последовательные порты), но документация не была на 100% точной.

Что нам очень помогло, так это создание программного обеспечения, которое прослушивает данные, поступающие с одного последовательного порта, регистрирует их и перенаправляет на другой последовательный порт. Затем мы смогли выяснить, как старая программа (которую мы заменяли) взаимодействовали с аппаратным обеспечением, и перепроектировать протокол. Они были связаны следующим образом: Старая программа <-> Виртуальный последовательный порт с обратной связью <-> Наш регистратор данных <-> Реальный последовательный порт <-> Оборудование.

Тогда мы не использовали TDD. Мы рассматривали возможность написания эмулятора для аппаратного обеспечения, чтобы мы могли тестировать программу изолированно, но поскольку мы не знали точно, как аппаратное обеспечение должно было работать, было сложно написать точный эмулятор, поэтому в итоге мы не сделали этого. сделай это. Если бы мы знали оборудование лучше, мы могли бы создать для него эмулятор, и это значительно упростило бы разработку программы. Тестирование на реальном оборудовании было самым ценным, и в ретроспективе нам следовало потратить еще больше времени на тестирование с аппаратным обеспечением.

4 голосов
/ 25 февраля 2009

Разделите ваш набор тестов на две части:

  1. Первая часть запускает тесты на реальном оборудовании. Эта часть используется для создания макетов. Написав автоматические тесты для этого, вы можете запустить их снова, если у вас есть какие-либо сомнения в правильности работы ваших макетов.

  2. Вторая часть работает против макетов. Эта часть запускается автоматически.

Часть # 1 запускается вручную после того, как вы удостоверились, что оборудование подключено правильно и т. Д. Хорошей идеей является создание набора тестов, которые выполняются для чего-то, возвращенного фабрикой, и запуск этих тестов дважды: один раз с фабрикой это возвращает настоящий «драйвер» и один раз против фабрики ваших ложных объектов. Таким образом, вы можете быть уверены, что ваши макеты работают точно так же, как настоящие:

class YourTests extends TestCase {
    public IDriver getDriver() { return new MockDriver (); }
    public boolean shouldRun () { return true; }
    public void testSomeMethod() throws Exception {
        if (!shouldRun()) return; // Allows to disable all tests
        assertEquals ("1", getDriver().someMethod());
    }
}

В моем коде я обычно использую системное свойство (-Dmanual = yes) для переключения ручных тестов:

class HardwareTests extends YourTests {
    public IDriver getDriver() { return new HardwareDriver (); }
    public boolean shouldRun () { return "yes".equals (System.getProperty("manual")); }
}
4 голосов
/ 25 февраля 2009

Если вы пишете программное обеспечение для манипулирования данными, поступающими из специализированного аппаратного обеспечения, то вы могли бы разумно создать резервные элементы для аппаратного обеспечения для тестирования программного обеспечения.

Если аппаратный интерфейс представляет собой нечто простое, например, последовательный порт, вы можете легко использовать кабель обратной связи, чтобы ваша программа взаимодействовала с имитируемым оборудованием. Я использовал этот подход несколько лет назад, когда писал программное обеспечение для общения с кредитным процессором. Моему тестовому приложению дали понять, что моим симулятором был модем и внутренний процессор.

Если вы пишете драйверы устройств PCI или программное обеспечение эквивалентного уровня, то, вероятно, вы не сможете создать программную замену.

Единственный хороший способ применить TDD к таким проблемам - это если вы можете подделать аппаратный ввод / вывод другой программой. Например, я работаю с кредитной картой для заправочных станций. В моем текущем проекте у нас есть симулятор, в котором электронная схема насоса подключена к некоторым переключателям, так что можно смоделировать работу насоса (рукоятка подъема, спусковой механизм, расход топлива). Вполне возможно, что мы могли бы создать симулятор, управляемый программным обеспечением.

С другой стороны, в зависимости от устройства, вы можете использовать стандартное испытательное оборудование (генераторы сигналов и т. Д.) Для подачи на него «известных входов».

Обратите внимание, что проблема заключается в том, что вы тестируете как аппаратное обеспечение, так и драйверы устройств вместе. К сожалению, это действительно единственный хороший выбор, который у вас есть на данном этапе - любое моделируемое оборудование, вероятно, будет достаточно отличаться от реального оборудования, которое будет бесполезно для тестирования.

2 голосов
/ 25 февраля 2009

Вероятно, не стоит включать тесты для доступа к оборудованию в ваш набор тестов. Одна из проблем этого подхода заключается в том, что тесты смогут выполняться только на машине, которая подключена к этому специальному оборудованию, что затрудняет запуск тестов, как часть (автоматического) процесса ночной сборки.

Одним из решений может быть написание некоторых программных модулей, которые ведут себя как отсутствующие аппаратные модули, по крайней мере, с точки зрения интерфейса. При запуске набора тестов используйте эти программные модули вместо реального оборудования.

Мне также нравится идея разбить набор тестов на две части:

  • тот, который обращается к реальному оборудованию, которое вы запускаете вручную
  • тот, который обращается к программным модулям, который запускается как часть автоматического тестирования

По моему опыту, тесты, в которых задействовано реальное аппаратное обеспечение, почти всегда требуют некоторого количества ручного взаимодействия (например, подключите что-то и выясните, правильно ли оно обнаружено), что затрудняет автоматизацию. Преимущества часто просто не стоят хлопот.

1 голос
/ 01 марта 2009

Когда я работал над приставками, у нас был инструмент, который генерировал макеты из любого C API с комментариями doxygen.

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

Таким образом, в приведенном выше примере вы установили бы результат FrameGrabber_API_IsDeviceAttached равным false, а когда ваш код вызывает эту функцию, он возвращает false и вы можете проверить его.

Насколько легко будет тестировать, зависит от того, как ваш код в настоящее время структурирован.

Инструмент, который мы использовали для создания насмешек, был в доме, поэтому я не могу помочь вам с этим. Но есть некоторые обнадеживающие хит Google: (отказ от ответственности - я использовал любой из них, но, надеюсь, они могут вам помочь)

Просто проверяю - есть ли у вас что-то вроде прямых вызовов ioctl в вашем коде или что-то в этом роде? Это всегда трудно издеваться. У нас был слой обертки ОС, для которого мы могли легко писать макеты, поэтому нам было довольно легко.

1 голос
/ 25 февраля 2009

Хитро умело.

0 голосов
/ 25 февраля 2009

Если у вас есть симулятор, вы можете написать тесты на симуляторе и запустить эти тесты на оборудовании.

Трудно ответить на вопросы с такой маленькой детализацией: -)

...