разработка задачи ведётся одним разработчиком в отдельной ветке, где нет чужих изменений, где никто не обновляет версии языка.
Просто вы не разрабатывали мультиплатформенный продукт, который может быть установлен на различных, поддерживаемых разработчиком, окружениях. Я встречал кейсы, когда результат математической функции был различным в одной и той же версии языка установленной на разных ОС. И эта проблема была обнаружена благодаря написанным тестам и не ушла в прод.
Вы смешали все заблуждения и плохие практики в кучу и обвинили TDD во всех грехах. Просто потому, что не поняли концепции.
Да, юнит тесты нужны для тестирования кирпичиков. Лучше описать что мы хотим от кирпичика до того, как мы его слепили и обожгли и поставили в стену.
Да, из хороших кирпичиков можно собрать плохой дом. Но хороший дом проще создать из хороших кирпичиков.
Да, сами авторы идеи говорят, что нет смысла в 100% кода и оно только вредит.
Вы изменили поведение компонента и изменили тест. Все предельно логично. Не вижу никаких противоречий TDD. Новое поведение системы теперь покрыто тестами и задокументировано.
Если изменение поведения нежелательно, это должно "всплыть" на код-ревью. Измененные тесты помогут явно обозначить это и помочь ревьюверу выявить проблемное место.
Предположим, используя TDD и не покрывая код тестами вовсе, я напишу код приблизительно одного качества. Но как на счет остального жизненного цикла? Уверенности, что чужие изменения ничего не ломают. Какой-никакой документации поведения. Как быть уверенным (хоть в какой-то степени), что обновление версии языка программирования ничего не сломает. Дело не только в качестве написанного кода, но в большей степени в надежности, простоте поддержки и сопровождения.
Во-первых, в вашем примере вы начинаете реализацию класса не понимая какие у него зависимости и на каком уровне/слое он находится. Как раз тут TDD вам сигнализирует о том, что вы, возможно не достаточно продумали решение и не понимаете до конца что хотите получить.
Во-вторых, я не понимаю что тут ломает концепцию TDD. Нигде не встречал мнения, что тесты нельзя менять. В вашем примере вам придется поменять лишь инициализацию объекта, добавив мок в конструктор. Ассерты же останутся прежними. Если же возникает необходимость изменить ассетры, то мы снова возвращаемся к осознанию того, что вы не достаточно понимаете, что хотите получить в итоге. Вернитесь на шаг назад и подумаете еще раз.
Но разве зависимости не должны существовать до того, как разрабатывается зависимый компонент? Если вы начинаете разработку с низкоуровневых компонентов, то TDD тут не при чем.
Я не ярый адепт TDD и не холивара ради. Исключительно из личных наблюдений за 11 лет опыта в разработке:
Код, покрытый юинт тестами обычно имеет лучшую архитектуру, чем тот, который тестов не имеет
Делать изменения в покрытом тестами компоненте безопаснее
Если для класса сложно написать тест, обычно он является проблемным местом и является частью плохой архитектуры
Громоздкие тесты, которые сложно читаются и понимаются сигнализируют о проблеме в юнитах, которые они тестируют
Да, понятия хорошая/плохая архитектура очень широки, но для краткости позволю себе оставить их без пояснения.
На мой взгляд у вас искаженное понимание целей юнит-тестирования. Для решения проблем с многопоточностью, с сетью, с БД, как вы упомянули, используются другие подходы к тестированию.
Как уже упоминалось, без примера и без конкретного альтернативного решения это просто водичка.
Ну допустим, TDD — не лучшая практика. А что тогда делать? Не применять ее? Применять частично? Применять другую практику (ага, значит тогда другая практика является лучшей)?
А выводы, типа: нам нужно тщательно, больше, глубже поощрять открытость, разбираться и прекратить уже наконец, научиться, увидеть и отказаться — это как-то не убедительно.
Я из Беларуси, у нас тут по президентам тоже нулевая текучка. Ничего хорошего, знаете ли, сказать не могу.
Перефразируя — текучка в пределах разумного полезна и даже необходима.
Т.е. перетекание воздуха из одной комнаты в другую вы не учитываете?
Выходит в 3-х комнатной квартире (+ кухня) где живет 4 человека нужно 1280 м3/ч?
Судя по бегло нагугленной информации 1280 — это производительность вентиляции для большого коттеджа.
Спасибо за подробное описание. Собрали массу полезной информации в одном месте.
Не могли бы, пожалуйста, пояснить вот это момент:
на человека нужно 80 м3/ч воздухообмена для этого, а на нас двоих 160 м3/ч. Поэтому я рассматривал приточку на 350 м3/ч: по 160 м3/ч на комнату
Не понял принцип расчета. На сколько я понимаю, на человека нужно 80м3/ч. При чем тут количество комнат? Как количество выделяемого человеком CO2 зависит от количество помещений/площади?
Не могли бы вы несколько подробнее рассказать каким образом вы все это настроили? Хотелось бы проделать нечто подобное у себя. На мой взгляд отличная тема для отдельной статьи.
Для меня тесты — это не только показатель работоспособности кода, но и инструмент для написания более архитектурно грамотного, качественного кода. Следуя TDD проблемные места видны заранее, еще до того как был реализован класс.
По этой причине низкое покрытие тестами может быть сигналом о том, что присутствуют архитектурные проблемы. На практике я заметил, что практически всегда тот код, который нельзя/сложно протестировать — код низкого качества.
Поэтому я стараюсь достигать как можно больших значений CC, пытаясь не "читерить".
Простейшее решение — указать callback для Job'а, который запустит ваш код в независимом потоке, на удаленном worker сервере или где вам угодно с необходимыми вам Fault tolerance, Graceful degradation, обработкой "падений", бэкапами и прочим.
Обработка ошибок стороннего кода и "падений" сторонних сервисов — не область ответственности этой библиотеки.
Вы подали мне хорошую идею. В ближайшее время допишу тул для перевода из формата cron
в формат iCalendar.
Но использование стандарта iCalendar было одной из основных целей написания этой библиотеки. Он гораздо более гибкий и используется повсеместно для подобных целей.
У нас несколько разный взгляд на разработку ПО. Я полагаю, что fatal error и "обрушение" недопустимы, и закладывать их вероятность при разработке это дикость. Представьте строителей, которые закладывают вероятность обрушения потолка при строительстве: "а давайте его веревками к стропилам привяжем, вдруг обрушится" (хотя, кажется, теперь я знаю чем руководствуются разработчики Skype).
Если говорить об ожидаемых авариях, исключительных ситуациях (Exceptions), то JobRunner их ловит, являясь последним форпостом на пути брошенного Exception. Но не пойманные исключения тем приложением, которое их бросило — тоже отдельный вопрос, который также не лучшим образом характеризует качество кода. Я долго сомневался стоит ли вовсе ловить исключения, брошенные чужим кодом.
Что касается запуска двух копий, тут я с вами согласен. В некоторых обстоятельствах может возникнуть такая ситуация (хотя ее тоже можно обработать кодом, запускающим планировщик). Но у меня в планах реализовать параллельное выполнение нескольких JobRunner.
Что за троллинг с публикацией ссылок на код, который я не писал?
На странице моей библиотеки есть бэйджи со значениями покрытия и качества кода.
Советую ознакомиться с текстом статьи и все же с моим кодом, прежде чем оставлять комментарии.
Просто вы не разрабатывали мультиплатформенный продукт, который может быть установлен на различных, поддерживаемых разработчиком, окружениях. Я встречал кейсы, когда результат математической функции был различным в одной и той же версии языка установленной на разных ОС. И эта проблема была обнаружена благодаря написанным тестам и не ушла в прод.
Вы смешали все заблуждения и плохие практики в кучу и обвинили TDD во всех грехах. Просто потому, что не поняли концепции.
Да, юнит тесты нужны для тестирования кирпичиков. Лучше описать что мы хотим от кирпичика до того, как мы его слепили и обожгли и поставили в стену.
Да, из хороших кирпичиков можно собрать плохой дом. Но хороший дом проще создать из хороших кирпичиков.
Да, сами авторы идеи говорят, что нет смысла в 100% кода и оно только вредит.
Вы изменили поведение компонента и изменили тест. Все предельно логично. Не вижу никаких противоречий TDD. Новое поведение системы теперь покрыто тестами и задокументировано.
Если изменение поведения нежелательно, это должно "всплыть" на код-ревью. Измененные тесты помогут явно обозначить это и помочь ревьюверу выявить проблемное место.
Соглашусь. Но тут, как и везде, нужен баланс. Иногда практичнее писать до, иногда после.
Как обычно, проблема не в методологии, а в фанатиках.
"Рефакторинг - процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения"
Предположим, используя TDD и не покрывая код тестами вовсе, я напишу код приблизительно одного качества. Но как на счет остального жизненного цикла? Уверенности, что чужие изменения ничего не ломают. Какой-никакой документации поведения. Как быть уверенным (хоть в какой-то степени), что обновление версии языка программирования ничего не сломает. Дело не только в качестве написанного кода, но в большей степени в надежности, простоте поддержки и сопровождения.
Во-первых, в вашем примере вы начинаете реализацию класса не понимая какие у него зависимости и на каком уровне/слое он находится. Как раз тут TDD вам сигнализирует о том, что вы, возможно не достаточно продумали решение и не понимаете до конца что хотите получить.
Во-вторых, я не понимаю что тут ломает концепцию TDD. Нигде не встречал мнения, что тесты нельзя менять. В вашем примере вам придется поменять лишь инициализацию объекта, добавив мок в конструктор. Ассерты же останутся прежними. Если же возникает необходимость изменить ассетры, то мы снова возвращаемся к осознанию того, что вы не достаточно понимаете, что хотите получить в итоге. Вернитесь на шаг назад и подумаете еще раз.
Но разве зависимости не должны существовать до того, как разрабатывается зависимый компонент? Если вы начинаете разработку с низкоуровневых компонентов, то TDD тут не при чем.
Я не ярый адепт TDD и не холивара ради. Исключительно из личных наблюдений за 11 лет опыта в разработке:
Код, покрытый юинт тестами обычно имеет лучшую архитектуру, чем тот, который тестов не имеет
Делать изменения в покрытом тестами компоненте безопаснее
Если для класса сложно написать тест, обычно он является проблемным местом и является частью плохой архитектуры
Громоздкие тесты, которые сложно читаются и понимаются сигнализируют о проблеме в юнитах, которые они тестируют
Да, понятия хорошая/плохая архитектура очень широки, но для краткости позволю себе оставить их без пояснения.
На мой взгляд у вас искаженное понимание целей юнит-тестирования. Для решения проблем с многопоточностью, с сетью, с БД, как вы упомянули, используются другие подходы к тестированию.
Будет больше мотивации давать понятные, человекочитаемые имена функциям и переменным. Как завещал дядюшка Боб.
Как уже упоминалось, без примера и без конкретного альтернативного решения это просто водичка.
Ну допустим, TDD — не лучшая практика. А что тогда делать? Не применять ее? Применять частично? Применять другую практику (ага, значит тогда другая практика является лучшей)?
А выводы, типа: нам нужно тщательно, больше, глубже поощрять открытость, разбираться и прекратить уже наконец, научиться, увидеть и отказаться — это как-то не убедительно.
Я из Беларуси, у нас тут по президентам тоже нулевая текучка. Ничего хорошего, знаете ли, сказать не могу.
Перефразируя — текучка в пределах разумного полезна и даже необходима.
Т.е. перетекание воздуха из одной комнаты в другую вы не учитываете?
Выходит в 3-х комнатной квартире (+ кухня) где живет 4 человека нужно 1280 м3/ч?
Судя по бегло нагугленной информации 1280 — это производительность вентиляции для большого коттеджа.
Спасибо за подробное описание. Собрали массу полезной информации в одном месте.
Не могли бы, пожалуйста, пояснить вот это момент:
Не понял принцип расчета. На сколько я понимаю, на человека нужно 80м3/ч. При чем тут количество комнат? Как количество выделяемого человеком CO2 зависит от количество помещений/площади?
Не могли бы вы несколько подробнее рассказать каким образом вы все это настроили? Хотелось бы проделать нечто подобное у себя. На мой взгляд отличная тема для отдельной статьи.
Для меня тесты — это не только показатель работоспособности кода, но и инструмент для написания более архитектурно грамотного, качественного кода. Следуя TDD проблемные места видны заранее, еще до того как был реализован класс.
По этой причине низкое покрытие тестами может быть сигналом о том, что присутствуют архитектурные проблемы. На практике я заметил, что практически всегда тот код, который нельзя/сложно протестировать — код низкого качества.
Поэтому я стараюсь достигать как можно больших значений CC, пытаясь не "читерить".
Я понимаю о чем вы. Возможно я добавлю другую реализацию
ActionInterface, которая будет запускать задачу в отдельном процессе.Простейшее решение — указать callback для Job'а, который запустит ваш код в независимом потоке, на удаленном worker сервере или где вам угодно с необходимыми вам Fault tolerance, Graceful degradation, обработкой "падений", бэкапами и прочим.
Обработка ошибок стороннего кода и "падений" сторонних сервисов — не область ответственности этой библиотеки.
Вы подали мне хорошую идею. В ближайшее время допишу тул для перевода из формата cron
в формат iCalendar.
Но использование стандарта iCalendar было одной из основных целей написания этой библиотеки. Он гораздо более гибкий и используется повсеместно для подобных целей.
У нас несколько разный взгляд на разработку ПО. Я полагаю, что fatal error и "обрушение" недопустимы, и закладывать их вероятность при разработке это дикость. Представьте строителей, которые закладывают вероятность обрушения потолка при строительстве: "а давайте его веревками к стропилам привяжем, вдруг обрушится" (хотя, кажется, теперь я знаю чем руководствуются разработчики Skype).
Если говорить об ожидаемых авариях, исключительных ситуациях (Exceptions), то JobRunner их ловит, являясь последним форпостом на пути брошенного Exception. Но не пойманные исключения тем приложением, которое их бросило — тоже отдельный вопрос, который также не лучшим образом характеризует качество кода. Я долго сомневался стоит ли вовсе ловить исключения, брошенные чужим кодом.
Что касается запуска двух копий, тут я с вами согласен. В некоторых обстоятельствах может возникнуть такая ситуация (хотя ее тоже можно обработать кодом, запускающим планировщик). Но у меня в планах реализовать параллельное выполнение нескольких JobRunner.
Что за троллинг с публикацией ссылок на код, который я не писал?
На странице моей библиотеки есть бэйджи со значениями покрытия и качества кода.
Советую ознакомиться с текстом статьи и все же с моим кодом, прежде чем оставлять комментарии.