Как выполнить модульное тестирование почтового клиента

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

У кого-нибудь есть идеи о том, как протестировать такого рода приложение, где оно опирается на внешние факторы при разработке?

РЕДАКТИРОВАТЬ:

Чтобы добавить некоторые детали: я работаю над библиотекой почтового клиента C++ более высокого уровня для моего приложения, которая использует libEtPan, библиотеку C, чтобы фактически обрабатывать детали подключения к почтовому серверу и взаимодействия с ним.

5 ответов

Решение

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

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

Я бы попытался написать это так, чтобы он мог работать, по крайней мере, следующими двумя способами: во-первых, он подключается к локальному серверу электронной почты, который вы можете настроить и настроить по своему усмотрению. В Java я использую Dumpster, но я уверен, что подобное существует для C++. Вторым было бы подключиться по крайней мере к одному локальному почтовому серверу, который вы можете написать. Тот, который вы можете разбрызгивать сколько угодно (так, чтобы он не был реальным или не использовался совместно разработчиками) и запускать тот же набор тестов против этого. Причина в том, что разработчики SMTP-серверов ненавидят всех, и вы захотите проверить, что ваша заглушка работает так же, как реальная вещь. Это я считаю эквивалентом одной базы данных на разработчика.

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

1) Может быть, вы могли бы сделать это как раз во время цикла CI, поэтому затем поделитесь одним набором серверов электронной почты между всеми разработчиками, и локальный прогон просто использует C++ Dumpster.

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

Чтобы сделать это эффективно, вам нужен интерфейс для общения с вашим почтовым сервером. Для тестирования реализация является макетом объекта. Для развертывания вы заменяете это реализацией, которая взаимодействует напрямую с почтовым сервером.

Посмотрите этот ТАК вопрос для C++ Mocking Frameworks.

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

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

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

Андрей прав насчет насмешки над почтовым API. Ваша проблема с этим, находящимся в C, может быть решена одним из двух способов.

  • предоставить простую оболочку C++, которая может быть подделана
  • Используйте компоновщик для предоставления вашей тестовой / макетной версии C api, вы должны использовать те же заголовочные файлы, что и в библиотеке, но ваши модульные тесты связываются с вашими фиктивными функциями C вместо библиотеки.

Существует замечательная книга, в которой рассказывается, как проводить модульное тестирование в сложных ситуациях: "Эффективная работа с устаревшим кодом", я не могу рекомендовать эту книгу достаточно высоко. Не стоит откладывать на заголовок, книга рассматривает унаследованный код как любой код без юнит-тестов.

Другие вопросы по тегам