Сколько покрытия кода «достаточно»?

37

Мы начинаем настаивать на покрытии кода здесь, на моей работе, и это заставило меня задуматься ... Насколько достаточно покрытия кода?

Когда вы дойдете до точки снижения прибыли от покрытия кода? Что такое сладкое место между хорошим освещением и недостаточно? Это зависит от типа проекта, который вы делаете (например, WPF, WCF, Mobile, ASP.NET) (это классы C #, которые мы пишем).

Vaccano
источник
Там действительно нет хорошего ответа на это; « Сколько вам нужно модульных тестов? » На форумах разработчиков Artima есть несколько полезных советов.
RN01

Ответы:

19

Мы стремимся как минимум на 70%. На вещи, которые легче тестировать (например, функциональные структуры данных), мы стремимся к 90%, а большинство людей стремятся к как можно более близким к 100%. На вещи, связанные с WPF, и другие фреймворки, которые очень сложно протестировать, мы получаем гораздо меньший охват (всего 70%).

Ной Ричардс
источник
Сложно ли тестировать WPF или же вы еще не потратили усилия на то, чтобы разработать лучшую стратегию для лучшего освещения?
JBRWilkinson
Во многом это связано с тем, что входные данные WPF трудно подделать. Наше тестирование такое же, как у юнитов или API-у, насколько мы можем его получить, и неспособность легко подделать слой, который находится «поверх» WPF (по крайней мере, на входе), затрудняет тестирование. Это не большая проблема, поскольку части API без графического интерфейса легко тестируются, но это просто последний этап, который идет от нашей модели (или модели представления) до WPF, что является сложной задачей.
Ноа Ричардс
1
Да, WPF - это сука для тестирования. И я мог бы жить с этим, если бы было время компиляции, проверяющее привязки в представлениях. Так что, по крайней мере, сборка будет нарушена, если вы измените свойство, к которому привязано представление. Но это не так. Это заставило нас использовать автоматизацию GUI в наших приемочных тестах, что также является сукой для написания. Но, по крайней мере, это дает нам уверенность в том, что система работает.
Пит
Мне нравится число (70%). По мере того, как мои команды становятся выше, я, как правило, начинаю находить тесты для покрытия, а не для оценки. На комментарии WPF, мы только в начале дня. Это означает, что мы не создаем / структурируем код WPF, чтобы его можно было легко тестировать. Макетные модели помогают. При разработке кода проектируйте его так, чтобы он был тестируемым. И да, на данный момент есть ограниченные примеры, так что вы должны подумать об этом. Не отличается от того, где находилось большинство разработчиков, так как TDD был представлен им впервые, только меньше отраслевого опыта.
Джим Раш
если быть более конкретным, то WPF - это сущий юнит- тест, если по какой-то причине вам требуется более широкий охват, самый простой способ расширить охват классов WPF - это кодированные тесты пользовательского интерфейса / интеграционные тесты
jk.
55

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

Fishtoaster
источник
8
Покрытие кода должно быть одним из результатов ваших автоматических тестов, которые выполняются в вашей автоматизированной системе сборки. Тесты, которые не проверяют вывод, вряд ли стоит иметь. Покрытие ниже порогового уровня указывает на новые функции, в которых тесты отсутствуют или недостаточны. Это не должно быть чем-то, что могло бы побить людей - но, конечно, это может пометить непроверенный код.
JBRWilkinson
3
Я второй JBRWilkinson здесь, хотя и не показатель хорошего кода, охват кода может быть индикатором отсутствия тестов. Кроме того, ваши модульные тесты могут предоставлять и другие показатели, например, показатели производительности, чтобы вы не удивились неожиданно, когда новая версия выйдет из строя на сервере при неожиданной рабочей нагрузке.
Матье М.
4
Я думаю, что это ложный выбор. Качественные тесты, которые затрагивают только небольшой объем кода, являются плохими общими показателями качества, как и «тесты», которые затрагивают большой объем кода, но на самом деле не проверяют результаты. Другими словами, представьте себе процесс обеспечения качества для автомобилей, который был очень тщательным при тестировании переднего колеса со стороны водителя, но никакой другой части автомобиля. Это было бы плохо, точно так же, как и процесс обеспечения качества, когда парень просто смотрел на всю машину и говорил: «Да, хорошо выглядит».
Ной Ричардс
38

«Достаточно» - это когда вы можете вносить изменения в свой код с уверенностью, что вы ничего не нарушаете. В некоторых проектах это может быть 10%, в других - 95%.

Это почти никогда не достигает 100%. Тем не менее, иногда попытка получить 100% -ное покрытие кода может быть отличным способом удалить излишки кода. Не забывайте, что есть два способа увеличить покрытие кода - написать больше тестов или убрать код. Если код не описан, потому что его сложно протестировать, есть большая вероятность, что вы можете упростить или реорганизовать его, чтобы упростить тестирование. Если слишком сложно заниматься тестированием, обычно есть хороший шанс, что ничто другое в коде не использует его.

RevBingo
источник
24
«Испытай, пока страх не превратится в скуку»
Брэд Мейс
2
Upvote за комментарий об удалении кода. Я использую метрики покрытия кода для этого все время (в VS, где это выделяет строки, которые не охвачены).
Ной Ричардс
Отличная цитата @bemace
jayraynet
14

Покрытие кода приближается к 100% асимптотически. Следовательно, эти последние 5%, вероятно, потребуют больше усилий, чем они того стоят, так как вы начинаете достигать невероятно небольшой отдачи от затраченных усилий.

Роберт Харви
источник
7

Охват - это показатель, за которым нужно следить, но он не должен быть конечной целью. Я видел (и по общему признанию!) Множество кода с высоким покрытием - покрытие 100% (конечно, TDD), но:

  • ошибки все еще появляются
  • дизайн все еще может быть плохим
  • Вы действительно можете убить себя, стреляя по какой-то произвольной цели освещения - выбирайте свои сражения: p

Там есть «Путь Testivus» запись , что я думаю , уместно сослаться здесь :)

ГИ
источник
5

Только 20% большей части кода будет выполняться 80% времени . Анализ покрытия кода не очень полезен, если только он не связан с графиком вызовов, чтобы определить, что нужно тестировать больше всего. Это говорит вам, где ваши крайние случаи могут быть. Вы можете предложить 100 тестов только для тех крайних случаев, которые составляют менее 5% фактического кода.

Итак, убедитесь, что покрыты 100% из 20%, которые определяют критические пути, и не менее 50% от остальных (согласно графику вызовов). Это должно дать вам (примерно) 70% - 75% общего покрытия, но оно варьируется.

Не тратьте время, пытаясь получить более 70% общего покрытия, оставляя критические крайние случаи без проверок.

Тим Пост
источник
Разве инструменты покрытия кода не генерируют граф вызовов по определению?
JBRWilkinson
4

Используйте покрытие в качестве руководства, чтобы указать области, которые не были проверены. Вместо того, чтобы иметь мандат на покрытие, разумнее понять причину, по которой код не охватывается. Запись причины нехватки - хорошая дисциплина, которая позволяет сбалансировать риски.

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

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

Мы также должны убедиться, что мы также охватили объектный код.

Это баланс между риском, в нашем случае очень высоким, и стоимостью / стоимостью. Необходим осознанный выбор, основанный на риске пропуска ошибки.

Марк Фишер
источник
3

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

У меня есть проекты, где эта точка равна 0%, потому что охват невозможно рассчитать без ущерба для дизайна и других проектов, где этот показатель достигает 92%.

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

Билл
источник
2

Для критически важного программного обеспечения требуется 100% покрытие.

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

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

mouviciel
источник
2

Мне очень нравится ответ @ RevBingo, потому что он предполагает, что борьба за 100% может привести к тому, что вы очистите или удалите неиспользуемый код. То, что я не видел в других ответах, - это ощущение, когда вам нужен высокий охват, а когда нет. Я сделал удар в начале этого. Я думаю, что добавление деталей к такой диаграмме было бы более полезным, чем поиск одного номера покрытия теста, подходящего для всего кода.

100%

Для общедоступного API, такого как коллекции java.util, который не связан с базой данных и не возвращает HTML, я думаю, что 100% покрытие - это благородная начальная цель, даже если вы соглашаетесь на 90-95% из-за времени или другого ограничения. Увеличение охвата тестами после завершения функции требует более детального изучения, чем другие виды проверки кода. Если ваш API вообще популярен, люди будут использовать его, создавать подклассы, десериализовать его и т. Д., Чего вы не можете ожидать. Вы не хотите, чтобы их первым опытом было обнаружение ошибки или недосмотр дизайна!

90%

Для кода бизнес-инфраструктуры, который принимает структуры данных и возвращает структуры данных, 100% по-прежнему, вероятно, хорошая начальная цель, но если этот код недостаточно общедоступен, чтобы вызвать много злоупотреблений, возможно, 85% все еще приемлемы?

75%

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

50% или меньше

Я ненавижу писать тесты для функций, которые возвращают HTML, потому что он такой хрупкий. Что если кто-то изменит CSS, JavaScript или весь блоб HTML и английского, который вы вернете, не имеет смысла для конечных пользователей? Если вы можете найти функцию, которая использует много бизнес-логики для создания небольшого HTML, это может стоить протестировать. Но обратная ситуация может вообще не стоить проверять.

Около 0%

Для некоторого кода определение «правильный» - это «имеет смысл для конечного пользователя». Существуют нетрадиционные тесты, которые вы можете выполнить с этим кодом, такие как автоматическая проверка грамматики или проверка правильности HTML-кода. Я даже настроил операторы grep для небольших несоответствий, которыми мы обычно становимся жертвами на работе, например, говоря «Логин», когда остальная система называет это «Вход». Этот человек не только должен быть модульным тестом, но и полезным способом выявления проблем, не ожидая конкретного выхода.

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

Абсолют 0%

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

Я купил книгу, потому что она утверждала, что она показывает, как автоматически копировать данные для тестирования Hibernate. Но он проверял только Hibernate HQL и SQL-запросы. Если вам приходится много работать с HQL и SQL, вы действительно не получаете преимущества Hibernate. Существует форма базы данных Hibernate в памяти, но я не потратил время на то, чтобы выяснить, как эффективно использовать ее в тестах. Если бы у меня это было запущено, я бы хотел иметь высокое (50% -100%) тестовое покрытие для любой бизнес-логики, которая вычисляет вещи путем навигации по графу объектов, в результате чего Hibernate запускает некоторые запросы. Моя способность тестировать этот код сейчас составляет около 0%, и это проблема. Поэтому я улучшаю охват тестами в других областях проекта и стараюсь отдавать предпочтение чистым функциям по сравнению с теми, которые обращаются к базе данных, в основном потому, что легче писать тесты для этих функций. Все еще,

GlenPeterson
источник
1

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

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

Джорджио
источник
0

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

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

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

Пит
источник