Разъемы для тестирования модулей

Приветствия Stackoverflowers,

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

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

Мне нужно написать unit test для этого класса. Я знаю, что модульные тесты должны иметь как можно меньше зависимостей. К сожалению, в этом случае зависимость - системный ресурс: сокет; и я не могу обойти его.

Мне нужно несколько советов о том, как пройти модульное тестирование этого класса.

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

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

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

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

Я думаю, что моя проблема в самом деле такова:

Если unit test выходит из строя... как узнать, если:

  • Сокет уже используется другим процессом;
  • unit test плохо написан; или
  • Метод ведет себя неправильно (это то, что стоит unit test).

Мне нужен unit test, чтобы проверить, только если метод ведет себя правильно или нет...

Ответ 1

Я написал аналогичный уровень абстракции, хотя и в C/С++, и мне приходилось тестировать код на основе сокетов. Я не знаю, есть ли что-то специфическое для PHP здесь, поэтому я просто предлагаю, какой общий совет я могу сделать.

  • Создайте серверный сокет в вашей настройке, закройте его в режиме срыва. В зависимости от того, поддерживаете ли вы многие клиенты, подключающиеся к сокету сервера, вы можете захотеть сделать эту часть в методе тестирования.
  • Предполагая, что вы можете указать порт для подключения к вашему коду клиента, подключите его к порту 0 (эфемерный порт), а затем используйте его в клиентском коде. Это устранит проблему привязки к уже используемому порту.
  • Установите таймауты в ваших сокетах. Если ваш тест не удается по какой-то неожиданной причине, вы не хотите, чтобы он висел в ожидании связи навсегда.
  • Вы должны иметь возможность чередовать поведение клиента/сервера. Например, вы захотите проверить, что произойдет, если сервер отключит свою сторону соединения на полпути через клиентское чтение/запись. Асинхронный ввод-вывод или многопоточность будут выполнять эту работу. Я не уверен, что у вас в вашем распоряжении в PHP.

Ответ 2

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

Например, вы можете написать один unit test, который сообщает экземпляру mock mock исключить исключение "port not available". В этом случае вы можете утверждать, что ваш метод поймал исключение и зарегистрировал его с тем же текстом, который был в исключении.

И еще более важным для этой проблемы вы можете написать unit test, который сообщает экземпляру mock mock вернуть действительный поток байтов из read(), а затем вы можете утверждать, что ваш метод делает правильные вещи (s ) с этими байтами.

Итак, вы на самом деле не проверяете сокет. Вы настраиваете сокет для имитации определенных событий, и вы проверяете, работает ли ваш код, который работает с сокетом, правильные вещи.

(Я использовал фальшивые фреймворки в Java, С#, Ruby и JavaScript. Я никогда не работал с PHP, но я готов поспорить, что для него есть некоторые из насмешливые фреймворки).

РЕДАКТИРОВАТЬ: Да, для PHP есть некоторые из насмешливые рамки. Я не могу рекомендовать его, но вот пара, которую я смог найти: PHPUnit и LastCraft