Как стать автором
Обновить
3
0
Семен Левин @remal

Пользователь

Отправить сообщение

Есть всякие тулы типа Terratest.

Но основной вопрос в уровне абстракции. Если вам надо протестировать, что какой-то простой метод возвращает какое-то значение, вы unit тест напишите или интеграционный? Думаю, ответ очевиден. Тогда почему для тестирования конфигов надо гонять end-to-end сценарии?

Немного по тексту статьи.

Для проверки на доступность порта я пользовался примерно таким кодом: https://stackoverflow.com/a/48828373 (см setReuseAddress)

Для проверки на дебаггер:

boolean IS_IN_DEBUG = ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("jdwp");

Возможно, менее универсально, чем у вас, но мне хватало.

Ожидать от внешнего сервиса можно что угодно, да. И то, что контракт может не исполняться. Проблема в том, что есть вещи в зоне нашей отвественности, а есть те, о которых мы должны знать (что они могут происходить), но вне нашей зоне ответственности. Вот оказалась на сервере битая плата оперативы. Вы это явно не тестами проверять будете, особенно если в облаке хоститесь. Соответственно, вкладываясь в интеграционные тесты, вы не вкладываетесь в observability и укорачавание релизного цикла (ресуры не бесконечны).

Как проверить какие сценарии покрыты тестами, а какие - нет? В общем случае гарантировать это невозможно. На уровне юнит тестов - code review. На уровне системы - а точно надо? Но даже если и надо, то, имхо, первичный вопрос - что делать с багами, найденными там? Я бы каждый найденный там баг спускал бы в команду разработки с вопросом как починить причину его возникновения (чек листы на code review, рефакторинг, архитектура, тренинги, ...) А вопрос как тестировать end-to-end для меня вторичен. Да хоть руками, если это экономически выгоднее.

Проблема в том, что качество не мерится только лишь процентом покрытия. На одном из проектов я вот прям и говорил: граничные условия покрываем только если есть свободное время. Это немного утрированно, но посыл был примерно такой, о приоритетах. Тем не менее, проблем с качеством было крайне мало и 90% багов было связано с плохим пониманием контрактов, что надо было решать не тестами, а привлечением аналитика. Ресурсов на аналитика не было, тч потерпели первые пару месяцев в продакшене, тестируя руками, дальше полет нормальный, все довольны. Но, да, мы использовали строгие контракты везде, где можно, много кодогенерации, задали высокую планку для code review, у нас в каждый pull request автоматом отправлялся check list, а также писали кучу правил для статического анализа (см ArchUnit).

Плюс юнит тестов не сколько в быстром исполнении, сколько в локализованности - вы очень быстро найдете где конкретно падает. Чем выше мы поднимаемся по пирамиде тестирования, тем дольше это время. На нынешнем проекте я месяца полтора убеждал заказчика писать меньше интеграционных тестов и больше юнит - команда разработки тратила 10-15% времени на починку и разбор нестабильных интеграционных тестов. Сейчас стало лучше.

Давайте честно: с тз читателя вы сделали не решение, а примерно описали в каком направлении копать и ряд подводных камней. Повторить ваше решение даже по статье сможет достаточно небольшой процент разработчиков. Это не претензия, если что. Кстати, я звездочками пометил пару репозиториев на github, за это спасибо. Проблема, на мой взгляд, что очень многие все еще говорят о том, как делать микросервисы, как писать интеграционные или end-to-end тесты и тд, но очень мало рассказов о том, как это не делать. А "не делать" - это не просто не делать. Это - о том, как не делая достигать поставленных целей. А тут и проблемы с доверием, и сбор бизнес метрик, и куча всего.

На тему end-to-end тестов вот неделю назад как раз читал: https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html?m=1 Но это - Гугл, они спокойно на пользователях в проде тестируют. Лично я выпускал успешные проекты без единого автоматизированного end-to-end, т.ч., да, я готов ставить под сомнение их целесообразность. И, если что, в моем понимании, интеграционные тесты - testcontainers, sql проверить, например. А ваше решение для меня намного ближе к end-to-end.

Я изначально свою ветку начал с того, что призвал читателей так не делать. Т.е. все это обсуждение - о целесообразности. Это не значит, что статья бесполезная, если что. Мой посыл, скорее, - почитайте, узнайте что-то новое, но 10 раз подумайте точно ли оно вам надо, перед тем, как копировать.

Хорошая архитектура в глобальном смысле - не только о возможностях, но и об ограничениях и посылах.

Тут вы даете возможность, но что насчет ограничений?

Давайте приведу вот еще такой пример: цель - деплоить несколько раз в день. Не в конце спринта, если у вас Скрам, а вот реально несколько раз в день. Одна эта цель меняет все - от стиля написания кода и размеров pull request'ов, до способа управления проектом (Скрам уже не подходит).

Понимаете какая штука... А вам точно нужно протестировать вот прям все сценарии с граничными условиями?

Ресурсы же не бесконечны и очень часто приходится расставлять приоритеты и чем-то жертвовать. Настолько ли ваша система критична, что даже час-два, к примеру, простоя вызовет огромные денежные потери для компании? Точно ли вам надо тратить пару человеко-месяцев на разработку и отладку такого решения, а не фичи пилить?

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

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

Проблема в том, что, возможно (!), вы чинили не причину, а следствие. Отсутствие доверия, в т.ч. и к самому себе, - это такая же проблема, как упавший тест или баг в продакшене. И ровно так же эта проблема может быть решена. Только смотреть тут надо на коммуникацию, процессы, архитектуру, метрики качества, насколько детальный анализ причин каждого бага проводится и т.д. Для инженера это сложно и непривычно, знаю по себе.

Понимаете, способов обеспечить качество много и парой видов тестов все не ограничивается.

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

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

На нескольких проектах я задавал такой вопрос. У нас есть отдельно протестированный сервис А и отдельно протестированный сервис B, где взаимодействие с сервисом A замокано. Зачем нам тестировать еще и end-to-end сценарии, если есть строгие контракты? Что мы тестируем вообще? Бизнес логика протестирована изолировано. Конфигурацию и инфраструктуру? Так это не сквозным тестированием проверить можно. Тогда что? Просто повторим наши юнит тесты? Смысл? Четстного ответа "мы не доверяем разработчикам" я так и не дожидался, хотя по косвенным признакам было понятно, что проблема где-то тут.

А вот по Testcontainers для баз, например, я полностью поддерживаю, кстати.

Автор, ваш подход, наверное, будет работать на вашем конеретном проекте, но читателей я прошу до последнего так не делать.

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

Вы выше упоминаете независимый деплой. На мой взгляд, независимый деплой возможен только при независимой разработке. У меня есть определенные подозрения, что в данном случае с независимой разработкой так себе. Я не авторитет? Без проблем, давайте посмотрим что говорят Sam Newman и Martin Fowler: https://youtu.be/GBTdnfD6s5Q

К чему подобные тесты приводят в long-term: нестабильные тесты, огромные затраты на поиск причины свалившегося теста и изменение кучи тестов при выкатывании новых фич. Надеюсь, у вас получается этого избежать.

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

jOOQ смего генератором эти проблемы решает довольно-таки легко.

Так а тривиальные запросы тривиально и на SQL пишуться.

Проблема в том, что тривиального crud только в туториалах много. А в реальном приложении всяких join, динамичных запросов и т п. дофига. Писать на hibernate все это - боль (в сравнении с sql).

А для тривиального crud всегда можно на том же jooq абстракцию написать.

А почему вы считаете, что измерили именно вызов метода 'add'? Он может заинлайнится, цикл может быть оптимизирован, а, учитывая, что поле 'value' не читается, не удивлюсь, если окажется, что и вызов метода вместе с циклом были просто удалены

Когда расхреначили ЮКОС, мы (россияне) молчали. Молчали когда НТВ превратилось в помойку. Молчали когда отжали Крым и когда Россия поддерживала конфликт в ЛДНР. Молчали когда условные Каспаров, Немцов, Навальный с командой или Гуриев говорили к чему все идет. Молчали в ответ на нечестные выборы. Молчали в ответ на повальные маркировки "инагентами". Молчали в ответ на коррупцию и на беспредел силовиков. Молчали по поводу пыток в тюрьмах. И т.п.

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

Очень печально что пострадют и те, кто не выбирал бездействие. Но давайте честно сами себе признаемся, что таких было невероятно мало.

Насколько я понимаю, все очень зависит от специфики. Много относительно мелких параллельных запросов? Используем nio (скорее всего). Одновременных запросов мало, но данных по каждому обработать дофига? Обычный io.

Насколько я помню, nio - не о throughput, а о scalability. Ссылок на бенчмарки сейчас по памяти не приведу, но, как минимум, переключение контекстов должно добавлять накладных расходов. Да и не просто так однопоточный gc показывает более высокий именно throughput.

А в чем проблема тут вообще? Любой нормальный текстовый редактор это прозрачно поддерживает, а про ide вообще молчу.

За время, что провожу интервью, только один раз спросил о том, как работает HashMap - хотел подтвердить свою теорию, что любой, хотя бы пытавшийся готовится к интервью, знает ответ. Подтвердил. Задачки на алгоритмы? Ровно также можно готовиться на leetcode.

Что спрашиваю вместо этого? Заковырестые места предыдущих проектов, распределенные транзакции, exactly once в messaging-е, observability, разные сценарии отказа, масштабирование как сервисов, так и баз, ну и то, что интересного вычитаю из резюме. Спрошу о видах тестирования и что-то об интеграционных тестах. По Спрингу - BeanPostProcessor'ы, по Спринг Буту - рассказать о написании стартера. По самой Java вопрос обычно один - поток стартует второй поток, а как потом этот второй поток остановить? На мой взгляд, senior в современной типовой java должен спокойно рассуждать на все эти темы. Большим плюсом будет наличие pet project'ов. Если что-то одно не знает или знает плохо (да хоть тот же Спринг, к примеру) - не страшно, т.к. толковый научится.

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

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

Да, у нас высокая процентная ставка. И?.. Что из этого следует-то, по вашему? И какие, по-вашему, причины такой ситуации? Давайте тогда и инфляцию, и риски сравнивать.

А что такое, по вашему, "перекредитованность"?

Общий размер долга, если что, не так важен, как способность к его обслуживанию. Банк России, например, оценил долю кредитов с просроченными платежами в России в 4.5%. В тех же США это цифра примерно в 2 раза меньше.

Статья достаточно очевидная, но аргументация хромает. Многие рассматривают микросервисы только как набор чисто технических "за" или "против". Проблема в том, что микросервисы - это не о "гибкости, простоте, масштабируемости, отказоустойчивости и т.п.". Микросервисы, прежде всего, - о масштабируемости организации. О том, как организовать работу нескольких десятков, сотен и тысяч разрабов. И тут, прежде всего, важным становится независимость разработки и деплоя. Отсюда вывод достаточно простой: entity service имеет смысл рассматривать только когда предметная область и конкретный бизнес уже очень хорошо изучены, а ранее, чем через года 3 это точно не произойдет. В противном случае контракты будут часто меняться и независимая разработка останется только в мечтах.

«Распределенная транзакция» сейчас считается анти-паттерном. Для меня вообще странно, что в 2020 году об этом паттерне говорят. Даже более того: имхо, это просто нерабочий паттерн. По одной простой причине — любой компонент системы когда-нибудь упадет. Рано или поздно упавший менеджер транзакций приведет к огромному геморою. Низкая производительность — тоже аргумент, но, с моей т.з., куда как менее важный.

По сути, другого выбора, кроме саги, в распределенных сервисах просто нет. Это может быть как формальная сага, так и сага по сути. В противном случае получите неконсистентные данные.
1
23 ...

Информация

В рейтинге
Не участвует
Откуда
San Jose, California, США
Дата рождения
Зарегистрирован
Активность