Как стать автором
Обновить
12
0.1
Павел @WieRuindl

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

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

а, ну если ссылки являются аргументами, то вот: https://www.piter.com/product/printsipy-yunit-testirovaniya

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

Проверяются только те кейсы, на которые вы не забыли написать тест.

Чтобы что-то делалось, нужно это сначала сделать, это довольно очевидно. А минусы где?

Именно юнит-тесты в этом слабо помогают. Поэтому им и нужны подпорки в виде других типов тестов.

unit-тесты - не панацея, и автор ни разу не сказал, что надо писать только их

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

Один раз накликать в браузере, может быть, и проще. Кликать весь функционал со всеми его инвариантами каждый раз после добавления/изменения куска кода - и близко не проще и не быстрее

А когда эти моки нужно ещё и без конца переписывать - это совсем утомительно.

Если код нормальный, и тест нормальный, то не придется ничего переписывать. Если на каждый чих надо переписывать, то это сигнал, то код - говно

Хороший рефакторинг меняет в том числе и контракты

Голословно

Чем чаще эта лампочка кричит "волки", тем реже на неё вообще обращают внимание.

Рекомендую почитать, что такое "хрупкие тесты", и почему это плохо, и почему надо писать нормальные тесты

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

Повторюсь, если тесты ломаются от каждого чиха, то это плохие тесты

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

Зависеть от порядка выполнения тестов - это, я даже не знаю, довольно занятное извращение, но так себе практика для проекта

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

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

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

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

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

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

Глупости, дядя, - это не использовать инструменты и методолгии, которые повышают качество работы и защищают от ошибок, а вместо диалога по существу докапываться до слов

ты действительно решил не ответить по существу, а докопаться до отсутствия слова "unit"?

Так а что мне показать? Как паттерном "стратегия" пользоваться вместо кучи приватных методов? Как избегать классов с 20ю внутренними филдами? Что методы с 10 возможными результатами - это плохо? Это всё идеи, которые лежат на поверхности, но на которые очень легко забить в процессе работы. Написание теста же сразу подсвечивает такие места. Да фиг с ним с тестом, его можно и не писать по итогу, но если ты в процессе работы думаешь над тем, что код должен быть тестируемым, то ты сразу думаешь над тем, как сделать нормально, а не тяп-ляп и в прод

Я вот абсолютно искренне не понимаю людей, которые не пишут тестов. Есть возможность делать хорошо, но они осознанно выбирают делать плохо. Зачем? Нафига? Очень много вопросов и так мало ответов

Если любое изменение приводит к падению тестов, то это плохие тесты. Не концепт плохой, а конкретная реализация. На хороший код тесты пишутся легко и приятно

Да нет, все правильно там написано. Я вообще не понимаю, как заниматься какими-либо изменениями в коде, если нет unit-тестов, это ж чистые слабоумие и отвага. Ну, если только звонки в 5 утра с криками, что прод упал, доставляют удовольствие и добавляют радости в жизни...

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

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

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

Моя практика показывает, что очень многие просто не умеют в ООП. Ну, то есть они выучили всякие ключевые слова типа class, interface, extends/implements и так далее, и даже на теоретические вопросы типа "что означает буква D в принципах SOLID" умеют отвечать, но реально в ООП стиле не умеют ни думать, ни кодить. А это ключевой момент, как оказывается. То, что код обмазан ключевыми словами, не делает его автоматически ООП, и все те крутые возможности, которые парадигма могла бы дать, просто теряются. И при этом эти люди, что удивительно, и чего я не могу никак понять, искренне убеждены, что они используют ООП, а на попытки показать, что можно лучше/проще/понятнее/etc. реагируют достаточно негативно

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

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

по барабану какой там у вас код

Мне не по барабану. Я люблю делать свою работу качественно, а не тяп-ляп, и пушим в прод, лишь бы работало

В проекте важны дедлайны

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

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

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

  1. Ну, допустим, можно ускорить, тут согласен

  2. Я не хочу дебажить тесты. Я хочу, чтобы тест мне ясно сообщал, в чем проблема, и что я сломал. Тесты должны упрощать жизнь, а не привносить в неё новые сложности

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

  1. Любой тест всегда можно удалить, если он мешает, и это нормально. Задача теста - не быть вечно, а защищать от случайного изменения логики там, где она не должна меняться. Требования бизнеса могут быть запутанными, но, блин, а мы кто тогда? Просто code monkey, которым что сказали, то они и пишут, прям в лоб и без никаких оптимизаций и структуры? Или все-таки у нас есть какие-то знания, умения и квалификации, как и выполнять запутанные требования, и писать при этом нормальный код

  2. Изменение существующий логики должно приводить к падению теста - это его задача. Добавление новой логики не должно проводить к падению тестов, потому что они за новую логику никак не отвечают. Иначе, опять же, где-то наговнокодили: либо в самом коде, либо в тестах

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

  4. А что плохого в том, чтобы рефакторить отдельные методы? Особенно если в угоду спешке написали что-то, лишь бы работало, а на оптимизации пока что забили. Это как раз более чем валидный кейс. Можно написать за 5 минут логику какого-нибудь полного перебора, и двигаться дальше, а если именно это место начнёт бить по перформансу, то именно это место и изменить. Можно, конечно с самого начала расчехлить свои умения с leetcode, и целый рабочий день фигачить какие-то алгоритмы, но как раз именно это может быть пустой потерей времени, если окажется, что этод метод вызывается раз в день, например

  5. Ну так напиши ещё один тест на всю фичу целиком, в чем проблема-то?

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

Однако нет ни одной удобоваримой теории как правильно писать тесты

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

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

на каждый метод по 20 тестов на каждый инвариант использования

Ну, во-первых, не обязательно писать прям на каждый метод. Важно покрывать тестами те методы, которые объявлены в интерфейсе и торчат наружу. Приватные методы и даже саму структуру класса тоже можно покрывать тестами, и у этого тоже есть свои преимущества, но все-таки основная задача - это убедиться, что внешний код, который и вызывает этот класс, получает правильные результаты, а не просто писать тесты ради самого процесса написания тестов. А насчёт 20- и инвариантов - ну, тут дело уже плохо. Даже не просто плохо, это ужасно. Не должно быть у метода 20 результатов, ну просто не должно быть. И, кстати, если исходить как раз из того, что на такой метод должен быть тест, проверяющий все выходы, то и самому человеку, который этот код написал, станет ясно, что это ужас, и, возможно, ему таки придёт в голову, что так оставлять дела нельзя, и надо придумать какое-то более осмысленное решение, лучшую структуру, привнести паттерн какой-нибудь - как раз ради того, чтобы тест не выглядел как разросшееся бесформенное нечто

Внутри меняйте и двигайте код как угодно

Вот внутри и получаются методы с 20 выходами, и прочая хтонь

зацементировать юнит тестами

Unit-тесты - это инструмент. Ребёнок с молотком видит вокруг лишь гвозди, но это не вина молотка, верно? Любой инструмент можно использовать и во благо, и во вред

Внутри меняйте и двигайте код как угодно

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

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

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

Плавали в таком, больше плавать не хотим

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

  1. Билд занимал минут по 15

  2. Если что-то где-то меняешь, и что-то где-то ломаешь, то вместо того, чтобы получить четкую ошибку, что, где и почему сломалась, получаешь в консоли HTTP 500, и удачи тебе дебажить весь процесс в попытке найти ошибку

  3. Ну и код в проекте был полное говно, что тоже частично следствие отсутствия unit-тестов

Интеграционные тесты должны быть, с этим я не спорю. Но они никоим образом не заменяют unit-тесты, которые тоже должны быть:

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

  • Если на любой чих в коде проходится менять тест, то это тоже сразу сигнал, что где-то что-то не в порядке: либо сам тест хреновый, либо, опять же, код - говно

  • Unit-тесты сами по себе являются документацией к коду. Ты сразу видишь, что и как должно работать

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

  • С помощью unit-тестов я могу заглянуть в любое место выполнения программы и посмотреть, что и как там работает. А также как угодно изменять условия и смотреть на изменения результата. Интеграционные тесты такой возможности не дают в принципе

Ну и вообще в статье правильно все описано: у unit-тестов и интеграционных тестов разные цели, и заменят первые вторыми - это крайне сомнительная затея

Информация

В рейтинге
3 442-й
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность