Вопрос

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

Проект

У меня есть несколько аппаратных средств, которые поставляются с интерфейсом ASCII через RS232.Я могу отдавать простые команды, получать простые ответы и управлять ими, как будто с их передней панели.Каждый из них имеет немного отличающийся синтаксис и очень разные наборы команд.Моя цель - создать абстракцию / интерфейс, чтобы я мог управлять ими всеми через графический интерфейс пользователя и / или удаленные вызовы процедур.

В чем проблема

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

Теперь, для модульных тестов, я не думаю, что мне действительно нужно реальное оборудование или последовательное соединение.Что я хотел бы сделать, так это передать моим коммуникаторам InputStream и OutputStream (или Reader и Writer), которые могли бы поступать из последовательного порта, файла, stdin / stdout, передаваться по каналу из тестовой функции, чего угодно.Итак, могу ли я просто попросить конструктор Communicator принять их в качестве входных данных?Если это так, было бы легко возложить ответственность за настройку всего этого на платформу тестирования, но на самом деле, кто устанавливает фактическое соединение?Отдельный конструктор?Функция, снова вызывающая конструктор?Отдельный класс, чья работа заключается в "подключении" Коммуникатора к правильным потокам ввода-вывода?

Редактировать

Я собирался переписать раздел "Проблема", чтобы получить ответы на вопрос, который, как мне казалось, я задавал, но, кажется, я понял это.Я (правильно?) определил две разные функциональные области.

1) Работа с последовательным портом

2) Связь с устройством (понимание его выходных данных и генерация команд)

Несколько месяцев назад я бы объединил все это в один класс.Моя первая идея отказаться от этого заключалась в том, чтобы передать только потоки ввода-вывода классу, который понимает устройство, и я не мог понять, кто тогда будет отвечать за создание потоков.

Проведя дополнительные исследования по инверсии контроля, я думаю, что у меня есть ан отвечай.Создайте отдельный интерфейс и класс, которые решают задачу № 1, и передайте их конструктору класса (ов?), которые решают задачу № 2.Таким образом, легко протестировать и то, и другое по отдельности.# 1 подключаясь к реальному оборудованию и позволяя тестовой платформе выполнять разные действия.# 2 можно протестировать, получив макет # 1.

Звучит ли это разумно?Нужно ли мне делиться дополнительной информацией?

Это было полезно?

Решение

С TDD вы должны позвольте вашему дизайну проявиться, начните с малого, с маленьких шажков и развивайте свои классы тест за тестом, понемногу.

ПРОЯСНЕННЫЙ:Начните с конкретного класса, чтобы отправить одну команду, модульно протестируйте ее с помощью макета или заглушки.Когда это будет работать достаточно (возможно, не со всеми опциями), протестируйте его на своем реальном устройстве один раз, чтобы подтвердить свой макет / заглушку / симулятор.

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

Другие советы

Извините за то , что я немного ориентирован на Linux ..

Мой любимый способ имитации гаджетов - это запись драйверов символьных устройств которые имитируют их поведение.Это также дает вам забавные возможности, такие как предоставление интерфейса ioctl (), который заставляет моделируемое устройство вести себя ненормально.

В этот момент ..от тестирования до реального мира имеет значение только то, какие устройства вы на самом деле открываете, читаете и записываете.

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

Увидев ваши правки, я думаю, что вы движетесь в совершенно правильном направлении.TDD, как правило, подталкивает вас к дизайну, состоящему из небольших классов с четко определенной ответственностью.Я бы также повторил совет тинкертима - симулятор устройства, которым вы можете управлять и "провоцировать" на разное поведение, бесценен для тестирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top