Тестирование middleware
От: cppguard  
Дата: 18.10.21 11:29
Оценка: +1
Прошу прощения, если неправильно применяю второе слово, но по-другому не знаю, как описать код, с которым я работаю по работе в данный момент. Суть его в том, что дёргаются разные микросервисы, переливаются данные из пустого JSON в порожнее Thrift и обратно. Как тестировать такой код, когда не существует заглушек или тривиальных реализаций для зависимостей? В данный момент 99% тестов это mocking API сервисов, к которым обращается тестируемый код, с последующей проверкой того, что функция была вызвана. По-мойму, это не просто пустая трата времени, а небольшая диверсия, потому что всем кажется, что код покрыт тестами, а на деле ничего не покрыто, и ломается на раз-два (происходит постоянно). Лет 8 назад я работал на похожем проекте, но там всё было на JavaEE с инверсией зависимостей и обязательным написанием stub или no-op реализации для каждого интерфейса.
Re: Тестирование middleware
От: vmpire Россия  
Дата: 18.10.21 14:13
Оценка: +1
Здравствуйте, cppguard, Вы писали:

C>Прошу прощения, если неправильно применяю второе слово, но по-другому не знаю, как описать код, с которым я работаю по работе в данный момент. Суть его в том, что дёргаются разные микросервисы, переливаются данные из пустого JSON в порожнее Thrift и обратно. Как тестировать такой код, когда не существует заглушек или тривиальных реализаций для зависимостей?

Тестировать нужно то, что может сломаться. Бессмысленно (за некоторыми исключениями) тестировать сам факт того, что дёрнется какой-то метод. Нужно тестировать не только компоненты системы (а если они тривиальные, так можно и вообще не тестировать), но и связь этих компонентов. То есть, если система сильно связанная, то основное внимание нужно уделять интеграционному тестированию.
Например, в вашем случае написать тест на "переливаются данные из JSON в Thrift и обратно и при этом данные не изменяются". Ну или какие там больше подходят.
Да, на вас будут катить бочку, что "это же не юнит тестирование!" и "как можно задействовать в тестах внешние компоненты!". Зато приложение будет реально протестировано.

C>В данный момент 99% тестов это mocking API сервисов, к которым обращается тестируемый код, с последующей проверкой того, что функция была вызвана. По-мойму, это не просто пустая трата времени, а небольшая диверсия, потому что всем кажется, что код покрыт тестами, а на деле ничего не покрыто, и ломается на раз-два (происходит постоянно).

Это типичная ловушка в которую попадают фанатичные апологеты TDD и IOC. По метрикам всё отлично: низкий каплинг, 90% покрытие тестами, тесты проходят быстро и на каждом билде, всё зелёное и красивое. Одна беда омрачает жизнь: проиложение не работает и никто не понимает, почему. Потому, что держать в голове взаимосвязь сотни компонентов нереально, а тесты тестируют только самих себя.
У меня сейчас в текущем проекте та же беда.
Re: Тестирование middleware
От: maxkar  
Дата: 25.10.21 09:03
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Как тестировать такой код, когда не существует заглушек или тривиальных реализаций для зависимостей?

Пишите нетривиальные реализации. Я тоже предложу смотреть на интеграционные тесты. Причем даже их есть два варианта. Первый — на "реальных" системах. Второй — на симуляторах этих внешних систем (может поддерживаться вашей командой). Симуляторы хороши тем, что:
Но симуляторы требуют дополнительных инвестиций в то, чтобы их было легко писать. И они тоже не панацея. Например, они не помогут, если ваши зависимости имеют тенденцию менять API несовместимым образом.

C>В данный момент 99% тестов это mocking API сервисов, к которым обращается тестируемый код, с последующей проверкой того, что функция была вызвана. По-мойму, это не просто пустая трата времени, а небольшая диверсия, потому что всем кажется, что код покрыт тестами, а на деле ничего не покрыто, и ломается на раз-два (происходит постоянно).

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

У вас ситуация сейчас отличная — система легко ломается. Вот с этого и нужно начинать. Есть что-нибудь общее между этими проблемами? Общая причина? Опечатки? Взаимодействие между командами? Разработчики забывают изменить код в одном из 10 мест при добавлении поля? Потенциальных причин — тысячи. Ваши данные стоит проанализировать и поискать пути. Вполне может оказаться, что у вас всего один-два критичных аспекта, которые относительно легко тестируются и закрывают 99% ваших типичных ошибок. А может вы увидите и другие решения. Например, изменить архитектуру/дизайн сервиса, чтобы уменьшить количество необходимых правок при изменении структуры сообщений. Или обсудить с командой пролемы и попросить уделять им больше внимания на ревью кода (или вообще переместить фокус этих ревью на ваши темы). QA — это не только тесты, это спектр мероприятий на всех этапах жизненного цикла.

