откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 17:01
Оценка: +5 -1
В чем смысл использовать тесты с моками вместо интеграционных тестов? При условии что интеграционные тесты возможны в данном случае, естественно.
Если ты написал интеграционные тесты — ты полностью уверен, что данный конкретный сценарий работает. Если ты написал тест с моками — может быть работает, может нет, хрен его знает.
Я чего-то не понимаю?
Ад пуст, все бесы здесь.
Re: откуда такая любовь к мокам?
От: scf  
Дата: 17.02.22 17:22
Оценка: 1 (1) +7
Здравствуйте, Codealot, Вы писали:

C>В чем смысл использовать тесты с моками вместо интеграционных тестов? При условии что интеграционные тесты возможны в данном случае, естественно.

C>Если ты написал интеграционные тесты — ты полностью уверен, что данный конкретный сценарий работает. Если ты написал тест с моками — может быть работает, может нет, хрен его знает.
C>Я чего-то не понимаю?

Безотносительно способа реализации (моки, стабы, фейки), есть три соображения: скорость работы тестов, сложность подготовки тестовых данных, параллелизация тестов
Re: откуда такая любовь к мокам?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.02.22 17:50
Оценка: 6 (3) +12
Здравствуйте, Codealot, Вы писали:

C>В чем смысл использовать тесты с моками вместо интеграционных тестов? При условии что интеграционные тесты возможны в данном случае, естественно.

C>Если ты написал интеграционные тесты — ты полностью уверен, что данный конкретный сценарий работает.

Нет. Потому что
1) С реальным внешним компонентом ты не проверишь все возможные (предполагаемые) варианты ответа другого компонента. Часто их слишком сложно смоделировать с реальным компонентом.
2) Продолжение предыдущего — если компонент участвует некорректно. Например, что делать, если сервер ответил разрушенной структурой данных.
3) Могут быть взаимоскомпенсированные ошибки (см. фольклор про чётность числа багов). Они взорвутся позже, тогда, когда ты уже забыл, что это было, как и почему (или вообще не ты писал и тайное знание давно потеряно).
The God is real, unless declared integer.
Re[2]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 18:22
Оценка: +3
Здравствуйте, netch80, Вы писали:

N>Нет. Потому что

N>1) С реальным внешним компонентом ты не проверишь все возможные (предполагаемые) варианты ответа другого компонента. Часто их слишком сложно смоделировать с реальным компонентом.

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

N>2) Продолжение предыдущего — если компонент участвует некорректно. Например, что делать, если сервер ответил разрушенной структурой данных.


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

N>3) Могут быть взаимоскомпенсированные ошибки (см. фольклор про чётность числа багов). Они взорвутся позже, тогда, когда ты уже забыл, что это было, как и почему (или вообще не ты писал и тайное знание давно потеряно).


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

В общем и целом — использование моков может иметь некоторый смысл как дополнение интеграционных тестов, но ни в коем случае как их замена. См исходный вопрос.
Ад пуст, все бесы здесь.
Отредактировано 17.02.2022 18:27 Codealot . Предыдущая версия . Еще …
Отредактировано 17.02.2022 18:24 Codealot . Предыдущая версия .
Re: откуда такая любовь к мокам?
От: vsb Казахстан  
Дата: 17.02.22 18:32
Оценка: +3
Здравствуйте, Codealot, Вы писали:

C>В чем смысл использовать тесты с моками вместо интеграционных тестов? При условии что интеграционные тесты возможны в данном случае, естественно.

C>Если ты написал интеграционные тесты — ты полностью уверен, что данный конкретный сценарий работает. Если ты написал тест с моками — может быть работает, может нет, хрен его знает.
C>Я чего-то не понимаю?

Скорость выполнения. У меня интеграционный тест запускается секунд 10 (поднимается в докере БД, стартует спринг, создаётся схема, данные), далее каждый тест выполняется около 1 секунды.

С моками юнит-тест выполняется микросекунды. То бишь гораздо проще тестировать весь функционал в юнит-тестах. А функциональные тесты на самые основные сценарии, просто чтобы проверить, что ничего в целом не сломалось.
Re[2]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 18:34
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Скорость выполнения. У меня интеграционный тест запускается секунд 10 (поднимается в докере БД, стартует спринг, создаётся схема, данные), далее каждый тест выполняется около 1 секунды.


vsb>С моками юнит-тест выполняется микросекунды. То бишь гораздо проще тестировать весь функционал в юнит-тестах. А функциональные тесты на самые основные сценарии, просто чтобы проверить, что ничего в целом не сломалось.


А затраты времени на создание моков и работу с усложненным кодом не учитываются?
Ад пуст, все бесы здесь.
Re[3]: откуда такая любовь к мокам?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.02.22 18:36
Оценка: +3 -1
Здравствуйте, Codealot, Вы писали:

N>>Нет. Потому что

N>>1) С реальным внешним компонентом ты не проверишь все возможные (предполагаемые) варианты ответа другого компонента. Часто их слишком сложно смоделировать с реальным компонентом.

C>Да. Потому что ты абсолютно точно уверен, что те сценарии которые ты протестировал — реально работают.


Но ты не знаешь, _почему_ они работают. Чаще всего без покомпонентного тестирования это случайный успех, ничем не подтверждённый, который перестанет работать при малейшем отклонении от предполагаемых входных данных.

C> А в случае с моками ты всегда тестируешь частично реальный код, а частично — моки, в которых тоже могут быть ошибки или различия с реальным кодом.


Мок предельно примитивен по сравнению с реальным компонентом. Для большинства случаев это фигня, которая принимает запрос, сверяет его с эталоном в нужных местах и отдаёт фиксированный ответ. Чем проще мок, тем прямее тестирование. Такой простой мок покрывает >95% вариантов тестов (для большинства применений >99%).

N>>2) Продолжение предыдущего — если компонент участвует некорректно. Например, что делать, если сервер ответил разрушенной структурой данных.

C>Значит, клиент поймает эту ошибку. Или выдаст некорректный результат, который будет пойман тестом.

Нет, он выдаст корректный, потому что просто заложен выдавать такое.

N>>3) Могут быть взаимоскомпенсированные ошибки (см. фольклор про чётность числа багов). Они взорвутся позже, тогда, когда ты уже забыл, что это было, как и почему (или вообще не ты писал и тайное знание давно потеряно).


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


Повторюсь: мок делается предельно простым, чтобы вероятность ошибок в нём уменьшить до предела. Например, мок может на любой HTTP запрос отвечать фиксированным {'x':1, 'y':2}.

Посмотри на питоновский unittest.mock. Он не идеал (по-нормальному управляющие методы надо было бы вынести в отдельный объект), но на нём можно написать в духе

m = Mock()
m.foo.return_value = 44

и всё что надо — любой вызов m.foo() отдаст 44.
Зато в управляющем коде теста потом пишешь

m.foo.assert_called_with(22, 2)

и если не так — получаешь исключение.

Что может быть проще, прямолинейнее и понятнее?
The God is real, unless declared integer.
Re[3]: откуда такая любовь к мокам?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.02.22 18:38
Оценка:
Здравствуйте, Codealot, Вы писали:

vsb>>С моками юнит-тест выполняется микросекунды. То бишь гораздо проще тестировать весь функционал в юнит-тестах. А функциональные тесты на самые основные сценарии, просто чтобы проверить, что ничего в целом не сломалось.


C>А затраты времени на создание моков и работу с усложненным кодом не учитываются?


Затраты времени минимальны.
"Усложнённый код" — отчего бы? В каком домене такое?
The God is real, unless declared integer.
Re: откуда такая любовь к мокам?
От: Слава  
Дата: 17.02.22 18:41
Оценка: 2 (1) +1
Здравствуйте, Codealot, Вы писали:

C>Я чего-то не понимаю?


Моки — это тестирование алгоритмов внутри вашего собственного сервиса. То есть, как ваш код обрабатывает данные снаружи, здесь эти данные берутся из моков.

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

*"...анализ бизнес-процессов показал, что бизнес-процессов по факту нет!" ((с) "Внедряй!", известный ролик на ютубе)
внедряй
Re[4]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 18:43
Оценка: :))
Здравствуйте, netch80, Вы писали:

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


Если в твоем коде такое происходит, то ты делаешь что-то очень сильно неправильно.

N>Мок предельно примитивен по сравнению с реальным компонентом. Для большинства случаев это фигня, которая принимает запрос, сверяет его с эталоном в нужных местах и отдаёт фиксированный ответ. Чем проще мок, тем прямее тестирование. Такой простой мок покрывает >95% вариантов тестов (для большинства применений >99%).


Такой код создает иллюзию для выполнения >95% вариантов тестов

N>Нет, он выдаст корректный, потому что просто заложен выдавать такое.


Щито? Клиент выдает то, что получил от сервера. То есть — некорректный результат.

N>Повторюсь: мок делается предельно простым, чтобы вероятность ошибок в нём уменьшить до предела. Например, мок может на любой HTTP запрос отвечать фиксированным {'x':1, 'y':2}.


Именно. А реальный код может выдать что-то куда сложнее. И что толку тогда от твоих моков?

N>Что может быть проще, прямолинейнее и понятнее?


И бесполезнее.
Ад пуст, все бесы здесь.
Re[4]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 18:45
Оценка:
Здравствуйте, netch80, Вы писали:

N>Затраты времени минимальны.

N>"Усложнённый код" — отчего бы? В каком домене такое?

Ни хрена они не минимальны. Как минимум надо делать моки и следить за тем, чтобы обновлять их вместе с реальным кодом. Лишняя точка поломки.
Ну а если ты пишешь на C#/Java/тп, то придется еще городить лишние интерфейсы для классов.
Ад пуст, все бесы здесь.
Re[2]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 18:46
Оценка:
Здравствуйте, Слава, Вы писали:

С>Моки — это тестирование алгоритмов внутри вашего собственного сервиса.


Чтобы тестировать алгоритмы (если они нормально спроектированы), никакие моки вообще не нужны.
Ад пуст, все бесы здесь.
Re[3]: откуда такая любовь к мокам?
От: vsb Казахстан  
Дата: 17.02.22 18:59
Оценка:
Здравствуйте, Codealot, Вы писали:

vsb>>Скорость выполнения. У меня интеграционный тест запускается секунд 10 (поднимается в докере БД, стартует спринг, создаётся схема, данные), далее каждый тест выполняется около 1 секунды.


vsb>>С моками юнит-тест выполняется микросекунды. То бишь гораздо проще тестировать весь функционал в юнит-тестах. А функциональные тесты на самые основные сценарии, просто чтобы проверить, что ничего в целом не сломалось.


C>А затраты времени на создание моков и работу с усложненным кодом не учитываются?


Это ещё надо посмотреть, что сложней, создавать мок, который на нужные методы выплюнет нужный ответ или вставлять данные в БД, согласно схеме и констрейнтам.
Re[3]: откуда такая любовь к мокам?
От: baxton_ulf США  
Дата: 17.02.22 19:00
Оценка: +1
Здравствуйте, Codealot, Вы писали:


С>>Моки — это тестирование алгоритмов внутри вашего собственного сервиса.


C>Чтобы тестировать алгоритмы (если они нормально спроектированы), никакие моки вообще не нужны.


думаю он имел ввиду тестирование как работает внутренняя логика при разных комбинациях на входе = параметры + значения возвращаемые моками.
да создание юнит-тестов может занять больше времени чем написание самой логики, но это делать надо обязательно
Re[5]: откуда такая любовь к мокам?
От: vsb Казахстан  
Дата: 17.02.22 19:01
Оценка: +1
Здравствуйте, Codealot, Вы писали:

N>>Затраты времени минимальны.

N>>"Усложнённый код" — отчего бы? В каком домене такое?

C>Ни хрена они не минимальны. Как минимум надо делать моки и следить за тем, чтобы обновлять их вместе с реальным кодом. Лишняя точка поломки.

C>Ну а если ты пишешь на C#/Java/тп, то придется еще городить лишние интерфейсы для классов.

Не знаю, что там в C#. В Java Mockito прекрасно мокирует классы без всяких интерфейсов. И ничего делать не надо. У тебя кажется какой-то допотопный взгляд на моки, где надо интерфейс выделять, писать полноценную реализацию этого интерфейса, имитирующую реальный объект. Современные инструменты этого всего позволяют не делать.

// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);

// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

// the following prints "first"
System.out.println(mockedList.get(0));

// the following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
Отредактировано 17.02.2022 19:02 vsb . Предыдущая версия .
Re[6]: откуда такая любовь к мокам?
От: Слава  
Дата: 17.02.22 19:02
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Не знаю, что там в C#. В Java Mockito прекрасно мокирует классы без всяких интерфейсов. И ничего делать не надо. У тебя кажется какой-то допотопный взгляд на моки, где надо интерфейс выделять, писать полноценную реализацию этого интерфейса, имитирующую реальный объект. Современные инструменты этого всего позволяют не делать.


По-моему, это особая магия в JVM, я не уверен, что CLR так умеет.
Re[6]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 19:03
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>У тебя кажется какой-то допотопный взгляд на моки, где надо интерфейс выделять


Не у меня, а у того, кто наколбасил проект, на который я прямо сейчас гляжу.

vsb>писать полноценную реализацию этого интерфейса, имитирующую реальный объект. Современные инструменты этого всего позволяют не делать.


Может, они еще и думают за тебя?
Ад пуст, все бесы здесь.
Re[7]: откуда такая любовь к мокам?
От: Codealot Земля  
Дата: 17.02.22 19:04
Оценка:
Здравствуйте, Слава, Вы писали:

С>По-моему, это особая магия в JVM, я не уверен, что CLR так умеет.


В теории вполне можно сделать при помощи IL rewriting и других методов, но мне о таких инструментах неизвестно.
Ад пуст, все бесы здесь.
Re[7]: откуда такая любовь к мокам?
От: vsb Казахстан  
Дата: 17.02.22 19:21
Оценка:
Здравствуйте, Слава, Вы писали:

vsb>>Не знаю, что там в C#. В Java Mockito прекрасно мокирует классы без всяких интерфейсов. И ничего делать не надо. У тебя кажется какой-то допотопный взгляд на моки, где надо интерфейс выделять, писать полноценную реализацию этого интерфейса, имитирующую реальный объект. Современные инструменты этого всего позволяют не делать.


С>По-моему, это особая магия в JVM, я не уверен, что CLR так умеет.


Просто создаётся наследник класса, у него переопределяются все методы и всё. Ну магия там, конечно, есть, но для других вещей.
Re[8]: откуда такая любовь к мокам?
От: Слава  
Дата: 17.02.22 19:29
Оценка:
Здравствуйте, vsb, Вы писали:

С>>По-моему, это особая магия в JVM, я не уверен, что CLR так умеет.


vsb>Просто создаётся наследник класса, у него переопределяются все методы и всё. Ну магия там, конечно, есть, но для других вещей.


Так если методы не виртуальные, то вызываться будут методы предка.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.