Size: a a a

2020 May 05

VM

Vladislav Milenin in Go-go!
Мерль🛠
Это те же самые принты, только автоматические
суть в том что логи и тесты писать итак придется, а дебаггер можно обойти стороной
источник

М

Мерль🛠 in Go-go!
Daniel Podolsky
вот я бы поленился щелкать руками и смотреть глазами, а навставлял бы логов, и написал бы тестов, которые бы проверяли корректность
И потом, я знаю из паления тестов, что алгоритм некорректен

Мне интересно посмотреть в кишки и понять почему именно алгоритм некорректен. И вот дебаг просто рулит и бибикает
источник

М

Мерль🛠 in Go-go!
Vladislav Milenin
суть в том что логи и тесты писать итак придется, а дебаггер можно обойти стороной
Логи в тестах полезны, я их использую, но:

1.  Не всегда понятно куда их втыкать
2. Их не всегда удобно воткнуть – стандартная библиотека и сторонние пакеты например
источник

VM

Vladislav Milenin in Go-go!
Мерль🛠
Логи в тестах полезны, я их использую, но:

1.  Не всегда понятно куда их втыкать
2. Их не всегда удобно воткнуть – стандартная библиотека и сторонние пакеты например
ну про сторонние либы скажу одно, у меня никогда с ними проблем не было. Бывало форкали и допиливали под свои нужды, но таких кейсов парочка за несколько лет

а куда втыкать всегда понятно. На логические развязки в коде
источник

М

Мерль🛠 in Go-go!
Мерль🛠
Логи в тестах полезны, я их использую, но:

1.  Не всегда понятно куда их втыкать
2. Их не всегда удобно воткнуть – стандартная библиотека и сторонние пакеты например
Да, дебаггер не обязателен, но очень очень удобен
источник

AK

Anton Kucherov in Go-go!
Мимо Проходящий
"Если тестируемая функция не чистая и зависимости в ней не замоканы, это интеграционный тест." - это вообще не тест а чёрт знает что. Я естественно о чистых функциях говорю, а не о тех, которые принимают интерфейсы. вроде бы уже уточнял
Почему это не тест а черти знает что? Если говорить о чистых функциях. Детерминированные функции тоже могут содержать в себе вызовы других детерминированных функций. И если вы их не мокаете, а тестируете их все неявно через вызов какой-то одной, это и есть интеграционный тест, потому что вы не изолировали функцию, вы просто дергаете половину мира и смотрите что она вернет. А вся суть юнит-тестов в изоляции.
источник

M

Max in Go-go!
Мимо Проходящий
"Если тестируемая функция не чистая и зависимости в ней не замоканы, это интеграционный тест." - это вообще не тест а чёрт знает что. Я естественно о чистых функциях говорю, а не о тех, которые принимают интерфейсы. вроде бы уже уточнял
Почему "черт знает что"? Это тестирование взаимодействия нескольких сущностей. Т.е., интеграционный тест.
источник

М

Мерль🛠 in Go-go!
Vladislav Milenin
ну про сторонние либы скажу одно, у меня никогда с ними проблем не было. Бывало форкали и допиливали под свои нужды, но таких кейсов парочка за несколько лет

а куда втыкать всегда понятно. На логические развязки в коде
Представь что у тебя конкурентная логика и очень много ветвлений

Сколько времени ты будешь вставлять логи? По хорошему надо делать отдельную инфраструру для дебаг режима – это нормально и правильно для бизнес логики, но если логика пакета не предполагает io, то это становится просто усложнением кода, которое 90% времени не используется
источник

DP

Daniel Podolsky in Go-go!
Мерль🛠
Представь что у тебя конкурентная логика и очень много ветвлений

Сколько времени ты будешь вставлять логи? По хорошему надо делать отдельную инфраструру для дебаг режима – это нормально и правильно для бизнес логики, но если логика пакета не предполагает io, то это становится просто усложнением кода, которое 90% времени не используется
но мне же все равно нужен тест, который покроет все варианты, и всем проверит корректность.

так что логи случатся сами собой
источник

М

Мерль🛠 in Go-go!
Daniel Podolsky
но мне же все равно нужен тест, который покроет все варианты, и всем проверит корректность.

так что логи случатся сами собой
Тест нужен и должен покрывать как можно больше комбинаций ветвлений

Но покрыть все нужные места логами – это совсем другой коленкор и может быть нетривиальной задачей
источник

М

Мерль🛠 in Go-go!
Для покрытия ветвлений тебе надо управлять входными данными тестами
источник

VM

Vladislav Milenin in Go-go!
Мерль🛠
Представь что у тебя конкурентная логика и очень много ветвлений

Сколько времени ты будешь вставлять логи? По хорошему надо делать отдельную инфраструру для дебаг режима – это нормально и правильно для бизнес логики, но если логика пакета не предполагает io, то это становится просто усложнением кода, которое 90% времени не используется
я поддерживаю log-driven development, у меня почти нет тестов (это херово, но речь о петпроджекте, на который времени не 40ч в неделю за зп)

начали с 1000 строк кода, уже под 20к, логи понатыканы везде где нужно через zap и обертки

как используем? Пишет юзер, что у него что-то пошло не так, мы берем userId и находим его сессии, далее по сессиям все что происходило и где оборвалось
что логгируем? user/session айди, входные данные, результаты обработки — в итоге всегда легко воспроизводится в любых окружениях, порой с планшета видно как и что 🙂 Ну и конечно prometheus/postgres метрики чтобы глобально что-то видеть и анализировать
источник

DP

Daniel Podolsky in Go-go!
не-не-не

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

вариант “давайте отладим, а тесты не будем писать” я не рассматриваю
источник

M

Max in Go-go!
Мерль🛠
Тест нужен и должен покрывать как можно больше комбинаций ветвлений

Но покрыть все нужные места логами – это совсем другой коленкор и может быть нетривиальной задачей
Кажется, "нужные" места имеет смысл покрывать логами во время кодинга, а не после.
источник

DP

Daniel Podolsky in Go-go!
впрочем - мне все ясно :)

я не люблю отладку, и потому не пользуюсь отладчиком

те, кто любят отладку - пользуются
источник

VM

Vladislav Milenin in Go-go!
Vladislav Milenin
я поддерживаю log-driven development, у меня почти нет тестов (это херово, но речь о петпроджекте, на который времени не 40ч в неделю за зп)

начали с 1000 строк кода, уже под 20к, логи понатыканы везде где нужно через zap и обертки

как используем? Пишет юзер, что у него что-то пошло не так, мы берем userId и находим его сессии, далее по сессиям все что происходило и где оборвалось
что логгируем? user/session айди, входные данные, результаты обработки — в итоге всегда легко воспроизводится в любых окружениях, порой с планшета видно как и что 🙂 Ну и конечно prometheus/postgres метрики чтобы глобально что-то видеть и анализировать
в итоге как-то и без дебаггера и тестов без багов неделями по 30-150 рпс держится и ок
источник

МП

Мимо Проходящий... in Go-go!
Anton Kucherov
Почему это не тест а черти знает что? Если говорить о чистых функциях. Детерминированные функции тоже могут содержать в себе вызовы других детерминированных функций. И если вы их не мокаете, а тестируете их все неявно через вызов какой-то одной, это и есть интеграционный тест, потому что вы не изолировали функцию, вы просто дергаете половину мира и смотрите что она вернет. А вся суть юнит-тестов в изоляции.
нет, они по определению чистой функции не являются "зависимостями". Нужно ли тестировать более низкоуровневые чистые функции, вызываемые более высокоуровневой, зависит от требуемой степени детализации. Теоретически можно написать тесты для всех функции, иногда достаточно для одной - если quick check показал её правильность, то из этого следует правильность и всех зависимых
источник

М

Мерль🛠 in Go-go!
Мерль🛠
Для покрытия ветвлений тебе надо управлять входными данными тестами
Для покрытия логами нужно пройтись по каждому пути и ветвлению

Если используются сторонние библиотеки – это становится очень однообразной работой с низким качеством выхлопа
источник

МП

Мимо Проходящий... in Go-go!
Daniel Podolsky
я недавно писал рейт-лимитер, и тестил, и все, что мне было нужно - это замокать net.Conn
а можно на это посмотреть?
источник

DP

Daniel Podolsky in Go-go!
Мимо Проходящий
а можно на это посмотреть?
источник