Как стать автором
Обновить

Комментарии 12

Кода бы побольше в статью. Простыня текста и два примера случаев с кодом. Статья же не о раннем творчестве Маяковского.

В данной части в основном понятия достаточно концептуальные, но да, конкретных примеров можно добавить больше, обязательно учту в следующих частях, спасибо!

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

В начале много теста посвящено "сложности" которая очень плохо влияет на проект. Ну так чуда нет. Правильная декомпозиция, четко прописанные "контракты" с этим борются. Не тесты. Тесты уже сугубо вторичны, так как они не меняют архитектуру :)

Теперь

4 свойства

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

  • Сопротивляемость рефакторингу. Тесты не должны мешать (увеличивать время) основному методу упрощения ПО, а именно рефакторингу. Рефакторинг для тестов (как и для обычного пользователя) должен быть незаметным.

  • Поддерживаемость. Тесты не должны требовать больших ресурсов на своё написание и изменение, ведь в противном случае вся работа в направлении оптимизации труда потеряет смысл, так как проще будет не писать такие тесты вовсе.

  • Быстродействие. Если проверка требует много времени для выполнения, то она будет запускаться редко. Чем реже запуск, тем выше вероятность появления дефекта и, как следствие, тем сложнее его отыскать. В каких-то случаях запуски будут игнорироваться вовсе, сводя все усилия на нет. Это также оказывает негативное влияние на динамику и скорость рефакторинга.

Полезные свойства. Смотрим по одному.

Регресс: нет никакого страха, если вы четко прописали контракт сервиса и его и тестируете в точке публикации API. Все просто. Понятно относительно просто, но тем не менее

Сопротивляемость рефакторингу: чуда нет, если делаем рефакторинг, а значит меняет структуру API и его контракты - тесты надо переписывать.

Поддерживаемость: ну тут все просто. Следуйте за структурой ПО и будете одновременно счастливы (или нет) с разработчиком

Быстродействие: это чисто вопрос автоматизации. Можем - делаем

----------------

Теперь внешние эффекты. Ну да, но опять же. Если сервисы спроектированы корректно - их влияние минимально и часто описано в том же "контракте".

Есть зависимость на источники данных. Ну то же как бы понятно. Всегда есть ГРАНИЦА между вами и внешним миром (зонами ответственности других). Мокать точки соприкосновения человечество научилось давно. Классика: фронт получить спеку и примеры - идет "пилить" свою часть на статике без живого бэкенда. Потом сводят вместе. Как часто - зависит от подхода. Тоже самое на внешние системы. В большом enterprise вы всегда будете иметь кучу связанных с вашим решением систем, которые не ваши, которые непонятно когда доступны, нет нужных тестовых данных и т.д. И это нормально. Еще до тестов с этом проблемой столкнуться разрабы и успешно ее победят

Я так и не понял, черезз все эти витееватые рассуждения и новые термины - с чем в итоге боремся?

Боремся с растущей сложностью в программе с помощью организации подходящего метода тестирования. Что не менее важно отмечаем роль архитектуры в данном процессе.

Правильная декомпозиция, четко прописанные "контракты" с этим борются.

Какая декомпозиция правильная, а какая нет? Что такое контракт? Возможно тест и есть один из инструментов описания контакта? Вы идете в правильном направлении, но моя задача не заключается в том чтобы поверхностно перечислить как догмы всем знакомые понятия в одной статье, а наоборот, объяснить понятным, где то строгим и для кого то занудным языком те концепции, с которыми многие инженеры работают на бессознательном уровне, на уровне "все так делают и я буду"

если делаем рефакторинг, а значит меняет структуру API и его контракты

Рефакторинг это далеко не всегда изменение внешних контрактов, следовательно одно из другого обязательно не следует.

Поддерживаемость: ну тут все просто.

К сожалению нет :)

Быстродействие: это чисто вопрос автоматизации.

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

Теперь внешние эффекты. Ну да, но опять же. Если сервисы спроектированы корректно - их влияние минимально

Их влияние не может быть минимальным или максимальным, оно должно быть ровно таким каким это требуется аналитикой.

В вашем выводе подчеркивается очевидность далеко не очевидных и комплексных понятий. Я вам это обязательно докажу в следующих частях серии статей. Спасибо за комментарий!

Боремся с растущей сложностью в программе с помощью организации подходящего метода тестирования. Что не менее важно отмечаем роль архитектуры в данном процессе.

Будет интересно посмотреть, как вы с помощью тестирования сможете побороть "сложность в программе" :) Программа то не изменится :)

Очень тяжело менятьб ничего не меняя, но мы будем. Жванецкий (с)

Какая декомпозиция правильная, а какая нет? Что такое контракт?

Ну, я как архитетор могу рассказать подробнее :) Контракт - описание сервиса:

  • где он есть (точка деплоя)

  • как к нему получить доступ (авторизация)

  • что передать на вход

  • что можно получить на выходе

  • что он "полезного" делает

  • ...

Возможно тест и есть один из инструментов описания контакта?

Нет, именно в силу первичногости проектирования ПО. На момент когда QA еще может не быть, это описание уже может быть :) Т.е. тут даже нет парадокса "яйца и курицы"

Рефакторинг это далеко не всегда изменение внешних контрактов, следовательно одно из другого обязательно не следует.

Тогда вообще нет проблем. Локальное изменение и жизнь прекрасна :)

----------------

Мне кажется, вы пытаетесь, меняя что-то с помощью тестирования, поставить "телегу впереди лошади". Ну при всем желании :) Но будет интересно посмотреть дальше :)

Ответы на ваши замечания потребуют выложить все остальные части серии прямо тут в комментариях :)

Прошу набраться терпения и дождаться оставшийся материал, надеюсь по итогу от недопонимания не останется и следа, спасибо что комментируете!

Не могу проголосовать кармой, так что поблагодарю комментарием. Хорошая формализация, в целом со всем согласен, интересно узнать, что дальше

Зачем что-то выдумывать? В Data-driven все тесты примитивны их даже можно автоматически генерировать, логика уже отделена, и есть верификации с транкзациями.

Хорошее начало! Кликбейтное =)
Надеюсь, что мы пытаемся рассказать не об одном и том же.
Хотя если подумать, то я даже буду рад, если кто-то ещё пришел к таким же выводам. Будет о чем поговорить =)

Позвольте несколько замечаний:

  1. То, что Вы назвали "Зависимость от интерфейса", имеет устоявшееся в "науке" наименование "inversion of control". Для солидности неплохо было бы привести ссылку на статью об этом паттерне.

  2. Компоненты, которые Вы назвали "Humble object" можно и даже нужно тестировать. Представьте, что у вас в репозитории написан гигантский SQL запрос с join и подзапросами. Для тестирования таких объектов существуют специальные библиотеки. В Java это testcontainers и mockserver. Наверняка что-то существует и для Вашей платформы (это вроде бы Nodejs)

  3. Было бы неплохо хотя бы одно предложение насчёт языка программирования: какой язык используется в примерах и валидно ли всё, что Вы написали выше, для других языков тоже.

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

Благодарю за замечания!

Отвечу по пунктам:

  1. Инверсия зависимостей будет представлена в следующей части

  2. Стоит понимать что речь идёт не только о сервер приложениях, но и о клиентской части где источники данных это чаще всего обычные вызовы API. По поводу того что делать со сложной SQL логикой, то конечно ее нужно тестировать, тут вы правы, но в таком случае она и не попадет в не тестируемый слой уже по определению, т. е. не будет частью источников данных в данной терминологии.

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

  4. Так точно :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий