Java Developer
  • Разработчик-тестировщик, оправдано ли?

    Я нигде не упоминал про TDD.
    Есть две крайности: либо сложные методы вообще без тестов, либо «открытые» классы без инкапсуляции с хрупкими тестами.

    Что делать? Боюсь, буду банален — есть удачные рецепты в шаблонах проектирования.

  • Разработчик-тестировщик, оправдано ли?

    Я понимаю ваше возмущение.

    Вот есть сложный метод, поэтому на него нет теста.
    Говорите, его надо разбить на части? Окей, а как?

    Шаблоны проектирования? Ну, на калькуляторах и туду-листах все эти фабрики и стратегии понятны. А в реальном проекте как быть?

    Много общих слов, и мало конкретики? Так я пытался свои слова конкретикой подкрепить.

    1. Нет теста? — сигнал, что плохой метод.
    2. В чём причина? — на мой взгляд, в new Date() в теле метода.
    3. Как исправить? — не создавать объект внутри, передавать его извне.
    4. Что дальше? — продолжаем изучать ООП.

    Вот потом можно и подумать о юнит-тесте,

    Уже отвечал.

    Я нигде не говорил, что нужно написать или не написать тест на этот метод. Но всячески подчёркивал, что кмк полезно задумываться, как же его тестировать.
  • Разработчик-тестировщик, оправдано ли?

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

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

    Если не возражаете, чтобы не повторяться dou.ua/…​ign=reply-comment#1095064

    А стремление распространить практику тестирования на всё — убивает все остальные задачи, переводя ресурсы на бюрократию.

    На мой взгляд, если практика тестирования «убивает» — это сигнал о плохом коде, а не о бюрократии.

  • Разработчик-тестировщик, оправдано ли?

    Извините, объясняю на пальцах.

    Есть метод, он что-то делает. Например, отправляет поздравления на НГ. Теста на него нет, потому что непонятно, как задачу разбить на классы и методы.

    Поэтому она проверяет ручным тестированием с переводом даты на машине разработчика.

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

    Может через год она и отработает нормально. А может и нет.

    Если вы умеете добавлять/изменять/развивать код, гарантируя сохранность старого функционала, так и скажите.

  • Разработчик-тестировщик, оправдано ли?

    Поэтому я повторюсь.

    Заранее усложнять код под будущие изменения — плохо, а если даже не писать тесты, но думать о них — хорошо.

  • Разработчик-тестировщик, оправдано ли?

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

  • Разработчик-тестировщик, оправдано ли?

    Я ожидал такого ответа.

    Во-первых, вы правы — ручное (ну или автоматическое) тестирование действительно превыше всего.

    И если юнит- и интеграционных тестов нет, то только оно и остаётся. А оно довольно медленное и дорогое.

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

  • Разработчик-тестировщик, оправдано ли?

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

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

  • Разработчик-тестировщик, оправдано ли?

    Окей, а вы что предлагаете: подождать до Нового года и посмотреть сработает или не сработает?

  • Разработчик-тестировщик, оправдано ли?

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

    Далее, я считаю, что хорошая архитектура и покрытие тестами — это не противоположные направления, а одно.

    юнит-тест — вовсе не обязательно что он проверяет все возможные сценарии поломки

    Мне кажется, что цели юнит-теста такие:
    1) даже не написанным позитивно влиять на архитектуру. Если ветвлений нет, возможно логгирования будет достаточно;
    2) зафиксировать для регрессии/возможного будущего рефакторинга positive flow;
    3) в случае рисков и/или багов добавлять negative flows;

  • Разработчик-тестировщик, оправдано ли?

    Коллега, ну мы же программисты всё таки. Давайте не будем «колбасить», пожалуйста.
    Посмотрите в сторону Parameterized, если уж есть необходимость проверять интерфейс на большом количестве значений.

  • Разработчик-тестировщик, оправдано ли?

    Ну, насчёт «лучше баг» — не могу согласиться. Или можно с НГ и в другой день поздравить, пользователи перебьются? :-) У нас, например, релизное окно — раз в два месяца, поэтому «быстренько подфиксить на проде» не работает.

    И, главное, как быть с сопровождением кода?

    Пример выше — вообще не про баг, а иллюстрация проблемы,

    что в теле метода создаётся новый объект, что практически перечёркивает возможность его тестирования, а не потому что времени не было или заказчик не заплатил.
  • Разработчик-тестировщик, оправдано ли?

    Извините, я вас плохо понимаю.

    Попробую сказать иначе: реализацию крайне выгодно держать доступной не по имени, не по пути к файлам, не по логике вызовов. А просто в том месте, где её будут искать. И ограничить исключительно этим местом.

    Есть класс/интерфейс, есть его реализация, одна или несколько. Вы о каком поиске?

    То же самое с тестами. Они должны быть написаны и находиться именно в том месте, где они будут понятны.

    Опять же, есть конвенция: имя класса Foo, имя теста — FooTest. В том же пакете.

    Если же для понимания теста нужно понимать код — это ПЛОХОЙ тест

    А может это плохой код? Тест должен писаться просто — AAA или GWT. Если это невозможно, имхо, проблема в сложном методе.

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

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

    И самый правильный способ это сделать — напрямую. Задача «а как потом это тестировать» потребует абстракции, такой чтобы и точка взятия, и точка куда ложить — была доступна извне, и понятно что это и как.

    А вот тут не согласен. И пытался продемонстрировать на примере с датой. Вы, если я правильно понял, призываете писать понятно, читаемо и без багов :-) Но не говорите, как этого достичь. А я предлагаю критерий, следуя которому, как мне кажется, улучшается компоновка. Сравните

    public void congrats() {
        Date today = new Date();
        if (today.getMonth() == 1 && today.getDay() == 1) {
            System.out.println("Happy New Year!");
         }
    }
    

    и

    @AllArgsConstructor
    class Congrats {
        private final Date date;
    
        public String toString() {
            if (date.getMonth() == 1 && date.getDay() == 1) {
                return "Happy New Year!";
             }
             return "";
        }
    }
    
    ...
    
    System.out.println(new Congrats(new Date()));
    

    Да, кода стало на пару строчек больше, и то, спасибо Lombok-у, а то Java не особо лаконична.
    Да, баг всё ещё присутствует, но когда на него наткнутся, понятно, как написать тест, исправить, и быть уверенным в исправлении.
    Да, на первый взгляд проще «напрямую», но тогда нет ни в чём уверенности, кроме как в полной регрессии на каждый чих.

    В местах разрыва или естественных абстракций — сущности легко объяснимы. А вот чтобы объяснить доступ к неочевидным временным частям целого объекта в неочевидной стадии — нужно очень постараться.

    Если не затруднит, может пример кода? Не могу понять, о чём идёт речь. Вы про инкапсуляцию, композицию и иммутабельность?

  • Разработчик-тестировщик, оправдано ли?

    Попробую объяснить. Если для структуры написан «индусский» тест на сеттеры-геттеры, а на «процедуры» тестов нет, потому что слишком сложно, или тесты с копи-пастой сетапа, ЗНАНИЯМИ о коде и прочими страшными вещами, перечислеными выше...

    ... то не в тестах проблема. Вернее, она, естественно, есть, но это следствие и симптом того, что

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

    Я выше приводил пример с датой и поздравлением с Новым годом. Даже в таком коротком и простом коде ошибка, на мой взгляд, из-за создания нового объекта — даты — в теле метода.

    Поддержал: Vadim Kopanev
  • Разработчик-тестировщик, оправдано ли?

    Вы тоже ужасы рассказываете, хотя, не буду отрицать, я с ними знаком :-)

    Код, код нужно писать так, чтобы

    Arrange-Act-Assert не особо выходил за рамки трёх строчек.

    Если большой/сложный/с ответвлениями/повторяющийся сетап — это в коде проблема, метод слишком сложный. Это всё должно один раз тестироваться, а не повторяться для разных тестов.

    Поддержал: Vadim Kopanev
  • Разработчик-тестировщик, оправдано ли?

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

    Главная проблема в сигнатуре метода, компоновке класса, а меньшая — что реализация подкачала.

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

    Поэтому я ещё раз повторюсь

    Даже если просто держать в уме «а как я этот метод буду тестировать?» — это уже очень сильно помогает.
  • Разработчик-тестировщик, оправдано ли?

    Вы какие-то странные вещи говорите.

    То есть чтобы протестить, нужно ЗНАТЬ код. А чтобы поменять код — нужно ЗНАТЬ тест,

    Если это так — это плохой признак. Сигнал о сложном методе, для тестирования которого нужны mocks == знания о том, что происходит внутри.

    Тесты — такой же код. И при их написании говнокод фактически считается «хорошей практикой».

    Зачем же так?

  • Разработчик-тестировщик, оправдано ли?

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

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

  • Разработчик-тестировщик, оправдано ли?

    Не согласен по форме — «кодерки», «забить болт», но согласен по сути — если код скомпонован правильно и есть логгирование, то очевидные тесты можно и не писать.

    Поддержал: Oleg Zarevych
  • Разработчик-тестировщик, оправдано ли?

    Мне кажется, что все эти разговоры, что нет времени, денег, тестировщиков, одобрения заказчика etc писать тесты — это симптомы. Тесты не пишутся, потому что их слишком сложно или вообще невозможно написать. А причина — плохая компоновка кода. Даже если просто держать в уме «а как я этот метод буду тестировать?» — это уже очень сильно помогает. И Arrange-Act-Assert не должен особо выходить за рамки трёх строчек.

    Если это не так, то не с тестом проблема, а сигнал, что код плохой.

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

    public void congrats() {
        Date today = new Date();
        if (today.getMonth() == 1 && today.getDay() == 1) {
            System.out.println("Happy New Year!");
         }
    }
    

    Здесь ошибка. И она не в том, что не использован Calendar, а в том, что непонятно, как этот метод протестировать. И если исправлять баг, то, опять же, нет уверенности, что исправление верное. Главная проблема в сигнатуре метода, компоновке класса, а меньшая — что реализация подкачала.

← Сtrl 1... 45678...12 Ctrl →