Я работаю в небольшой компании в качестве индивидуального разработчика. На самом деле я единственный разработчик в компании. У меня есть несколько (относительно) крупных проектов, которые я написал и регулярно поддерживаю, и ни у одного из них нет тестов для их поддержки. Когда я начинаю новые проекты, я часто задаюсь вопросом, стоит ли мне попробовать подход TDD. Это звучит как хорошая идея, но я, честно говоря, никогда не смогу оправдать дополнительную работу.
Я усердно работаю, чтобы быть дальновидным в своем дизайне. Я понимаю, что, безусловно, однажды другому разработчику придется поддерживать мой код или, по крайней мере, устранять его. Я держу вещи настолько простыми, насколько это возможно, и я комментирую и документирую вещи, которые будет трудно понять. И дело в том, что эти проекты не настолько велики или сложны, что достойному разработчику будет сложно их понять.
Многие примеры тестов, которые я видел, доходят до мелочей, охватывающих все аспекты кода. Поскольку я единственный разработчик, и я очень близок к коду во всем проекте, гораздо эффективнее следовать шаблону «запись-потом-проверка вручную». Я также нахожу, что требования и функции меняются достаточно часто, так что поддержание тестов добавит значительного сопротивления проекту. Время, которое могло бы быть потрачено на решение бизнес-задач.
Так что я получаю один и тот же вывод каждый раз. Возврат инвестиций слишком низок.
Иногда я настраивал несколько тестов, чтобы убедиться, что я правильно написал алгоритм, например, подсчет количества лет, проведенных в компании, на основе даты их найма. Но с точки зрения покрытия кода я покрыл около 1% своего кода.
В моей ситуации, вы все равно найдете способ сделать модульное тестирование регулярной практикой, или я оправдан, чтобы избежать этих накладных расходов?
ОБНОВЛЕНИЕ: Несколько вещей о моей ситуации, которые я пропустил: все мои проекты - это веб-приложения. Чтобы покрыть весь мой код, я должен был бы использовать автоматизированные тесты пользовательского интерфейса, и это область, в которой я до сих пор не вижу большого преимущества по сравнению с ручным тестированием.
источник
Ответы:
Так? Вам не нужно проверять все . Просто актуальные вещи.
Это на самом деле неверно. Это не более эффективно. Это действительно просто привычка.
То, что делают другие разработчики соло, - это написать эскиз или схему, написать контрольные примеры, а затем заполнить схему окончательным кодом.
Это очень, очень эффективно.
Это тоже ложь. Тесты не являются тормозом. Изменения требований - перетаскивание.
Вы должны исправить тесты, чтобы отразить требования. Будь то их мелочи или высокого уровня; написано первым или написано последним.
Код не готов, пока тесты не пройдут. Это одна универсальная правда программного обеспечения.
Вы можете пройти ограниченный приемочный тест «вот оно».
Или вы можете пройти несколько юнит-тестов.
Или вы можете иметь оба.
Но независимо от того, что вы делаете, всегда есть тест, чтобы продемонстрировать, что программное обеспечение работает.
Я бы предположил, что небольшая формальность и хороший набор инструментов для модульного тестирования делают этот тест намного более полезным.
источник
sqrt(-1)
должно ли быть целое число, вы получите ошеломляющие ответы, склоняющиеся в одну сторону. Баланс вокруг «как» и «какой порядок». Сам факт, что вы должны проверить. Поэтому сначала напишите тесты и убедитесь, что они работают.Представьте, что у вас был набор тестов, которые могли бы выполняться с привязкой к глазу и зажечь зеленый или красный свет. Представьте, что этот набор тестов проверил все ! Представьте, что все, что вам нужно было сделать для запуска набора тестов, это набрать ^ T. Какую силу это даст вам?
Можете ли вы внести изменения в код, не боясь что-то сломать? Не могли бы вы добавить новую функцию, не боясь сломать старую функцию? Не могли бы вы быстро убрать грязный код, не боясь нанести ущерб?
Да, вы могли бы сделать все эти вещи! А что будет с вашим кодом со временем? Это будет становиться все чище и чище, потому что не будет никакого риска для его очистки.
Давайте представим, что у вас на плече была маленькая фея. Каждый раз, когда вы писали строку кода, фея добавляла что-то в набор тестов, который проверял, что эта строка кода выполняет то, для чего она предназначена. Таким образом, каждые несколько секунд вы можете нажать ^ T и увидеть, что последняя строка кода, которую вы написали, работает.
Как вы думаете, сколько отладки вы бы сделали?
Если это звучит как фантазия, вы правы. Но реальность не сильно отличается. Замените связку глаз несколькими секундами, а фею - дисциплиной TDD, и вы в значительной степени поняли это.
Допустим, вы возвращаетесь к системе, которую вы построили год назад, и вы забыли, как создать один из центральных объектов. Существуют тесты, которые создают этот объект любым способом, которым он может быть создан. Вы можете прочитать эти тесты и пробежаться по памяти. Нужно вызвать API? Существуют тесты, которые вызывают этот API во всех отношениях. Эти тесты - небольшие документы , написанные на понятном вам языке. Они абсолютно однозначны. Они настолько формальны, что их казнят. И они не могут выйти из синхронизации с приложением!
Не стоит вложений? Ты наверное шутишь! Как кто-то может НЕ хотеть этот набор тестов? Сделай себе одолжение и прекрати придираться к глупости. Научитесь хорошо выполнять TDD и наблюдайте, насколько быстрее вы идете и насколько чище ваш код.
источник
Ошибка, которую вы совершаете, заключается в том, что вы рассматриваете тестирование как временную инвестицию без немедленной отдачи. Это не обязательно так работает.
Во-первых, написание тестов действительно фокусирует вас на том, что должна делать эта часть вашего кода.
Во-вторых, при их запуске выявляются ошибки, которые в противном случае могли бы появиться при тестировании.
В-третьих, их запуск иногда выявляет ошибки, которые в противном случае не возникали бы при тестировании, а затем действительно кусали бы вас в задницу на производстве.
В-четвертых, если вы столкнетесь с ошибкой в работающей системе и создадите для нее модульный тест, вы не сможете повторно представить эту ошибку позже. Это может быть действительно большой помощью. Повторно введенные ошибки являются общими и очень раздражающими.
В-пятых, если вам когда-нибудь понадобится передать код кому-то другому, набор тестов значительно облегчит их жизнь. Кроме того, если вы проигнорировали проект и вернулись к нему через несколько лет, вы больше не будете так близки к нему, и он будет вам полезен.
Мой опыт неизменно заключался в том, что при разработке проекта наличие достойных модульных тестов всегда делало процесс более быстрым и надежным.
источник
У парней из JUnit (фреймворк Java Unit test) есть философия, что если тестирование слишком простое, не тестируйте его . Я настоятельно рекомендую прочитать их часто задаваемые вопросы , так как это довольно прагматично.
TDD - это другой процесс написания вашего программного обеспечения. Основная предпосылка модульного тестирования заключается в том, что вы будете тратить меньше времени на отладчик, шагая по коду, и быстрее выяснять, не произойдет ли изменение кода случайно в системе. Это вписывается в TDD. Цикл TDD выглядит так:
Что менее очевидно в применении TDD, так это то, что он меняет способ написания кода . Заставляя себя думать о том, как тестировать / проверять работоспособность кода, вы пишете тестируемый код. И поскольку мы говорим о модульном тестировании, это обычно означает, что ваш код становится более модульным. Для меня модульный и тестируемый код - это большая победа.
Теперь вам нужно протестировать такие вещи, как свойства C #? Представьте себе свойство, определенное так:
Ответ будет «нет», его не стоит тестировать, потому что в этот момент вы тестируете языковой компонент. Просто верьте, что ребята на платформе C # поняли это правильно. Кроме того, если это не удалось, то , что может вам сделать , чтобы это исправить?
Кроме того, вы обнаружите, что в вашем коде есть определенные части, которые будут слишком трудоемкими для правильного тестирования. Это означает, что не делайте этого, но убедитесь, что вы тестируете код, который использует / используется сложной задачей:
Верьте или нет, TDD поможет вам войти в устойчивый темп развития. Это не из-за магии, а из-за того, что у вас плотная петля обратной связи, и вы можете быстро уловить действительно глупые ошибки. Стоимость исправления этих ошибок по существу постоянна (по крайней мере, достаточно для целей планирования), потому что маленькие ошибки никогда не вырастают в большие ошибки. Сравните это с бурной природой спринтов по очистке binge / debug.
источник
Вы должны сбалансировать стоимость тестирования со стоимостью ошибок.
Написание 10-строчного модульного теста для функции, открывающей файл, где ошибка «файл не найден», не имеет смысла.
Функция, которая делает что-то сложное со сложной структурой данных - тогда, очевидно, да.
Хитрый бит между ними. Но помните, что реальная ценность модульных тестов заключается не в тестировании конкретной функции, а в тестировании сложных взаимодействий между ними. Таким образом, модульный тест, который обнаруживает, что изменение одного бита кода, нарушает некоторые функции в другом модуле на расстоянии 1000 строк, стоит своего веса в кофе.
источник
Тестирование - это азартная игра.
Создание теста - это ставка на то, что стоимость ошибок в модуле, возникающих и не фиксирующих их в этом тесте (сейчас и во всех будущих версиях кода), больше стоимости разработки теста. Эти затраты на разработку тестов включают в себя такие вещи, как начисление заработной платы за разработку дополнительных тестов, добавленное время выхода на рынок, издержки упущенных возможностей из-за отсутствия кодирования других вещей и т. Д.
Как и любая ставка, иногда вы выигрываете, иногда вы проигрываете.
Иногда запоздалое программное обеспечение с гораздо меньшим количеством ошибок побеждает быстрее, но с ошибками, которые выходят на рынок первыми. Иногда наоборот. Вы должны посмотреть на статистику в вашей конкретной области, и сколько руководство хочет играть.
Некоторые типы ошибок могут быть настолько маловероятными или делать это из каких-либо ранних проверок работоспособности, что статистически не стоит времени для создания дополнительных специальных тестов. Но иногда цена ошибки настолько велика (медицинская, ядерная и т. Д.), Что компании приходится делать проигрышную ставку (подобно покупке страховки). Многие приложения не имеют такой высокой стоимости отказов, и поэтому не нуждаются в более высоком неэкономичном страховом покрытии. Другие делают.
источник
Мой совет - проверять только тот код, который вы хотите работать правильно.
Не проверяйте код, который, по вашему мнению, должен содержать ошибки и создавать проблемы для вас в будущем.
источник
TDD и модульное тестирование - это не одно и то же.
Вы можете написать код, а затем добавить модульные тесты позже. Это не TDD, а много дополнительной работы.
TDD - это практика кодирования в петле красного света. Зеленый свет. Рефакторинг итераций.
Это означает написание тестов для кода, который еще не существует, наблюдение за ошибками тестов, исправление кода, чтобы тесты работали, а затем исправление кода. Это часто экономит вашу работу
Одним из преимуществ TDD является то, что он уменьшает необходимость думать о мелочах. Такие вещи, как ошибочные ошибки, исчезают. Вам не нужно искать документацию по API, чтобы узнать, начинается ли возвращаемый список с 0 или 1, просто сделайте это.
источник
Я работал над системой, где мы тестировали почти все. Примечательными выполнениями для тестирования были выходной код PDF и XLS.
Почему? Мы смогли протестировать части, которые собирали данные, и построили модель, которая использовалась для создания выходных данных. Мы также смогли протестировать части, которые выяснили, какие части модели будут добавлены в PDF-файлы. Мы не смогли проверить, выглядел ли PDF нормально, потому что это было абсолютно субъективно. Мы не смогли проверить, что все части в PDF были доступны для чтения обычному пользователю, потому что это было также субъективно. Или если выбор между гистограммой и круговой диаграммой был правильным для набора данных.
Если результат будет субъективным, вы можете выполнить то, что стоит затраченных усилий, с помощью небольшого модульного тестирования.
источник
Для многих вещей «написать-то-вручную-тест» занимает не больше времени, чем написание пары тестов. Экономия времени достигается за счет возможности повторного запуска этих тестов в любое время.
Подумайте об этом: если у вас есть приличное покрытие функций вашими тестами (не путать с покрытием кода), и, скажем, у вас есть 10 функций - нажатие кнопки означает, что вы имеете примерно 10, вы снова делаете свои тесты ... пока вы сидите и пьете свой кофе.
Вам также не нужно проверять мелочи. Вы можете написать интеграционные тесты, которые охватывают ваши функции, если вы не хотите вдаваться в подробности ... IMO, некоторые модульные тесты слишком детализируют тестирование языка и платформы, а не кода.
TL; DR Это действительно никогда не уместно, потому что преимущества слишком хороши.
источник
Здесь есть два очень хороших ответа:
Основания для избежания воспринимаемых накладных расходов:
Вы не хотели бы оставить отличный продукт со своей стороны в качестве доказательства качества своей работы? Если говорить эгоистично, разве тебе не лучше, что ты делаешь?
источник
Профессиональные разработчики пишут модульные тесты, потому что в долгосрочной перспективе они экономят время. Вы будете тестировать свой код рано или поздно, и если вы этого не сделаете, ваши пользователи будут делать это, и если вам придется исправлять ошибки позже, их будет труднее исправить, и у вас будет больше эффектов.
Если вы пишете код без тестов и у вас нет ошибок, хорошо. Я не верю, что вы можете написать нетривиальную систему с нулевыми ошибками, поэтому я предполагаю, что вы тестируете ее так или иначе.
Модульные тесты также важны для предотвращения регрессии при изменении или рефакторинге старого кода. Они не доказывают, что ваши изменения не сломали старый код, но придают вам большую уверенность (если, конечно, они пройдут :))
Я бы не стал возвращаться и писать целую серию тестов для кода, который вы уже отправили, но в следующий раз, когда вам понадобится изменить функцию, я бы предложил попробовать написать тесты для этого модуля или класса, чтобы получить покрытие до 70%. + прежде чем применять какие-либо изменения. Посмотрите, поможет ли это вам.
Если вы попробуете это и сможете честно сказать, что это не помогло, то достаточно справедливо, но я думаю, что есть достаточно отраслевых доказательств того, что они помогут сделать это, по крайней мере, того стоило, пока вы испытываете подход.
источник
Кажется, что большинство ответов про-TDD, хотя вопрос был не о TDD, а о модульных тестах в целом.
Не существует абсолютно объективного правила, что проводить модульное тестирование или нет. Но есть пара случаев, когда многие программисты не проводят модульное тестирование:
В зависимости от вашей философии ООП вы можете создавать частные методы для отделения сложных процедур от ваших открытых методов. Публичные методы обычно предназначены для вызова во многих разных местах и часто используются, а частные методы действительно вызываются только одним или двумя открытыми методами в классе или модуле для чего-то очень специфического. Обычно достаточно написать модульные тесты для общедоступных методов, но не базовые частные методы, которые заставляют некоторые чудеса происходить. Если что-то пойдет не так с закрытым методом, ваши общедоступные методы должны быть достаточно хорошими, чтобы обнаружить эти проблемы.
Многие новые программисты идут против этого, когда впервые учатся тестировать, и думают, что им нужно тестировать каждую выполняемую строку. Если вы используете внешнюю библиотеку и ее функциональные возможности хорошо протестированы и задокументированы ее авторами, обычно бессмысленно тестировать конкретную функциональность в модульных тестах. Например, кто-то может написать тест, чтобы убедиться, что его модель ActiveRecord сохраняет правильное значение для атрибута с обратным вызовом before_save в базу данных, даже если само это поведение уже тщательно протестировано в Rails. Методы, которые вызывает обратный вызов, возможно, но не само поведение обратного вызова. Любые основные проблемы с импортированными библиотеками лучше выявить с помощью приемочных тестов, а не модульных тестов.
Оба из них могут применяться независимо от того, используете ли вы TDD или нет.
источник
Кен, я и многие другие разработчики пришли к тому же выводу, что и вы, несколько раз в течение нашей карьеры.
Я полагаю, что правда (как и многие другие) вы найдете в том, что первоначальные затраты на написание тестов для вашего приложения могут показаться пугающими, но если они написаны правильно и нацелены на правильные части вашего кода, они действительно могут сэкономить массу времени.
Моя большая проблема была с доступными структурами тестирования. Я никогда не чувствовал, что они были тем, что я искал, поэтому я просто нашел свое очень простое решение. Это действительно помогло мне приблизиться к «темной стороне» регрессионного тестирования. Я поделюсь основным псевдо-фрагментом того, что я сделал здесь, и, надеюсь, вы сможете найти решение, которое подойдет вам.
Единственная сложность после этого - выяснить, какой уровень детализации, по вашему мнению, является наилучшим «ударом для доллара» для любого проекта, который вы делаете.
Создание адресной книги, безусловно, потребует гораздо меньшего количества тестирования, чем поисковая система предприятия, но основные принципы не меняются.
Удачи!
источник