Привет!
Опубликовал первый пост про тестирование TA с общими идеями и принципами (но уже здесь с иллюстрациями реальным кодом из TA).
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
Опубликовал первый пост про тестирование TA с общими идеями и принципами (но уже здесь с иллюстрациями реальным кодом из TA).
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
👍2
Привет!
Опубликовал второй кусочек описания тестирования Trainer Advisor - сетап system under test.
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
Опубликовал второй кусочек описания тестирования Trainer Advisor - сетап system under test.
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
🔥7❤1
И опубликовал очередной кусочек описания тестирования Trainer Advisor - формирование фикстурных объектов и их вставка в БД.
Там из 34К знаков 14К - код, почти половина:).
P.s. сбросьте кэш браузера, чтобы подтянуть css с выделеним строк в некоторых из сниппетов
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
Там из 34К знаков 14К - код, почти половина:).
P.s. сбросьте кэш браузера, чтобы подтянуть css с выделеним строк в некоторых из сниппетов
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
👍3
Привет!
Второй или третий раз смотрю де-факто один и тот же доклад про ТДД и не устаю его рекомендовать - в этот раз по мотивам доклада у меня снова родилась пачка мыслей.
Мысль №1
В докладе мужик привёл пару определений:
> Падение юнит-теста подразумевает сбой ровно в одном юните (методе, классе, модуле, пакете)
> Падение девелоперского теста подразумевает ошибку в последнем изменении кода
И мысль ещё из Бековской TDD by Example - кол-во кода, которое вы пишите между запусками тестов зависит от вашей уверенности в умении писать такой код.
И аналогия с вождением машины - чем увереннее вы себя чувствуете, тем быстрее вы едете.
И это прям хорошо легло на мой свежий опыт:
1. В Trainer Advisor у меня примерно 3-4 теста на HTTP-эндпоинт. И ~95% - работают либо через хттп, либо через конторллер
2. А недавно я написал один хттп эндпоинт, с 22 тестами из которых <50% работают через http.
В чём разница? В TA львиная доля эндпоинтов - примитивный КРУД - перегнать ДТО в сущность, сохранить сущность; вычитать ДТО из БД, вернуть - я это пишу спинным мозгом и там граничных случаев ноль целых хрен десятых.
А в методе из п.2 был не совсем тривиальный алгоритм с пачкой граничных условий и я не был уверен, что сходу напишу всё правильно.
В этом и разница.
—
Мысль №2
Что переход на более низкий уровень абстракции, что использование мока - снижают устойчивость тестов к рефакторингу и, как следствие, увеличивают стоимость разработки (читай: вашу нервотрёпку). Но, при этом снижают стоимость разработки самих тестов. И надо стараться искать оптимальное соотношение разных типов тестов, которое обеспечит минимальную стоимость разработки (читай: вашей нервотрёпки). Пока могу предложить это только в качестве лозунга - как конкретно искать этот баланс я не знаю.
—
Мысль №3
Возможно молодые подписчики ещё не сталкивались с http://wiki.c2.com/. Это самая первая вики в мире из 1995 года. От чувака, который придумал гексагональную архитектуру. И в которой в старые добрые времена тусила вся старая гвардия - начиная с самого Кокберна и продолжая анкл Бобом, Фаулером, Беком, Коплейном. Можно выделить вечерок и пошататься по ней впитывая мудрость древних.
—
Мысль №4
Чёт то ли я туплю, то ли у мужика не стыковка - он сначала пинает тесты с моками, за то что они мешают рефакторингу. А в конце доклада предлагает писать тесты на код интеграций с моками. Чтобы их потом не рефакторить?
—
Мысль №5
Мужик топит, за то, что код с вводом-выводом надо тестировать как-то по другому, потому что он медленный и хрупкий. И, видимо, раз я решил проблемы скорости и хрупкости такого кода, то мне можно и для него писать нормальные тесты. Можно же?
—
Мысль №6
У мужика в докладе ни строчки кода нет. А у меня есть ~150 "developer tests", которые "tests behaviour, not functions" и для которых процентов на 30 готово описание идей и техник как, такие тесты писать
#talks@ergonomic_code #ergo_testing@ergonomic_code #tdd@ergonomic_code #whynomocks@ergonomic_code
Второй или третий раз смотрю де-факто один и тот же доклад про ТДД и не устаю его рекомендовать - в этот раз по мотивам доклада у меня снова родилась пачка мыслей.
Мысль №1
В докладе мужик привёл пару определений:
> Падение юнит-теста подразумевает сбой ровно в одном юните (методе, классе, модуле, пакете)
> Падение девелоперского теста подразумевает ошибку в последнем изменении кода
И мысль ещё из Бековской TDD by Example - кол-во кода, которое вы пишите между запусками тестов зависит от вашей уверенности в умении писать такой код.
И аналогия с вождением машины - чем увереннее вы себя чувствуете, тем быстрее вы едете.
И это прям хорошо легло на мой свежий опыт:
1. В Trainer Advisor у меня примерно 3-4 теста на HTTP-эндпоинт. И ~95% - работают либо через хттп, либо через конторллер
2. А недавно я написал один хттп эндпоинт, с 22 тестами из которых <50% работают через http.
В чём разница? В TA львиная доля эндпоинтов - примитивный КРУД - перегнать ДТО в сущность, сохранить сущность; вычитать ДТО из БД, вернуть - я это пишу спинным мозгом и там граничных случаев ноль целых хрен десятых.
А в методе из п.2 был не совсем тривиальный алгоритм с пачкой граничных условий и я не был уверен, что сходу напишу всё правильно.
В этом и разница.
—
Мысль №2
Что переход на более низкий уровень абстракции, что использование мока - снижают устойчивость тестов к рефакторингу и, как следствие, увеличивают стоимость разработки (читай: вашу нервотрёпку). Но, при этом снижают стоимость разработки самих тестов. И надо стараться искать оптимальное соотношение разных типов тестов, которое обеспечит минимальную стоимость разработки (читай: вашей нервотрёпки). Пока могу предложить это только в качестве лозунга - как конкретно искать этот баланс я не знаю.
—
Мысль №3
Возможно молодые подписчики ещё не сталкивались с http://wiki.c2.com/. Это самая первая вики в мире из 1995 года. От чувака, который придумал гексагональную архитектуру. И в которой в старые добрые времена тусила вся старая гвардия - начиная с самого Кокберна и продолжая анкл Бобом, Фаулером, Беком, Коплейном. Можно выделить вечерок и пошататься по ней впитывая мудрость древних.
—
Мысль №4
Чёт то ли я туплю, то ли у мужика не стыковка - он сначала пинает тесты с моками, за то что они мешают рефакторингу. А в конце доклада предлагает писать тесты на код интеграций с моками. Чтобы их потом не рефакторить?
—
Мысль №5
Мужик топит, за то, что код с вводом-выводом надо тестировать как-то по другому, потому что он медленный и хрупкий. И, видимо, раз я решил проблемы скорости и хрупкости такого кода, то мне можно и для него писать нормальные тесты. Можно же?
—
Мысль №6
У мужика в докладе ни строчки кода нет. А у меня есть ~150 "developer tests", которые "tests behaviour, not functions" и для которых процентов на 30 готово описание идей и техник как, такие тесты писать
#talks@ergonomic_code #ergo_testing@ergonomic_code #tdd@ergonomic_code #whynomocks@ergonomic_code
YouTube
TDD Revisited - Ian Cooper - NDC Porto 2023
This talk was recorded at NDC Porto in Porto, Portugal. #ndcporto #ndcconferences #testing #tdd #softwaredeveloper
Attend the next NDC conference near you:
https://ndcconferences.com
https://ndcporto.com/
Subscribe to our YouTube channel and learn…
Attend the next NDC conference near you:
https://ndcconferences.com
https://ndcporto.com/
Subscribe to our YouTube channel and learn…
👍5❤1
Привет!
Опубликовал пост с последним кусочком описания сетапа фикстуры Trainer Advisor - сетап тестовых дублей.
В этом посте для полноты картины я добавил бонус-трек с описанием сетапа тестовых дублей для тестирования работы с внешними веб-сервисами, кроликом, кафкой и MQTT-брокером.
И под это дело добавил соответствующий бонус-трек в пост с описанием запуска инфраструктуры.
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code #whynomocks@ergonomic_code
Опубликовал пост с последним кусочком описания сетапа фикстуры Trainer Advisor - сетап тестовых дублей.
В этом посте для полноты картины я добавил бонус-трек с описанием сетапа тестовых дублей для тестирования работы с внешними веб-сервисами, кроликом, кафкой и MQTT-брокером.
И под это дело добавил соответствующий бонус-трек в пост с описанием запуска инфраструктуры.
#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code #whynomocks@ergonomic_code
❤5👍2
Привет!
Я в Project Mariotte сделал страшное - перешёл на MockMvc.
Изначальная мотивация была в том, чтобы сэкономить секунду на запуске Tomcat.
Потом выяснилось, что инициализация RestAssured занимает ещё секунду, которую тоже можно сэкономить
Но последним аргументом стало то, что со WebTestClient можно переехать на работу через HTTP затри четыре простых шага.
И это навело меня на мысли об эволюции ЭП от сложного к простому за последние 4 года.
В конце 19-ого - начале 20-ого года можно было сказать, что ЭП = модульный монолит + тесты без моков + ДДД + чистая архитектура + railway-oriented programming на монадах.
И на тот момент, это всё (на мой взгляд) были маргинальные идеи, не имеющие широкого распространения.
Но за прошедшие 4 года, они все если не вошли, то сильно приблизились к мейнстриму, на мой взгляд.
А я с ЭП за эти же 4 года то ли ушёл вперёд, то ли откатился назад:
1. К модульному монолиту добавились цитадели, а для самого монолита появилось ограничение, что типовой тест должен отрабатывать не больше чем за 30 секунд
2. В тестировании добавилось разрешение на использование моков для симуляции ошибок инфраструктуры и для дорогой инфраструктуры. И свеженькое разрешение на использование MockMvc, при условии, что код самих клиентв (тест-кейсов) на него не завязан.
3. От ДДД осталась только декомпозиция модели на агрегаты, но по более приземлённой технологии на базе жизненного цикла сущностей и транзакционного анализа; а вместо ограниченных контекстов - декомпозиция на базе эффектов;
4. Чистую архитектуру я заменил на тщательное проектирование интерфейсов;
5. ROP на монадах, наконец, я заменил на Guard clause.
И при этом Эргономичный подход остаётся совместимым со всеми этими идеями там, где это надо:
1. Цитадель оказалась плохой затеей? Затолкать её обратно в монолит - вообще не проблема;
2. Тестов на моках стало слишком много или появилось слишком много багов в обработке ошибок? Поменять моки на стабы - уже сложнее, но тоже вполне решаемая задача;
3. В проекте появилась сложная предметная область и/или эксперт по ней? Перейти на ограниченные контексты и агрегаты на базе инвариантов - без проблем, вся инфраструктура и структура кодовой базы готовы;
4. В проекте появилась необходимость менять инфраструктуру без пересборки/перезапуска? Вытащить интерфейс из существующего класса - дело 5 минут. С реализацией сложнее, но это другой вопрос;
5. В проекте появилась потребность на лету собирать пайплайны? Обернуть имеющиеся вызовы эффективных методов в монады не составит труда.
А прямо сейчас, в моменте, ваш код будет максимально простым, без лишних сложностей и архитектуры.
Изначально Эргономичный подход был глотком свежего воздуха для тех, кто устал от хаоса и багов императивной слоёнки с тестами на моках.
Теперь Эргономичный подход стал глотком свежего воздуха для тех, кто устал от поисков стороны, с которой подойти к ДДД, церемоний чистой архитектуры и сложностей объяснения монад простым смертным.
В общем, покой нам только снится:)
#ergo_approach@ergonomic_code #project_mariotte@ergonomic_code #tdd@ergonomic_code #ergo_testing@ergonomic_code #mocks@ergonomic_code #clean_architecture@ergonomic_code #functional_architecture@ergonomic_code #ddd@ergonomic_code #rop@ergonomic_code
Я в Project Mariotte сделал страшное - перешёл на MockMvc.
Изначальная мотивация была в том, чтобы сэкономить секунду на запуске Tomcat.
Потом выяснилось, что инициализация RestAssured занимает ещё секунду, которую тоже можно сэкономить
Но последним аргументом стало то, что со WebTestClient можно переехать на работу через HTTP за
И это навело меня на мысли об эволюции ЭП от сложного к простому за последние 4 года.
В конце 19-ого - начале 20-ого года можно было сказать, что ЭП = модульный монолит + тесты без моков + ДДД + чистая архитектура + railway-oriented programming на монадах.
И на тот момент, это всё (на мой взгляд) были маргинальные идеи, не имеющие широкого распространения.
Но за прошедшие 4 года, они все если не вошли, то сильно приблизились к мейнстриму, на мой взгляд.
А я с ЭП за эти же 4 года то ли ушёл вперёд, то ли откатился назад:
1. К модульному монолиту добавились цитадели, а для самого монолита появилось ограничение, что типовой тест должен отрабатывать не больше чем за 30 секунд
2. В тестировании добавилось разрешение на использование моков для симуляции ошибок инфраструктуры и для дорогой инфраструктуры. И свеженькое разрешение на использование MockMvc, при условии, что код самих клиентв (тест-кейсов) на него не завязан.
3. От ДДД осталась только декомпозиция модели на агрегаты, но по более приземлённой технологии на базе жизненного цикла сущностей и транзакционного анализа; а вместо ограниченных контекстов - декомпозиция на базе эффектов;
4. Чистую архитектуру я заменил на тщательное проектирование интерфейсов;
5. ROP на монадах, наконец, я заменил на Guard clause.
И при этом Эргономичный подход остаётся совместимым со всеми этими идеями там, где это надо:
1. Цитадель оказалась плохой затеей? Затолкать её обратно в монолит - вообще не проблема;
2. Тестов на моках стало слишком много или появилось слишком много багов в обработке ошибок? Поменять моки на стабы - уже сложнее, но тоже вполне решаемая задача;
3. В проекте появилась сложная предметная область и/или эксперт по ней? Перейти на ограниченные контексты и агрегаты на базе инвариантов - без проблем, вся инфраструктура и структура кодовой базы готовы;
4. В проекте появилась необходимость менять инфраструктуру без пересборки/перезапуска? Вытащить интерфейс из существующего класса - дело 5 минут. С реализацией сложнее, но это другой вопрос;
5. В проекте появилась потребность на лету собирать пайплайны? Обернуть имеющиеся вызовы эффективных методов в монады не составит труда.
А прямо сейчас, в моменте, ваш код будет максимально простым, без лишних сложностей и архитектуры.
Изначально Эргономичный подход был глотком свежего воздуха для тех, кто устал от хаоса и багов императивной слоёнки с тестами на моках.
Теперь Эргономичный подход стал глотком свежего воздуха для тех, кто устал от поисков стороны, с которой подойти к ДДД, церемоний чистой архитектуры и сложностей объяснения монад простым смертным.
В общем, покой нам только снится:)
#ergo_approach@ergonomic_code #project_mariotte@ergonomic_code #tdd@ergonomic_code #ergo_testing@ergonomic_code #mocks@ergonomic_code #clean_architecture@ergonomic_code #functional_architecture@ergonomic_code #ddd@ergonomic_code #rop@ergonomic_code
GitHub
GitHub - ergonomic-code/Project-Mariotte: Демонстрационный проект Эргономичного подхода - сервис бронирования номеров в отелях
Демонстрационный проект Эргономичного подхода - сервис бронирования номеров в отелях - ergonomic-code/Project-Mariotte
👌2
Эргономичный код
Привет! Я в Project Mariotte сделал страшное - перешёл на MockMvc. Изначальная мотивация была в том, чтобы сэкономить секунду на запуске Tomcat. Потом выяснилось, что инициализация RestAssured занимает ещё секунду, которую тоже можно сэкономить Но последним…
После Project Mariotte я перенёс подход с MockMVC на другой (закрытый) проект и словил там проблему - по дефолту настройки секьюрити не подтянутся.
Для того чтобы их прикрутить надо:
1. Не забыть добавить зависимость
2. Донастроить webTestClient:
Возможно там где-то дальше ещё какие-то грабли есть, но меня утешает мысль, что вернуться к тестам через HTTP можно будет лёгким движением руки
#ergo_testing@ergonomic_code #tdd@ergonomic_code #mockmvc@ergonomic_code #springsecurity@ergonomic_code #webtestclient@ergonomic_code
Для того чтобы их прикрутить надо:
1. Не забыть добавить зависимость
testImplementation("org.springframework.security:spring-security-test")2. Донастроить webTestClient:
client = MockMvcWebTestClient
.bindToApplicationContext(applicationContext)
.apply(springSecurity(FilterChainProxy(securityFilterChain)))
.configureClient()
.defaultHeader("Content-Type", "application/json")
.build()
Возможно там где-то дальше ещё какие-то грабли есть, но меня утешает мысль, что вернуться к тестам через HTTP можно будет лёгким движением руки
#ergo_testing@ergonomic_code #tdd@ergonomic_code #mockmvc@ergonomic_code #springsecurity@ergonomic_code #webtestclient@ergonomic_code
👍4
Привет!
Сроки по Проекту Р уже полыхают синим пламенем но я, тем не менее, повыкраивал по чуть-чуть времени на микропост с описанием того, как я добился сетапа свежей БД на 300+ таблиц за 1.5 секунды.
#ergo_testing@ergonomic_code #tdd@ergonomic_code #integration_tests@ergonomic_code #project_r@ergonomic_code
Сроки по Проекту Р уже полыхают синим пламенем но я, тем не менее, повыкраивал по чуть-чуть времени на микропост с описанием того, как я добился сетапа свежей БД на 300+ таблиц за 1.5 секунды.
#ergo_testing@ergonomic_code #tdd@ergonomic_code #integration_tests@ergonomic_code #project_r@ergonomic_code
👍5
Привет!
Говорят, чёрный пиар - это тоже пиар, поэтому надеюсь пацаны из Spring АйО (Саша, привет! 👋 ) не сильно обидятся, что я их пост разнесу чутка:)
Пример теста в посте имеет две проблемы
Проблема первая - непонятно, что тестирует этот тест
Вообще, вроде как, он должен тестировать клиента внешней системы. Но фактически, он тестирует не клиента внешней системы, а просто фиксирует вызовы Spring-овго АПИ (читай: детали реализации).
И если внешняя система поменяет формат ответа на json - код сломается, а тест продолжит проходить.
А если я перепишу клиента на restTemplate (и проверю руками) - код будет работать, а тест сломается.
Проблема вторая - он нарушает хрестоматийное правило тестов с моками
Мокайте только собственные типы (см. Growing Object-Oriented Software, Guided by Tests, Chapter 8)
—
Как это надо было делать
Вариант №1: идеальный
Поднять в тестконтейнере latest-версию внешней системы и написать тест, который бы работал с ней.
Такой тест:
1. ни как бы не был завязан на реализацию - вы с внешней системой могли бы хоть на protobuf перейти и в самом тесте вообще ничего менять бы не пришлось
1.1. Как следствие он бы подстраховал вас и если бы вы решили поменять либу для работы с хттп (на тот же RestTemplate, например)
2. поймает ошибки обратной совместимости внешнего АПИ, особенно если его регулярно на CI запускать
3. поймает регрессии в Spring
4. Ну и, очевидно, поймает если нарушите контракт (например, при рефакторинге идея затупит и поменяет слово в пути)
5. а ещё вы сможете его использовать в процессе разработки и соответственно быстро итерироваться с кодом реализации клиента, не рестаруя всё приложение целиком или не костыляя какой-то отдельный main-метод для этих целей
В общем он будет вашим другом - когда и если вы захотите поменять код клиента, он не будет вам мешать просто так и подскажет, если вы что-то сломаете.
Но это (внешняя система в докере) - практически нереальный вариант.
Вариант №2: реальный
Соответственно следующий вариант - написать тест, который работает с тестовым контуром внешней системы. Скорее всего, его придётся засунуть под флаг и запускать только на CI.
Он продолжит быть вашим другом, но и принесёт ряд проблем:
1. скорее всего он будет медленный
2. возможно он будет мигать
3. сообщать о проблемах он будет позже, чем хотелось бы
Вариант №3: cомнительно, но окей
Если варианты выше не возможны, либо не приемлемы (слишком медленно, слишком часто мигает) - можно взять WireMock.
В этом варианте вы потеряете контроль соблюдения контракта вами и внешней системой, но хотя бы останется контроль, соблюдения контракта вами и Spring-ом. Соответственно такой тест подстрахует вас, если вы решите поменять либу работы с ХТТП, либо обновите версию Spring.
Но я бы на такие тесты вообще не заморачивался - это всё будет покрыто тестами, клиентов нашего клиента, которым для работы надо будет, чтобы InspirationalQuotesClient смог взять данные.
Вариант №4: кто-то в интернете считает, что так правильно, но он не прав
Собственно мокисты считают, что правильно:
1. InspirationalQuotesClient покрыть интеграционным тестом (варианты 1-3 выше), либо не покрывать тестами вообще
2. А в тесте клиента InspirationalQuotesClient замокать уже сам InspirationalQuotesClient, а не WebClient
Но на самом деле правильно:
1. операцию, в которой задействован InspirationalQuotesClient покрыть одним интеграционным тестом, который:
1.1. всю управляемую инфраструктуру (БД, очередь сообщений, внутренние сервисы) поднимает в тест контейнерах и работает с ней
1.2. везде где возможно для неуправляемой инфраструктуры поднимает фейки на транспортном уровне (WireMock)
1.3. В самом крайнем случае мокает свои типы, которые абстрагируют внешнюю инфру, которую по другому не симулировать никак
2. Эту операцию сделать сбалансированной
3. И получить возможность всю бизнес-логику (которая даже косвенно через интерфейсы не зависит от внешних систем) покрыть чистыми юнит тестами, без спринга, моков, тестконтейнеров и т.д.
#ergo_testing@ergonomic_code
Говорят, чёрный пиар - это тоже пиар, поэтому надеюсь пацаны из Spring АйО (Саша, привет! 👋 ) не сильно обидятся, что я их пост разнесу чутка:)
Пример теста в посте имеет две проблемы
Проблема первая - непонятно, что тестирует этот тест
Вообще, вроде как, он должен тестировать клиента внешней системы. Но фактически, он тестирует не клиента внешней системы, а просто фиксирует вызовы Spring-овго АПИ (читай: детали реализации).
И если внешняя система поменяет формат ответа на json - код сломается, а тест продолжит проходить.
А если я перепишу клиента на restTemplate (и проверю руками) - код будет работать, а тест сломается.
Проблема вторая - он нарушает хрестоматийное правило тестов с моками
Мокайте только собственные типы (см. Growing Object-Oriented Software, Guided by Tests, Chapter 8)
—
Как это надо было делать
Вариант №1: идеальный
Поднять в тестконтейнере latest-версию внешней системы и написать тест, который бы работал с ней.
Такой тест:
1. ни как бы не был завязан на реализацию - вы с внешней системой могли бы хоть на protobuf перейти и в самом тесте вообще ничего менять бы не пришлось
1.1. Как следствие он бы подстраховал вас и если бы вы решили поменять либу для работы с хттп (на тот же RestTemplate, например)
2. поймает ошибки обратной совместимости внешнего АПИ, особенно если его регулярно на CI запускать
3. поймает регрессии в Spring
4. Ну и, очевидно, поймает если нарушите контракт (например, при рефакторинге идея затупит и поменяет слово в пути)
5. а ещё вы сможете его использовать в процессе разработки и соответственно быстро итерироваться с кодом реализации клиента, не рестаруя всё приложение целиком или не костыляя какой-то отдельный main-метод для этих целей
В общем он будет вашим другом - когда и если вы захотите поменять код клиента, он не будет вам мешать просто так и подскажет, если вы что-то сломаете.
Но это (внешняя система в докере) - практически нереальный вариант.
Вариант №2: реальный
Соответственно следующий вариант - написать тест, который работает с тестовым контуром внешней системы. Скорее всего, его придётся засунуть под флаг и запускать только на CI.
Он продолжит быть вашим другом, но и принесёт ряд проблем:
1. скорее всего он будет медленный
2. возможно он будет мигать
3. сообщать о проблемах он будет позже, чем хотелось бы
Вариант №3: cомнительно, но окей
Если варианты выше не возможны, либо не приемлемы (слишком медленно, слишком часто мигает) - можно взять WireMock.
В этом варианте вы потеряете контроль соблюдения контракта вами и внешней системой, но хотя бы останется контроль, соблюдения контракта вами и Spring-ом. Соответственно такой тест подстрахует вас, если вы решите поменять либу работы с ХТТП, либо обновите версию Spring.
Но я бы на такие тесты вообще не заморачивался - это всё будет покрыто тестами, клиентов нашего клиента, которым для работы надо будет, чтобы InspirationalQuotesClient смог взять данные.
Вариант №4: кто-то в интернете считает, что так правильно, но он не прав
Собственно мокисты считают, что правильно:
1. InspirationalQuotesClient покрыть интеграционным тестом (варианты 1-3 выше), либо не покрывать тестами вообще
2. А в тесте клиента InspirationalQuotesClient замокать уже сам InspirationalQuotesClient, а не WebClient
Но на самом деле правильно:
1. операцию, в которой задействован InspirationalQuotesClient покрыть одним интеграционным тестом, который:
1.1. всю управляемую инфраструктуру (БД, очередь сообщений, внутренние сервисы) поднимает в тест контейнерах и работает с ней
1.2. везде где возможно для неуправляемой инфраструктуры поднимает фейки на транспортном уровне (WireMock)
1.3. В самом крайнем случае мокает свои типы, которые абстрагируют внешнюю инфру, которую по другому не симулировать никак
2. Эту операцию сделать сбалансированной
3. И получить возможность всю бизнес-логику (которая даже косвенно через интерфейсы не зависит от внешних систем) покрыть чистыми юнит тестами, без спринга, моков, тестконтейнеров и т.д.
#ergo_testing@ergonomic_code
Telegram
Эргономичный код
🔗 Создание Deep Stubs в Mockito
При юнит-тестировании часто требуется проверить методы, которые используют цепочки вызовов, например, в WebClient из Spring WebFlux.
⚠️ Если задача позволяет, лучше воспользоваться MockWebServer или WireMock для гибкого тестирования…
При юнит-тестировании часто требуется проверить методы, которые используют цепочки вызовов, например, в WebClient из Spring WebFlux.
⚠️ Если задача позволяет, лучше воспользоваться MockWebServer или WireMock для гибкого тестирования…
👍4❤3
Что ещё почитать на тему тестирования
Принципы юнит тестирования - самая крутая книга на эту тему
TDD Revisited - Ian Cooper - NDC Porto 2023 - суть здорового тестирования за час пятнадцать
Пачка постов у меня про тестирование Trainer Advisor
Подборки постов у меня в канале - #tdd #nomocks
#ergo_testing@ergonomic_code #books@ergonomic_code #talks@ergonomic_code #posts@ergonomic_code
Принципы юнит тестирования - самая крутая книга на эту тему
TDD Revisited - Ian Cooper - NDC Porto 2023 - суть здорового тестирования за час пятнадцать
Пачка постов у меня про тестирование Trainer Advisor
Подборки постов у меня в канале - #tdd #nomocks
#ergo_testing@ergonomic_code #books@ergonomic_code #talks@ergonomic_code #posts@ergonomic_code
👍9
Карта канала (Так же в Max)
Добро пожаловать на канал "Эргономичный код" — канал о разработке поддерживаемых кодовых баз в общем и моём подходе к этой задаче — Эргономичном подходе.
Что такое Эргономичный подход?
По большому счёту это небольшой набор принципов, взятых в основном из классической школы TDD, функциональной архитектуры и DDD, и большой набор рецептов — моделей, методик и шаблонов —, которые позволяют команде быстро создавать кодовые базы, соответствующие этим принципам и, как следствие, лёгкие в поддержке.
Подробности на сайте Эргономичного подхода
В Эргономичном подходе есть что-то уникальное?
Да. Идея представления системы как модели её эффектов в виде диаграммы эффектов и методика проектирования на базе этой модели.
"Слова дёшевы, покажи мне код!"
Trainer Advisor — некоммерческий, но реальный (~20K строк Котлин кода, 21 таблица, 2 настоящих пользователя, горки костылей, "компромиссных решений" и исторических наслоений) проект с открытым исходным кодом, разрабатываемый по Эргономичному подходу. В этот проект можно поконтрибьютить и на своём опыте прочувствовать работу с эргономичной кодовой базой.
Project Mariotte — минимальный демонстрационный пример кодовой базы, написанной по Эргономичному подходу, на примере операции бронирования номера в отеле
Есть что посмотреть или послушать?
Да, все мои публичные выступления собраны на одной странице
А почитать, кроме канала?
Да, в блоге
В блоге и канале есть подборки:
- Кейсы (в блоге, в канале #case@ergonomic_code)
- Примеры кода (в блоге)
- Эргономичный подход (в блоге, в канале #ergo_approach@ergonomic_code)
- Эргономичное тестирование (в блоге, в канале #ergo_testing@ergonomic_code)
- Функциональная архитектура (в блоге, в канале #functional_architecture@ergonomic_code)
- Эргономиный персистанс (в блоге, в канале #ergo_persistance@ergonomic_code)
- Что ещё почитать (в блоге, в канале #books@ergonomic_code, #posts@ergonomic_code, #papers@ergonomic_code)
- Что ещё посмотреть (в блоге, в канале #talks@ergonomic_code)
Какие ваши доказательства?
Исследование "Характеристики поддерживаемых кодовых баз backend-приложений"
А у меня вопрос!
Приходите в группу - там целому сообществу (более 100 крутых инженеров) можно задать любой вопрос по тематике канала - Эргономичный подход, классическая школа ТДД, ФА, ФП, в целом дизайн модели и системный дизайн
Как мне научить ИИ агента писать код по Эргономичному подходу?
Попробуйте раннюю версию моего фреймворка для ИИ-агентов.
Добро пожаловать на канал "Эргономичный код" — канал о разработке поддерживаемых кодовых баз в общем и моём подходе к этой задаче — Эргономичном подходе.
Что такое Эргономичный подход?
По большому счёту это небольшой набор принципов, взятых в основном из классической школы TDD, функциональной архитектуры и DDD, и большой набор рецептов — моделей, методик и шаблонов —, которые позволяют команде быстро создавать кодовые базы, соответствующие этим принципам и, как следствие, лёгкие в поддержке.
Подробности на сайте Эргономичного подхода
В Эргономичном подходе есть что-то уникальное?
Да. Идея представления системы как модели её эффектов в виде диаграммы эффектов и методика проектирования на базе этой модели.
"Слова дёшевы, покажи мне код!"
Trainer Advisor — некоммерческий, но реальный (~20K строк Котлин кода, 21 таблица, 2 настоящих пользователя, горки костылей, "компромиссных решений" и исторических наслоений) проект с открытым исходным кодом, разрабатываемый по Эргономичному подходу. В этот проект можно поконтрибьютить и на своём опыте прочувствовать работу с эргономичной кодовой базой.
Project Mariotte — минимальный демонстрационный пример кодовой базы, написанной по Эргономичному подходу, на примере операции бронирования номера в отеле
Есть что посмотреть или послушать?
Да, все мои публичные выступления собраны на одной странице
А почитать, кроме канала?
Да, в блоге
В блоге и канале есть подборки:
- Кейсы (в блоге, в канале #case@ergonomic_code)
- Примеры кода (в блоге)
- Эргономичный подход (в блоге, в канале #ergo_approach@ergonomic_code)
- Эргономичное тестирование (в блоге, в канале #ergo_testing@ergonomic_code)
- Функциональная архитектура (в блоге, в канале #functional_architecture@ergonomic_code)
- Эргономиный персистанс (в блоге, в канале #ergo_persistance@ergonomic_code)
- Что ещё почитать (в блоге, в канале #books@ergonomic_code, #posts@ergonomic_code, #papers@ergonomic_code)
- Что ещё посмотреть (в блоге, в канале #talks@ergonomic_code)
Какие ваши доказательства?
Исследование "Характеристики поддерживаемых кодовых баз backend-приложений"
А у меня вопрос!
Приходите в группу - там целому сообществу (более 100 крутых инженеров) можно задать любой вопрос по тематике канала - Эргономичный подход, классическая школа ТДД, ФА, ФП, в целом дизайн модели и системный дизайн
Как мне научить ИИ агента писать код по Эргономичному подходу?
Попробуйте раннюю версию моего фреймворка для ИИ-агентов.
Эргономичный подход
Редирект на индексную страницу
🔥6❤4👍3
Привет!
Добавил на вики пару заглушек паттернов тестирования:
1. Тестирование генерации xlsx-документов с помощью Apache POI
2. Используйте фейковый кодировщик паролей
#ergo_testing@ergonomic_code #ergowiki@ergonomic_code
Добавил на вики пару заглушек паттернов тестирования:
1. Тестирование генерации xlsx-документов с помощью Apache POI
2. Используйте фейковый кодировщик паролей
#ergo_testing@ergonomic_code #ergowiki@ergonomic_code
Эргономичный подход
Тестирование генерации xlsx-документов с помощью Apache POI (v0.0.0)
Тестирование кода генерации xlsx-документов является достаточно сложной задачей.
Верификация состояния XSSFWorkbook вручную будет очень громоздкой и сложной для чтения.
О существовании какого-то DSL-я, который бы позволял лаконичного и читаемо описывать корректные…
Верификация состояния XSSFWorkbook вручную будет очень громоздкой и сложной для чтения.
О существовании какого-то DSL-я, который бы позволял лаконичного и читаемо описывать корректные…
🔥5
Привет!
Мне тут на Хабре заминусили коммент про отказ от моков в пользу интеграционного тестирования.
В ответ на это я собрался мокистам ответить подборкой цитат классиков и экспертов по ТДД о моках и оказалось, что у меня её нет.
Теперь есть:)
Берите себе на вооружение, в своей борьбе за простое девелоперское счастье и здоровый ночной сон:)
#posts@ergonomic_code #whynomocks@ergonomic_code #ergo_testing@ergonomic_code
Мне тут на Хабре заминусили коммент про отказ от моков в пользу интеграционного тестирования.
В ответ на это я собрался мокистам ответить подборкой цитат классиков и экспертов по ТДД о моках и оказалось, что у меня её нет.
Теперь есть:)
Берите себе на вооружение, в своей борьбе за простое девелоперское счастье и здоровый ночной сон:)
#posts@ergonomic_code #whynomocks@ergonomic_code #ergo_testing@ergonomic_code
Алексей Жидков
Эксперты об интеграционном тестировании и моках - Алексей Жидков
https://azhidkov.pro/
1👍11🔥6❤4
Эргономичный код
Привет!
Баги, найденные командой QA это:
Баги, найденные командой QA это:
Понимаю, что на самом деле сильно зависит от, но хочу понять общее отношение к багам в сообществе - выберите вариант который вам по духу ближе, пожалуйста.
#ergo_testing@ergonomic_code
#ergo_testing@ergonomic_code
Привет!
У меня в новом сервисе в Проекте Э на Spring Boot 3.5 новый рекорд скорости тестов:)
54 кейса за 2.7 секунды, 90% тестов - < 60мс, медиана - 14мс.
Сетап:
1. инфра (PostgreSQL и Minio на RAM-диске) запускается руками по кнопке в Идее docker compose-ом.
2. Отказ от компонент скана бинов
3. Отказ от скана авто-конфигов
4. ленивая иницилазиация бинов (spring.main.lazy-initialization)
5. Работа через WebTestClient с MockMvc
Не 5мс на кейс, как у Саши Раковского, конечно, но уже близко и это полный набор тестов, после которого можно деплоить в прод:)
#ergo_testing@ergonomic_code #project_e@ergonomic_code #spring_boot@ergonomic_code
У меня в новом сервисе в Проекте Э на Spring Boot 3.5 новый рекорд скорости тестов:)
54 кейса за 2.7 секунды, 90% тестов - < 60мс, медиана - 14мс.
Сетап:
1. инфра (PostgreSQL и Minio на RAM-диске) запускается руками по кнопке в Идее docker compose-ом.
2. Отказ от компонент скана бинов
3. Отказ от скана авто-конфигов
4. ленивая иницилазиация бинов (spring.main.lazy-initialization)
5. Работа через WebTestClient с MockMvc
Не 5мс на кейс, как у Саши Раковского, конечно, но уже близко и это полный набор тестов, после которого можно деплоить в прод:)
#ergo_testing@ergonomic_code #project_e@ergonomic_code #spring_boot@ergonomic_code
🔥8👍7
Привет!
Я закончил большой 5-месячный долгострой на 43 коммита по интеграции Google Calendar в Trainer Advisor.
В реализации этой фичи довольно много интересных, на мой взгляд, аспектов, каждый из которых заслуживает отдельного поста. Но сейчас их писать настроения нет, поэтому я ограничился микропостом с обзором реализации. Ну как микро - 25 минут чтения по оценке ФФ:)
И чтобы вам не продираться сквозь 25 минут потока сознания в поисках чего-то интересного для себя - вот краткое содержание:)
Абстрактный ресурс
Для меня самым интересным в этой фиче было то, что для её реализации пришлось ввести некие штуки с рабочим названием «Абстрактный ресурс».
Не знаю пока что с этим делать и надо ли что-то делать.
MockServers
Паттерн для организации WireMock-стабов
Fixtures
Паттерн для сетапа фикстур, состоящих из сложных графов объектов
Пример «простого» CRUD-приложения
Я в последнее время в канале несколько раз писал о «простых» CRUD-приложения — приложениях без сложной бизнес-логики или нефункциональных требований, но, тем не менее, которые назвать простыми не поворачивается язык. И всякий раз это порождало вопросы в комментариях, что конкретно я имею ввиду.
И вот у меня, наконец появился, хороший open source-ый пример — операция отображения страницы расписания терапевта.
Рефакторинг findCalendarItemsInInterval (уровни абстракции/стратификация)
Пример приведения метода к соответствию правилу "У функции должен быть один уровень абстракции"
SourceItem → URI
К своему стыду, должен признаться, что я только недавно до конца (чуть лучше?) осознал что такое URI. Но лучше поздно, чем никогда - правда же?
И вот теперь благодаря этим новым знаниям, мне удалось сделать работу с разными календарями в Trainer Advisor чуть более "production grade".
Как добыть OAuth2AuthorizedClient без того, чтобы перетереть Authorization в SecurityContext
Я хз. Но у меня есть рабочий код, на который можно ориентироваться
И этот код мало того, что рабочий — он ещё и тестами покрыт.
Тестирование интеграции с Google OAuth и Google Calendars
Вот оно:
- GoogleAuthorizationIntegrationTest;
- GoogleCalendarsServiceTest;
- GetGoogleCalendarsSettingsEndpointTest;
- SetCalendarShouldBeShownTest;
- Тест "Страница календаря должна рендериться корректно, даже если у терапевта есть подключенный Google-календарь и запрос событий из него приводит к ошибке";
- CreateAppointmentPageTest.createAppointmntWithGoogleEvnt;
- SchedulePageControllerTest;
Верификация приложения в Google
Это 7 кругов ада. Но без них ваши токены будут протухать раз в неделю и вам надо будет снова гнать юзеров на авторизацию в гугле
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #case@ergonomic_code
Я закончил большой 5-месячный долгострой на 43 коммита по интеграции Google Calendar в Trainer Advisor.
В реализации этой фичи довольно много интересных, на мой взгляд, аспектов, каждый из которых заслуживает отдельного поста. Но сейчас их писать настроения нет, поэтому я ограничился микропостом с обзором реализации. Ну как микро - 25 минут чтения по оценке ФФ:)
И чтобы вам не продираться сквозь 25 минут потока сознания в поисках чего-то интересного для себя - вот краткое содержание:)
Абстрактный ресурс
Для меня самым интересным в этой фиче было то, что для её реализации пришлось ввести некие штуки с рабочим названием «Абстрактный ресурс».
Не знаю пока что с этим делать и надо ли что-то делать.
MockServers
Паттерн для организации WireMock-стабов
Fixtures
Паттерн для сетапа фикстур, состоящих из сложных графов объектов
Пример «простого» CRUD-приложения
Я в последнее время в канале несколько раз писал о «простых» CRUD-приложения — приложениях без сложной бизнес-логики или нефункциональных требований, но, тем не менее, которые назвать простыми не поворачивается язык. И всякий раз это порождало вопросы в комментариях, что конкретно я имею ввиду.
И вот у меня, наконец появился, хороший open source-ый пример — операция отображения страницы расписания терапевта.
Рефакторинг findCalendarItemsInInterval (уровни абстракции/стратификация)
Пример приведения метода к соответствию правилу "У функции должен быть один уровень абстракции"
SourceItem → URI
К своему стыду, должен признаться, что я только недавно до конца (чуть лучше?) осознал что такое URI. Но лучше поздно, чем никогда - правда же?
И вот теперь благодаря этим новым знаниям, мне удалось сделать работу с разными календарями в Trainer Advisor чуть более "production grade".
Как добыть OAuth2AuthorizedClient без того, чтобы перетереть Authorization в SecurityContext
Я хз. Но у меня есть рабочий код, на который можно ориентироваться
И этот код мало того, что рабочий — он ещё и тестами покрыт.
Тестирование интеграции с Google OAuth и Google Calendars
Вот оно:
- GoogleAuthorizationIntegrationTest;
- GoogleCalendarsServiceTest;
- GetGoogleCalendarsSettingsEndpointTest;
- SetCalendarShouldBeShownTest;
- Тест "Страница календаря должна рендериться корректно, даже если у терапевта есть подключенный Google-календарь и запрос событий из него приводит к ошибке";
- CreateAppointmentPageTest.createAppointmntWithGoogleEvnt;
- SchedulePageControllerTest;
Верификация приложения в Google
Это 7 кругов ада. Но без них ваши токены будут протухать раз в неделю и вам надо будет снова гнать юзеров на авторизацию в гугле
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #case@ergonomic_code
Алексей Жидков
Trainer Advisor — интеграция с Google Calendar - Алексей Жидков
https://azhidkov.pro/
❤10👍7
Привет!
Собрал микропост со сверкой рекомендаций ЭП с результатами анализа.
TLDR:
Судя по данным, собранным в рамках исследования:
— три из девяти рекомендаций Эргономичного подхода (пишите тесты, держите тесты быстрыми, исключайте циклы в зависимостях) ведут к повышению поддерживаемости;
— ещё пять (минимизация моков, разбиение модели на агрегаты, разделение IO и логики и использование неизменяемой модели данных, ограничение кол-ва зависимостей до 5–7 на компонент, использование открытой архитектуры), как минимум не снижают поддерживаемость, либо имеют небольшой тренд на её повышение;
— наконец, последняя рекомендация — не вводить интерфейсы без необходимости — никак не связана с поддерживаемостью: не повышает, но и не снижает её.
Хоть выборка у нас получилась и небольшая, но, на мой взгляд, голословные утверждения и немного статистики - это немного лучше, чем просто голословные утверждения.
—
Плюс пока писал пост накопал ещё один любопытный инсайт.
Между временем запуска одного теста и поддерживаемостью есть погранично значимая, но сильная (почти что очень сильная) связь с поддерживаемостью. И больше всего поддерживаемых (10 из 13) проектов было в категории «2–10 секунд». В то время как для категории «0-1 секунду» только лишь 2 из 7 проектов были поддерживаемым.
Здесь уже начинаются чистой воды спекуляции на результатах анализа совсем маленькой выборки (23 ответа на этот вопрос), но, кажется, эти данные можно проинтерпретировать как дважды косвенное подтверждение идеи, что фокус на качественных (работающих до 10 секунд) интеграционных тестах повышает поддерживаемость.
#ergo_approach@ergonomic_code #ergo_testing@ergonomic_code
Собрал микропост со сверкой рекомендаций ЭП с результатами анализа.
TLDR:
Судя по данным, собранным в рамках исследования:
— три из девяти рекомендаций Эргономичного подхода (пишите тесты, держите тесты быстрыми, исключайте циклы в зависимостях) ведут к повышению поддерживаемости;
— ещё пять (минимизация моков, разбиение модели на агрегаты, разделение IO и логики и использование неизменяемой модели данных, ограничение кол-ва зависимостей до 5–7 на компонент, использование открытой архитектуры), как минимум не снижают поддерживаемость, либо имеют небольшой тренд на её повышение;
— наконец, последняя рекомендация — не вводить интерфейсы без необходимости — никак не связана с поддерживаемостью: не повышает, но и не снижает её.
Хоть выборка у нас получилась и небольшая, но, на мой взгляд, голословные утверждения и немного статистики - это немного лучше, чем просто голословные утверждения.
—
Плюс пока писал пост накопал ещё один любопытный инсайт.
Между временем запуска одного теста и поддерживаемостью есть погранично значимая, но сильная (почти что очень сильная) связь с поддерживаемостью. И больше всего поддерживаемых (10 из 13) проектов было в категории «2–10 секунд». В то время как для категории «0-1 секунду» только лишь 2 из 7 проектов были поддерживаемым.
Здесь уже начинаются чистой воды спекуляции на результатах анализа совсем маленькой выборки (23 ответа на этот вопрос), но, кажется, эти данные можно проинтерпретировать как дважды косвенное подтверждение идеи, что фокус на качественных (работающих до 10 секунд) интеграционных тестах повышает поддерживаемость.
#ergo_approach@ergonomic_code #ergo_testing@ergonomic_code
Алексей Жидков
Анализ результатов исследования факторы поддерживаемости backend-проектов с точки зрения Эргономичного подхода - Алексей Жидков
https://azhidkov.pro/
1👍9🔥5
Привет!
Я недавно сделал Web Push уведомления в Trainer Advisor и попутно снова узнал и придумал пачку прикольных штук, о которых накатал очередной "микропост" на 30-40 минут чтения по оценке ФФ.
Ну и по традции вот вам сразу содержание, чтобы привлечь внимание мякоткой:
* Отправка пушей
* Архитектура
* Абстракция vs очевидность эффектов и разделение ввода и вывода
* И снова про уровни абстракции/стратификацию
* Пример №1: код открытия диплинка по клику
* Пример №2: фетч ресурсов с фолбэком на кэш и кастомную страницу «Сервис недоступен"
* Postgres GENERATED-колонки для ограничений целостности в JSONB
* TrainerAdvisorApis
* В Gradle-плагин GitProperties завезли поддержку git worktrees
* Отказ от Kotest Matchers в пользу shuold*-методов
#case@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #ergo_persistance@ergonomic_code
Я недавно сделал Web Push уведомления в Trainer Advisor и попутно снова узнал и придумал пачку прикольных штук, о которых накатал очередной "микропост" на 30-40 минут чтения по оценке ФФ.
Ну и по традции вот вам сразу содержание, чтобы привлечь внимание мякоткой:
* Отправка пушей
* Архитектура
* Абстракция vs очевидность эффектов и разделение ввода и вывода
* И снова про уровни абстракции/стратификацию
* Пример №1: код открытия диплинка по клику
* Пример №2: фетч ресурсов с фолбэком на кэш и кастомную страницу «Сервис недоступен"
* Postgres GENERATED-колонки для ограничений целостности в JSONB
* TrainerAdvisorApis
* В Gradle-плагин GitProperties завезли поддержку git worktrees
* Отказ от Kotest Matchers в пользу shuold*-методов
#case@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #ergo_persistance@ergonomic_code
Алексей Жидков
Trainer Advisor — WebPush-уведомления - Алексей Жидков
https://azhidkov.pro/
🔥4❤3👍2
Привет!
У меня недавно в Проекте Э случилась поучительная и многогранная история. Эта история одновременно:
1. Иллюстрирует как именно глобальное изменяемое состояние усложняет поддержку кода. И соответственно, почему его стоит избегать.
2. Показывает, что зелёные тесты на внешнее API не гарантируют отсутствие тупых багов внутри.
#why_fp@ergonomic_code #ergo_testing@ergonomic_code #project_e@ergonomic_code
У меня недавно в Проекте Э случилась поучительная и многогранная история. Эта история одновременно:
1. Иллюстрирует как именно глобальное изменяемое состояние усложняет поддержку кода. И соответственно, почему его стоит избегать.
2. Показывает, что зелёные тесты на внешнее API не гарантируют отсутствие тупых багов внутри.
#why_fp@ergonomic_code #ergo_testing@ergonomic_code #project_e@ergonomic_code
Алексей Жидков
Глобальное состояние и тестирование через внешнее API - Алексей Жидков
https://azhidkov.pro/
Привет!
Навеяно интернетом.
Многие думают, что тесты нужны для того, чтобы проверить код, который программист написал только что.
Некоторые из них вспоминают, что Дейкстра писал:
И говорят: «Тесты не нужны» (c).
И (по крайней мере для тестов на базе примеров, а не тестов свойств) в каком-то смысле они правы — я как человек, который "пишет тесты. не так много. в основном интеграционные", отлично знаю, что Корпоративный Разработчик из Ада обдурит львиную долю моих интеграционных тестов на базе примеров как младенцев.
Но, несмотря на это, у меня другое мнение по вопросу "нужны ли тесты?" (вот это каминг аут у меня тут вышел🤦♂️ ).
Тесты нужны. Но не для того, чтобы продемонстрировать отсутствие ошибок в коде, который я только что написал. А для того, чтобы продемонстрировать отсутствие ошибок в коде, который я только что изменил. И во всех его зависимостях.
И с учётом этого, тесты начинают играть новыми красками.
Если вы только что сделали новую фичу и все тесты зелёные — то действительно, в ней всё ещё могут быть баги.
Но можно фикс каждого бага начинать с теста.
И тогда после того, как ваша фича пройдёт QA и покрутится месяц в проде, она обрастёт набором тестов на кейсы, которые действительно важны пользователям.
И этот набор уже можно будет считать достаточно адекватным способом продемонстрировать отсутствие ошибок в фиче.
И это — быстрая проверка кода тестами на отсутствие ошибок — единственный известный мне реальный способ уйти от установки "работает — не трожь" и спокойно менять работающий код тогда, когда это надо.
Что, в свою очередь, является единственным известным мне способом своевременно отдавать техдолг: менять уже работающий код.
Что, наконец, является единственным известным мне способом гордиться тем, что я делаю, и с радостьюприходить утром на работу переключаться в обед на рабочий воркспейс. Ну и не терять темп разработки со временем.
—
Теоретически адекватных тестов можно можно добиться и без TDD.
Но дисциплина работы по TDD даёт простым смертным:
1. Гарантию того, что вы действительно напишете тесты (а не спишите их написание в техдолг).
2. Гарантию того, что эти тесты будут проверять все требования о которых вы и постановщик задачи подумали (а не только те, о которых вы вспомнили и на которые хватило времени).
3. Гарантию того, что эти тесты действительно что-то проверяют, а не зелёные всегда (вы же не пишете тесты на тесты?).
В общем: Пишите тесты. Сначала. Не так много. В основном интеграционные.
#ergo_testing@ergonomic_code
Навеяно интернетом.
Многие думают, что тесты нужны для того, чтобы проверить код, который программист написал только что.
Некоторые из них вспоминают, что Дейкстра писал:
Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence.
—
Тестирование программ может быть очень эффективным способом продемонстрировать наличие ошибок, но оно безнадёжно неадекватно для демонстрации их отсутствия.
И говорят: «Тесты не нужны» (c).
И (по крайней мере для тестов на базе примеров, а не тестов свойств) в каком-то смысле они правы — я как человек, который "пишет тесты. не так много. в основном интеграционные", отлично знаю, что Корпоративный Разработчик из Ада обдурит львиную долю моих интеграционных тестов на базе примеров как младенцев.
Но, несмотря на это, у меня другое мнение по вопросу "нужны ли тесты?" (вот это каминг аут у меня тут вышел
Тесты нужны. Но не для того, чтобы продемонстрировать отсутствие ошибок в коде, который я только что написал. А для того, чтобы продемонстрировать отсутствие ошибок в коде, который я только что изменил. И во всех его зависимостях.
И с учётом этого, тесты начинают играть новыми красками.
Если вы только что сделали новую фичу и все тесты зелёные — то действительно, в ней всё ещё могут быть баги.
Но можно фикс каждого бага начинать с теста.
И тогда после того, как ваша фича пройдёт QA и покрутится месяц в проде, она обрастёт набором тестов на кейсы, которые действительно важны пользователям.
И этот набор уже можно будет считать достаточно адекватным способом продемонстрировать отсутствие ошибок в фиче.
И это — быстрая проверка кода тестами на отсутствие ошибок — единственный известный мне реальный способ уйти от установки "работает — не трожь" и спокойно менять работающий код тогда, когда это надо.
Что, в свою очередь, является единственным известным мне способом своевременно отдавать техдолг: менять уже работающий код.
Что, наконец, является единственным известным мне способом гордиться тем, что я делаю, и с радостью
—
Теоретически адекватных тестов можно можно добиться и без TDD.
Но дисциплина работы по TDD даёт простым смертным:
1. Гарантию того, что вы действительно напишете тесты (а не спишите их написание в техдолг).
2. Гарантию того, что эти тесты будут проверять все требования о которых вы и постановщик задачи подумали (а не только те, о которых вы вспомнили и на которые хватило времени).
3. Гарантию того, что эти тесты действительно что-то проверяют, а не зелёные всегда (вы же не пишете тесты на тесты?).
В общем: Пишите тесты. Сначала. Не так много. В основном интеграционные.
#ergo_testing@ergonomic_code
Please open Telegram to view this post
VIEW IN TELEGRAM
Kentcdodds
Write tests. Not too many. Mostly integration.
[Guillermo Rauch](https://x.com/rauchg) [tweeted](https://x.com/rauchg/status/807626710350839808) this a while back. Let's take a dive into what it means.
❤9💯3