Применяется ли YAGNI и при написании тестов? - PullRequest
13 голосов
/ 03 июня 2009

Когда я пишу код, я пишу только те функции, которые мне нужны, когда они мне нужны.

Применяется ли этот подход также к написанию тестов?

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

Ответы [ 11 ]

13 голосов
/ 03 июня 2009

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

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

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

В последнем случае я менее способен дать вам окончательный ответ. Вы, конечно, хотите, чтобы ваши тесты оставались СУХИМЫМИ - не пишите тест, который просто повторяет другой тест, даже если он содержит другие данные. В качестве альтернативы, вы не можете обнаружить потенциальные проблемы проектирования, если вы не используете крайние случаи ваших данных. Простым примером является метод, который вычисляет сумму двух целых чисел: что произойдет, если вы передадите ему maxint в качестве обоих параметров? Если у вас есть только один тест, вы можете пропустить это поведение. Очевидно, это связано с предыдущим пунктом. Только вы можете быть уверены, когда тест действительно необходим или нет.

9 голосов
/ 03 июня 2009

Да, YAGNI абсолютно подходит для написания тестов.

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

Вы всегда должны учитывать обоснованность написания любого теста. Если для вас нет явной выгоды при написании теста, я бы посоветовал вам этого не делать. Однако это явно очень субъективно , так как то, что вы думаете, не стоит того, что кто-то может подумать, стоит усилий.

Кроме того, я бы написал тесты для проверки ввода? Абсолютно. Однако я бы сделал это до точки . Скажем, у вас есть функция с 3 параметрами, которые являются целыми, и она возвращает значение double. Сколько тестов вы собираетесь написать вокруг этой функции. Я бы использовал YAGNI, чтобы определить, какие тесты принесут вам хороший ROI , а какие бесполезные.

4 голосов
/ 03 июня 2009

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

Это дает следующие преимущества:

  1. Ваши тесты помогают определить функциональность этого этапа.
  2. Вы знаете, когда прошли этот этап, потому что все ваши тесты пройдены.
4 голосов
/ 03 июня 2009

Напишите тест, как вам нужно. Тесты кодовые. Написание нескольких (изначально неудачных) тестов заблаговременно нарушает цикл TDD красный / исправление / зеленый и усложняет идентификацию действительных отказов по сравнению с неписанным кодом.

3 голосов
/ 03 июня 2009

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

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

3 голосов
/ 03 июня 2009

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

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

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

Мягкое обновление

Должен заметить, что я иду с другой точки зрения, чем многие здесь. Я часто нахожу, что пишу код в библиотечном стиле, то есть код, который будет повторно использоваться в нескольких проектах для разных клиентов. В результате я, как правило, не могу с уверенностью сказать, что определенных вариантов использования просто не произойдет. Лучшее, что я могу сделать, это либо документ, что они не ожидаются (и, следовательно, может потребовать обновления тестов позже), либо - и это мое предпочтение :) - просто написание тестов. Я часто нахожу вариант № 2 для более пригодного для повседневного использования, просто потому, что у меня гораздо больше уверенности, когда я повторно использую компонент X в новом приложении Y. И уверенность, на мой взгляд, то, что автоматическое тестирование является все о.

3 голосов
/ 03 июня 2009

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

Итак, нет. YAGNI не включает тесты:)

2 голосов
/ 03 июня 2009

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

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

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

1 голос
/ 03 июня 2009

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

Если вы решите проводить более инкрементное тестирование, я мог бы добавить в комментарии к документу, что функция «тестируется только для [определенных видов ввода], результаты для других входов не определены».

0 голосов
/ 03 июня 2009

Если вы работаете в стиле TDD или XP, вы не будете писать что-либо «заранее», как говорите, вы будете работать над очень точной функциональностью в любой момент, так что вы Я напишу все необходимые тесты, чтобы убедиться, что функциональность работает так, как вы намереваетесь.

Тестовый код аналогичен самому «коду», вы не будете писать код заранее для каждого случая использования вашего приложения, так зачем вам писать тестовый код заранее?

...