Я новый программист (учусь только около года), и в своей цели стать лучше, я только недавно узнал о TDD. Я хотел привыкнуть к нему, потому что это кажется очень полезным. Я хотел проверить и убедиться, что я использую это правильно.
Что я делаю:
- Подумайте о новом методе, который мне нужен.
- Создайте тест для этого метода.
- Неудачный тест.
- Напишите метод.
- Пройдите тест.
- Рефакторинг метод.
- Повторение.
Я делаю это для КАЖДОГО метода, который я пишу, есть ли некоторые, с которыми мне не стоит беспокоиться? Позже я обычно думаю о способе тестирования уже существующих методов другим способом или ситуацией. Должен ли я сделать эти новые тесты, о которых я думаю, или, поскольку у каждого метода уже есть свой тест, не стоит ли мне беспокоиться? Могу ли я НАБЛЮДАТЬ за тестирование своего кода? Думаю, это моя главная задача, чтобы спросить об этом
РЕДАКТИРОВАТЬ
Кроме того, это было то, что мне просто интересно. При выполнении чего-то вроде создания графического интерфейса, TDD будет необходимо в этой ситуации? Лично я не могу придумать, как написать для этого тесты.
Ответы:
То, что вы описываете как рабочий процесс, на мой взгляд, не дух TDD.
Синопсис книги Кента Бекса об Амазонке гласит:
Практический TDD
Формальное автоматическое тестирование, особенно модульное тестирование, каждый метод каждого класса так же плох как антишаблон и ничего не тестирует. Есть баланс, который нужно иметь. Вы пишете юнит-тесты для каждого
setXXX/getXXX
метода, это тоже методы!Кроме того, тесты могут помочь сэкономить время и деньги, но не забывайте, что они требуют времени и денег на разработку, и они являются кодом, поэтому они требуют времени и денег на сопровождение. Если они атрофируются из-за нехватки обслуживания, они становятся пассивом больше чем выгодой.
Как и все, как это, есть баланс, который не может быть определен кем-либо, кроме вас самих. Любая догма в любом случае, вероятно, более неправильная, чем правильная.
Хорошей метрикой является код, критически важный для бизнес-логики и подверженный частым изменениям в зависимости от меняющихся требований. Эти вещи нуждаются в формальных тестах, которые будут автоматизированы, что будет большой отдачей от инвестиций.
Вам будет очень трудно найти много профессиональных магазинов, которые работают таким же образом. Просто не имеет смысла тратить деньги на тестирование вещей, которые для практических целей никогда не изменятся после проведения простого теста на дым. Написание формальных автоматизированных модульных тестов для
.getXXX/.setXXX
методов является ярким примером этого, полной траты времени.Смотрите также этот ответ .
источник
setXXX/getXXX
вообще не нужно :)Ты очень близко. Попробуйте думать немного иначе.
Не создавайте автоматически методы получения и установки для каждого свойства . Не думайте о полном методе и напишите тест (ы), чтобы охватить все функции . Попробуйте инкапсулировать свойства внутри класса и напишите методы, чтобы обеспечить необходимое поведение. Пусть ваши методы превратятся в хороший дизайн вместо того, чтобы пытаться планировать их заранее. Помните, что TDD - это процесс проектирования, а не процесс тестирования. Преимущество, которое он имеет перед другими процессами проектирования, заключается в том, что он оставляет позади поток автоматизированных регрессионных тестов, а не кусок бумаги, который вы выбрасываете в корзину.
Кроме того, помните три правила дяди Боба TDD .
источник
Несколько вещей, чтобы добавить к ответам других:
Существует такая вещь, как чрезмерное тестирование. Вы хотите, чтобы ваши юнит-тесты перекрывались как можно меньше. Нет смысла иметь несколько тестов для проверки одинаковых условий в одном и том же фрагменте кода. С другой стороны, когда вы реорганизуете свой рабочий код и у вас есть много тестов, которые перекрывают этот раздел, вам придется вернуться и исправить все эти тесты. Принимая во внимание, что если они не перекрываются, то одно изменение в лучшем случае нарушит только один тест.
Только потому, что вы подумали о лучшем способе написания теста, я не вернусь туда и не начну его переписывать. Это относится к людям, которые продолжают писать и переписывать один и тот же класс / функцию, потому что они пытаются сделать его идеальным. Это никогда не будет идеально, так что двигайтесь дальше. Когда вы найдете лучший метод, держите его в голове (или добавьте в комментарии к тесту). В следующий раз, когда вы окажетесь там, и вы сразу увидите выгоду от перехода на новый путь, это время для рефакторинга. В противном случае, если функция завершена, и вы перешли, и все работает, оставьте его работающим.
TDD фокусируется на обеспечении немедленной ценности, а не просто на проверке каждой функции. Когда вы добавляете функциональность, начните с вопроса «что нужно клиенту». Затем определите интерфейс, чтобы дать клиенту то, что ему нужно. Затем выполните все, что нужно, чтобы пройти тест. TDD почти как тестирование сценариев сценариев использования (включая все «что-если»), а не просто кодирование открытых функций и тестирование каждого из них.
Вы спрашивали о тестировании кода GUI. Посмотрите шаблоны «Скромный диалог» и «MVVM». Идея, лежащая в основе обоих, заключается в том, что вы создаете набор классов «модели представления», которые на самом деле не имеют специфичной для пользовательского интерфейса логики. Однако эти классы будут иметь всю бизнес-логику, которая обычно является частью вашего пользовательского интерфейса, и эти классы должны быть на 100% тестируемыми. Остаётся очень тонкая оболочка пользовательского интерфейса и, да, обычно эта оболочка остается без тестового покрытия, но в этот момент у нее почти не должно быть логики.
Если у вас есть большая часть существующего кода, как предлагали немногие, не стоит начинать добавлять модульные тесты абсолютно везде. Это займет у вас вечность, и вы не получите выгоды от добавления модульных тестов в 80% классов, которые стабильны и не изменятся в ближайшем (или не очень) будущем. Однако, для новой работы, я считаю использование разработки TDD со ВСЕМ кодом чрезвычайно полезным. Когда вы закончите, вы получите не только комплект автоматизированных тестов, но и реальная разработка имеет огромные преимущества:
источник
Есть некоторые методы, которые не тестируются, а именно эти тесты. Тем не менее, есть кое-что, что нужно сказать о некоторых тестах, добавляемых после написания исходного кода, таких как граничные условия и другие значения, так что может быть несколько тестов для одного метода.
Хотя вы можете перепроверять свой код, обычно это происходит, когда кто-то хочет проверить каждую возможную перестановку входных данных, что не совсем похоже на то, что вы делаете. Например, если у вас есть метод, который принимает символ, вы пишете тест для каждого возможного значения, которое можно ввести? Это было бы то место, где вы бы переоценили, ИМО.
источник
Как правило, вы делаете это правильно.
Тесты кодовые. Так что, если вы можете улучшить тест, сделайте его рефакторинг. Если вы считаете, что тест можно улучшить, смените его. Не бойтесь заменить тест на более качественный.
Я рекомендую при тестировании вашего кода избегать указания того, как код должен делать то, что он делает. Тесты должны смотреть на результаты методов. Это поможет с рефакторингом. Некоторые методы не требуют явного тестирования (т. Е. Простые методы получения и установки), поскольку вы будете использовать их для проверки результатов других тестов.
источник
Мое мнение о TDD заключается в том, что инструментальные средства создали мир разработчиков стиля «наведи и щелкни». То, что инструменты создают заглушку для каждого метода, не означает, что вы должны писать тесты для каждого метода. Некоторые люди «переименовывают» TDD в BDD (развитие, основанное на поведении), где тесты гораздо более детализированы и предназначены для проверки поведения класса, а не каждого из них.
Если вы разрабатываете свои тесты для тестирования класса как предназначенного для использования, тогда вы начинаете получать некоторые преимущества, особенно когда вы начинаете писать тесты, которые выполняют немного больше, чем каждый метод, особенно когда вы начинаете тестировать взаимодействие этих классов. методы. Я полагаю, вы могли бы думать об этом как о написании тестов для класса, а не как методов. В любом случае вы все равно должны написать «приемочные тесты», в которых используется комбинация методов, чтобы убедиться в отсутствии противоречий или конфликтов в том, как они используются вместе.
Не путайте TDD с тестированием - это не так. TDD разработан таким образом, что вы пишете код для выполнения ваших требований, а не для проверки методов. Это тонкий, но важный момент, который часто теряется людьми, которые слепо пишут тестовый код для каждого метода. Дело в том, что вы должны писать тесты, которые гарантируют, что ваш код выполняет то, что вы хотите, а не то, что написанный вами код работает так, как он должен.
Справа есть несколько хороших ссылок о BDD v TDD. Проверь их.
источник
Когда вы начинаете изучать TDD, да, вы должны слепо следовать догматическому подходу, заключающемуся в том, чтобы не писать ни одной строки кода, кроме как для неудачного прохождения теста, и для написания только достаточного количества тестов для провала (и провала по правильной / ожидаемой причине). ,
После того, как вы узнали, что такое TDD, вы можете решить, что некоторые вещи не стоит тестировать. Это тот же подход, которому вы должны следовать во всем, и японские боевые искусства называют это « шухари ». (Ссылка также объясняет, как можно пройти этапы обучения без учителя, что, как я подозреваю, является тем, как большинство людей должны учиться.)
источник
Я считаю, что вы переоцениваете.
Я практикую TDD в течение многих лет, и по моему опыту, когда TDD выполняется эффективно, вы получаете два основных преимущества:
Обеспечить быструю обратную связь
Особенно с динамическими языками, я могу выполнить соответствующие тесты менее чем за секунду. И у меня есть наблюдатели файловой системы, запускающие эти тесты автоматически при изменении исходного файла на диске. Таким образом, у меня практически нет времени ожидания для тестов, и я сразу же узнаю, что код, который я пишу, работал так, как ожидалось. Таким образом, TDD приводит к очень эффективному способу работы.
Включить рефакторинг
Если у вас есть хороший набор тестов, вы можете безопасно провести рефакторинг, поскольку вы получите новое понимание того, как должна создаваться система.
Хороший набор тестов позволяет вам перекладывать ответственность в своем коде и при этом быть уверенным в том, что код работает, как и ожидалось, после перемещения. И вы должны быть в состоянии сделать это с небольшими изменениями в тестовом коде.
Если вы пишете тесты для каждого метода в вашей системе, то есть вероятность, что вы не сможете легко реорганизовать свой код, каждый рефакторинг вашего кода потребует значительных изменений в тестовом коде. И можете ли вы быть уверены, что тестовый код все еще работает, как ожидалось? Или вы случайно ввели код в тестовый код, который, следовательно, приводит к ошибке в рабочем коде?
Однако если вы, как и предлагалось в ответе pdr , при написании тестов сосредоточитесь на поведении, а не на методах , у вас будут тесты, которые потребуют гораздо меньше изменений при рефакторинге системы.
Или, как говорит Ян Купер в этой презентации (я процитировал по памяти, поэтому, возможно, не совсем правильно):
источник
Вы должны проверить каждый публичный метод.
Подвох в том, что если ваши публичные методы очень малы, вы, вероятно, выставляете слишком много информации. Обычная практика выставления каждого свойства как
getXXX()
фактического нарушает инкапсуляцию.Если ваши публичные методы на самом деле являются поведением класса, то вы должны их протестировать. Если нет, то они не являются хорошими публичными методами.
РЕДАКТИРОВАТЬ: pdr ответ гораздо более полный, чем мой.
источник