Все примеры выше — гипотетические. Я не утверждаю, что для вас они релевантны, смотрите на вашу ситуацию. Если хотите, можете здесь описать, как именно ломается система и мы обсудим, как лучше это предотвращать.
Re: Тестирование middleware
От: rosencrantz США  
Дата: 07.11.21 15:45
Оценка: 6 (1) +1
Здравствуйте, cppguard, Вы писали:

C>Прошу прощения, если неправильно применяю второе слово, но по-другому не знаю, как описать код, с которым я работаю по работе в данный момент. Суть его в том, что дёргаются разные микросервисы, переливаются данные из пустого JSON в порожнее Thrift и обратно. Как тестировать такой код, когда не существует заглушек или тривиальных реализаций для зависимостей? В данный момент 99% тестов это mocking API сервисов, к которым обращается тестируемый код, с последующей проверкой того, что функция была вызвана. По-мойму, это не просто пустая трата времени, а небольшая диверсия, потому что всем кажется, что код покрыт тестами, а на деле ничего не покрыто, и ломается на раз-два (происходит постоянно). Лет 8 назад я работал на похожем проекте, но там всё было на JavaEE с инверсией зависимостей и обязательным написанием stub или no-op реализации для каждого интерфейса.


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

Есть классическая наркоманская практика, с которой я сталкивался уже много раз. Аппликейшн выставляет API, за которым стоит много работы с базой данных. Надо написать тесты. Берут, и на доступ к базе пишут моки. В итоге API покрывается на 100% тестами, тесты работают быстро, все счастливы. Ценность таких конечно тестов нулевая, плюс ещё оверхед на сопровождение и дописывание. Мне кажется у вас сейчас аналогичная ситуация.

Адекватный подход — перед запуском тестов поднять базу, развернуть в неё минимально необходимый датасет, и дальше тестировать честно работающую систему. Такие тесты работают медленно, но от них всегда очень крутой выхлоп. Т.е. в вашем случае мне кажется проблему надо решать не на вашем уровне, а выше — "стратегия тестирования всей этой системы".
Re[2]: Тестирование middleware
От: Sharov Россия  
Дата: 08.11.21 10:48
Оценка:
Здравствуйте, rosencrantz, Вы писали:

R>Есть классическая наркоманская практика, с которой я сталкивался уже много раз. Аппликейшн выставляет API, за которым стоит много работы с базой данных. Надо написать тесты. Берут, и на доступ к базе пишут моки. В итоге API покрывается на 100% тестами, тесты работают быстро, все счастливы. Ценность таких конечно тестов нулевая, плюс ещё оверхед на сопровождение и дописывание. Мне кажется у вас сейчас аналогичная ситуация.


Почему же нулевая? Как минимум изменение в бизнес логике отследить и отловить можно. Уже неплохо для юнит-тестов.

R>Адекватный подход — перед запуском тестов поднять базу, развернуть в неё минимально необходимый датасет, и дальше тестировать честно работающую систему. Такие тесты работают медленно, но от них всегда очень крутой выхлоп. Т.е. в вашем случае мне кажется проблему надо решать не на вашем уровне, а выше — "стратегия тестирования всей этой системы".


Согласен, но это уже интеграционные тесты, но в целом штука более мощная, т.к. приближена к боевым условиям.
Кодом людям нужно помогать!
Re[3]: Тестирование middleware
От: rosencrantz США  
Дата: 08.11.21 17:46
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, rosencrantz, Вы писали:


R>>Есть классическая наркоманская практика, с которой я сталкивался уже много раз. Аппликейшн выставляет API, за которым стоит много работы с базой данных. Надо написать тесты. Берут, и на доступ к базе пишут моки. В итоге API покрывается на 100% тестами, тесты работают быстро, все счастливы. Ценность таких конечно тестов нулевая, плюс ещё оверхед на сопровождение и дописывание. Мне кажется у вас сейчас аналогичная ситуация.


S>Почему же нулевая? Как минимум изменение в бизнес логике отследить и отловить можно. Уже неплохо для юнит-тестов.


Да, я плохо сформулировал "API, за которым стоит много работы с базой данных". Что пытался сказать:

1. Полтора ифа бизнес-логики (50% кода, 3% сложности)
2. Пара страшнючих запросов к базе (50% кода, 97% сложности)

Вменяемое тестирование — это когда покрывается не "код", а "сложность". Т.е. в примере выше думать надо в первую очередь про п.2, а не про п.1.

Если замокать п.2, то покрытие кода будет 50%, при этом покрытие сложности — всего 3%. Это дрянь, а не тестирование, и "изменения в бизнес-логике отследить можно" — это тот самый нулевой (трёхпроцентный) выхлоп.

R>>Адекватный подход — перед запуском тестов поднять базу, развернуть в неё минимально необходимый датасет, и дальше тестировать честно работающую систему. Такие тесты работают медленно, но от них всегда очень крутой выхлоп. Т.е. в вашем случае мне кажется проблему надо решать не на вашем уровне, а выше — "стратегия тестирования всей этой системы".


S>Согласен, но это уже интеграционные тесты, но в целом штука более мощная, т.к. приближена к боевым условиям.


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