В книге Growing Object-Oriented Software, Guided by Tests, мы описали различные виды тестов, которые мы используем при проектировании ПО и показали, как хорошо они сочетаются с архитектурным стилем Порты и Адаптеры (Ports and Adapters by Alistair Cockburn).
В Портах и Адапттерах центральное место приложения занимает доменная модель, не имеющая точек соприкосновения ни с какими частями инфраструктуры, будь то БД, очереди, UI, и т.д. Но модель содержит интерфейсы, которые определяют ее взаимоотношения с внешним миром в терминах домена. Cockburn называет эти интерфейсы портами. Эти интерфейсы реализуются в соответствующих объектах, осуществляющих взаимодействие с внешним миром — Cockburn назвал их адаптерами. В распределенных системах разные процессы, каждый со своей доменной моделью, взаимодействюут между собой с помощью портов и адаптеров.
На диаграмме выше, большой круг — это процесс, маленькие(внутри него) — объекты. Домен располагается в центре процесса. Инфраструктурные модули(на рисунке это подписанные сектора), через которые процесс взаимодействует с внешним миром, облепляют доменный "круг". Модули-адаптеры, отображающие концепции домена на технические реализации находятся между ними.
Ниже я попытаюсь объяснить, как различные уровни тестирования вписываются в Порты и Адаптеры.
Модульные тесты
Модульные тесты тестируют отдельные объекты, или их небольшие группы внутри одного процесса. Например, при Test-Driven Development, мы пишем модульные тесты, результаты выполнения которых влияют на тестируемый код — мы редактируем его, когда он не проходит какие-то тест кейсы.
Интеграционные тесты
Термин "интеграционные тесты" может применяться ко многим видам тестирования. В нашей книге мы использовали его, чтобы обозначить тесты для какой-то абстаркции из нашего кода, которая реализуется с помощью сторонних пакетов. Здесь мы хотим затестить, что наша реализация абстракции корректно интегрируется со сторонним кодом: убедиться что мы не сделали неверных предположений о том, как она работает и просто не спотыкается о какие-то неучтенные нами ошибки. Однако, мы не можем взять и прямо исправить найденные этими тестами ошибки, т.к доступа к тестируемому(стороннему) коду у нас нет.
Приемочные тесты
Приемочные тесты — это тесты, ориентированные на пользователя, они тестируют доменную логику всей сестемы, и демонстрируют, что она действительно работает так, как ожидается.
Порты и Адаптеры позволяют запускать приемочные тесты прямо для доменного слоя, т.к он полностью изолирован от технической инфраструктуры и реального мира. Приемочные тесты могут взаимодействовать с моделью через интерфейсы портов. Такие тесты будут чертовски быстрыми. Также их легко изолировать друг от друга, т.к они не сохраняют состояние модели(в базы или очереди, к примеру).
Приемочные тесты для распределенной системы могут инициализировать домены разных процессов в общей памяти и ссылаться друг на друга с помощью реализаций интерфейсов их портов, что позволит каждому конкретному тесту не выходить за границы своего процесса.
Системные тесты
Системные тесты, тестируют систему целиком, управляя ей, через открытые порты. Они также тестируют сборку, развертывание и загрузку системы. Написание системных тестов на ранних этапах разработки, гарантирует что система всегда будет готова для деплоя по мере своего развития.
Однако такие тесты дико тормозные + реальные условия, в которых они запускаются (параллелизм, асинхронность, необходимость сохранения данных) здорово усложняют написание читабельных тестов, изолированных друг от друга.
nizkopal
Чет я ничего не понял… :)
Сумбурная статья, ни «здрасте», ни «досвиданья».
Если бы не знал описанных в статье понятий заранее, из статьи точно бы не узнал и не разобрался бы. Зачем все это? о_О
arturpanteleev Автор
Да, сейчас сам перечитываю, понимаю, что так, похоже, и есть.
Когда изначально наткнутся на эту статью мне понравились как разные виды тестов были проиллюстрированы + описание того как они соотносятся с понятиями гексогональной архитектуры.
Лучше будет скрыть этот перевод, а на его основе уже написать свою статью, с более подробным разбором каждого уровня и примерами кода.