Любые инструменты / предложения по опровержению аргумента качества покрытия кода

11

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

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

Я смог оттолкнуть меня, продав аргумент, что Code Coverage говорит мне, что не было проверено наверняка, и помогает нам сосредоточиться на этих областях.

(Вышеупомянутое обсуждалось аналогичным образом в других вопросах SO, подобных этому - /programming/695811/pitfalls-of-code-coverage )

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

Хотя я понимаю их точку зрения, я ищу способ сделать более надежное обоснование для покрытия кода путем введения более надежных инструментов / структур, которые заботятся о большем количестве критериев покрытия (Functional, Statement,Decision, Branch, Condition, State, LCSAJ, path, jump path, entry/exit, Loop, Parameter Value etc) .

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

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


Редактировать: чтобы избежать путаницы в моем понимании слабости типичного покрытия кода, я хочу отметить, что я не имею в виду Statement Coverage (или строки исполняемого кода) инструменты (их много). На самом деле вот хорошая статья обо всем, что с ней не так: http://www.bullseye.com/statementCoverage.html

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

Смотрите: http://en.wikipedia.org/wiki/Code_coverage#Coverage_criteria

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


Редактировать:
Хорошо, возможно, я спроектировал это слишком драматично, но вы поняли. Проблема заключается в том, чтобы установить процессы / политики в целом для всех групп однородно / согласованно. И общий страх заключается в том, как обеспечить качество тестов, как распределить гарантированное время без каких-либо мер. Поэтому мне нравится иметь поддающуюся измерению особенность, которая при поддержке соответствующих процессов и правильных инструментов позволила бы нам улучшить качество кода, зная, что время не тратится на расточительные процессы.


РЕДАКТИРОВАТЬ: Пока что я имею из ответов:

  • Обзоры кода должны охватывать тесты для обеспечения качества тестов
  • Стратегия Test First помогает избежать тестов, написанных после факта, просто увеличив охват%
  • Изучение альтернативных инструментов, которые охватывают критерии тестирования, отличные от простого утверждения / строки
  • Анализ покрытого кода / количества найденных ошибок поможет оценить важность покрытия и улучшить ситуацию
  • Самое главное доверять вкладу команды, чтобы делать правильные вещи и бороться за свои убеждения
  • Блоки Крытые / # испытаний - Спорно, но имеет некоторое значение

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

MickJ
источник
4
Никто нигде не предлагает выполнить 100-процентное покрытие кода, это действительно глупое поручение.
Джимми Хоффа
1
Спасибо. И я уже знаю и признаю это. Кроме того, люди обычно связывают 100% покрытие кода со 100% заявлением (или строкой) покрытия. Также не удержался - Джимми, они искали тебя повсюду.
MickJ
3
«Тогда команда реагировала бы быстро, создавая тесты низкого качества и, таким образом, тратя время, не добавляя существенного качества» - отличная команда!
Петр Перак
Хорошо, может быть, я спроектировал это слишком драматично, но вы поняли. Проблема заключается в установлении процессов / политик в целом во всех командах однородным / последовательным образом. И общий страх заключается в том, как обеспечить качество тестов, как распределить гарантированное время без каких-либо мер. Поэтому мне нравится иметь поддающуюся измерению особенность, которая при поддержке соответствующих процессов и правильных инструментов позволила бы нам улучшить качество кода, зная, что время не тратится на расточительные процессы.
MickJ
1
@JimmyHoffa - для критически важного программного обеспечения обычно требуется 100% покрытие кода.
Mouviciel

Ответы:

9

По моему опыту, покрытие кода так же полезно, как вы делаете это . Если вы пишете хорошие тесты, которые охватывают все ваши случаи, то прохождение этих тестов означает, что вы выполнили свои требования. На самом деле это точная идея , что Test Driven Development использует. Вы пишете тесты перед кодом, ничего не зная о реализации (иногда это означает, что другая команда полностью пишет тесты). Эти тесты предназначены для проверки того, что конечный продукт выполняет все, что указано в ваших спецификациях, и ТОГДА вы пишете минимальный код для прохождения этих тестов.

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

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

Ampt
источник
+1 за предположение, что написание тестов в первую очередь улучшает качество тестов, поэтому комбинация Test сначала с Code Coverage определенно полезна.
MickJ
Да, я всегда обнаруживал, что если вы пишете тесты после разработки кода, вы будете тестировать только то, что, как вы знаете, ваш код пройдет, или вы будете писать тесты способом, который дополняет реализацию, что на самом деле никому не помогает. Если вы пишете свои тесты независимо от кода, вы сосредотачиваетесь на том, что должен делать код , а не на том, что он делает .
День
Спасибо @Ampt. Помимо усиления процесса с помощью TDD, есть ли какие-либо инструменты покрытия кода, которые вы рекомендуете, которые заботятся о большем количестве критериев покрытия более исчерпывающим образом, помогая тем самым подтвердить качество тестов, написанных хотя бы в некоторой степени?
MickJ
Возможно, я вас неправильно понимаю, но вы предполагаете, что разные инструменты будут показывать вам разное покрытие для ваших тестов? Мой опыт всегда заключался в том, что инструменты покрытия просто наблюдают за выполнением тестов и записывают, какие строки кода выполняются. В этом случае инструменты переключения не должны влиять на покрытие, так как количество выполненных строк остается неизменным. Я бы с осторожностью относился к инструменту, который дает больше охвата для того же теста. Тем не менее, я не чувствую, что попадание в каждую строку кода является хорошей оценкой качества теста, поскольку это тщательность . Хорошие тесты проистекают из хороших требований.
Неудачный
Спасибо. То, на что вы ссылаетесь - это Statement Coverage(или выполненные строки кода). Я искал больше, чем просто заявление или линейное освещение, углубляясь в multiple coverage criteriaуровни и уровни. См. En.wikipedia.org/wiki/Code_coverage#Coverage_criteria и en.wikipedia.org/wiki/Linear_Code_Sequence_and_Jump . Идея состоит в том, что если инструмент может сообщить нам о нашем покрытии на основе нескольких критериев, то это станет разумной автоматизированной оценкой качества теста. Я ни в коем случае не пытаюсь сказать, что покрытие линии - хорошая оценка. На самом деле это предпосылка моего вопроса.
MickJ
6

Во- первых, люди делают адвокатскую 100% охват:

Большинство разработчиков считают ... "100% покрытие заявления" адекватным. Это хорошее начало, но вряд ли достаточно. Лучший идентификатор стандарта покрытия, чтобы соответствовать так называемому «100% охвату филиалов» ...

Стив Макконнелл, Code Complete , Глава 22: Тестирование разработчика.

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

Я бы посоветовал разрешить спор путем сбора и анализа данных о ваших собственных проектах.

Для сбора данных я лично использую следующие инструменты:

  • JaCoCo и связанный с ним Eclipse-плагин EclEmma для измерения покрытия кода.
  • Сценарии Ant для автоматического построения, тестирования и создания отчетов.
  • Jenkins для непрерывных сборок - любое изменение в управлении исходным кодом вызывает автоматическую сборку
  • Плагин JaCoCo для Jenkins - фиксирует показатели покрытия для каждой сборки и составляет график тенденций. Также позволяет определить пороговые значения покрытия для каждого проекта, которые влияют на работоспособность сборки.
  • Bugzilla для отслеживания ошибок.

Когда у вас есть это (или что-то подобное), вы можете начать более внимательно смотреть на свои собственные данные:

  • больше ошибок найдено в плохо освещенных проектах?
  • больше ошибок найдено в плохо покрытых классах / методах?
  • и т.п.

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

Натан Герхарт
источник
Мне очень нравится этот ответ. Спасибо за предложения по инструментам и, что более важно, мне нравится идея подхода на основе данных для обоснования покрытия кода. Хотя я, как правило, беру слово команд на ценность и не буду подвергать сомнению это в любом случае. Возможно, это может помочь мне доказать более убедительные аргументы в пользу нашего опыта. Благодаря!
MickJ
4

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

Это вопрос доверия , а не инструментов .

Спросите их, почему, если они действительно верят этому утверждению, они доверяют команде вообще писать какой-либо код?

Стивен А. Лоу
источник
Поскольку они знают, что функциональность кода - это основной итог, то есть: тестирование, документирование, комментарии, обзоры и т. Д. Могут быть принесены в жертву без каких-либо непосредственных последствий; хотя я согласен, это плохой знак.
Джеффо
Хорошо, может быть, я спроектировал это слишком драматично, но вы поняли. Проблема заключается в установлении процессов / политик в целом во всех командах однородным / последовательным образом. И общий страх заключается в том, как обеспечить качество тестов, как распределить гарантированное время без каких-либо мер. Поэтому мне нравится иметь поддающуюся измерению особенность, которая при поддержке соответствующих процессов и правильных инструментов позволила бы нам улучшить качество кода, зная, что время не тратится на расточительные процессы.
MickJ
3

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

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

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

Обычный график:

  1. dev: эй, смотри - я добавил метрики покрытия кода на нашу панель, разве это не здорово?
  2. менеджер: конечно, давайте добавим обязательные цели и соблюдение тех
  3. dev: не берите в голову, покрытие кода глупо и бесполезно, давайте отбросим его
ptyx
источник
1
+1 Я видел это слишком много раз, чтобы не соглашаться. Я в моем случае, хотя разговор идет немного по этому пути. dev: эй, смотри - я добавил метрики покрытия кода на нашу панель, разве это не здорово? менеджер: конечно, все, что вы, ребята, думаете, улучшает качество, это замечательно. Начальник босса менеджеров: я думаю, что нам нужно иметь один процесс в командах. Я думаю, что покрытие кода бессмысленно, если мы не сможем гарантировать ценность из затраченных затрат.
MickJ
2

По моему опыту, есть несколько вещей, которые можно объединить с покрытием кода, чтобы сделать метрику полезной:

Код Отзывы

Если вы можете сдать плохие тесты обратно разработчику, это может помочь ограничить количество плохих тестов, которые обеспечивают это бессмысленное покрытие.

Отслеживание ошибок

Если у вас есть большой охват кода в модуле, но вы все еще получаете много / серьезных ошибок в этой области, то это может указывать на проблему, когда разработчику необходимо улучшить свои тесты.

Прагматизм

Никто не собирается достигать 100% с хорошими тестами на нетривиальном коде. Если вы, как руководитель группы, посмотрите на покрытие кода, но вместо того, чтобы сказать «нам нужно добраться до N%!» вы выявляете пробелы и просите людей «улучшить охват в модуле X», чтобы достичь вашей цели, не предоставляя людям возможность играть в систему.

Покрытые блоки / Количество тестов

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

Telastyn
источник
+1 Хорошие предложения, мне особенно нравятся покрытые блоки / количество тестов и обзоров кода. Хотя мы уже делаем обзоры кода, было бы полезно подчеркнуть важность более тщательного анализа самих тестов.
MickJ
2

Вот мои 2 цента.

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

Несколько примеров:

  • Напишите модульные тесты со 100% покрытием кода, и вы получите лучшее качество кода.
  • Применяйте TDD систематически, и вы получите лучший дизайн.
  • Занимайтесь парным программированием, вы улучшите качество кода и сократите время разработки.

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

Таким образом, приведенные выше утверждения содержат некоторую правду, но слишком упрощают вещи, например:

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

Возвращаясь к покрытию кода.

Я смог оттолкнуть меня, продав аргумент, что Code Coverage говорит мне, что не было проверено наверняка, и помогает нам сосредоточиться на этих областях.

Я думаю, вы должны судить от случая к случаю, стоит ли иметь 100% покрытие для определенного модуля.

Модуль выполняет некоторые очень важные и сложные вычисления? Затем я хотел бы протестировать каждую строку кода, а также написать содержательные модульные тесты (модульные тесты, которые имеют смысл в этой области).

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

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

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

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

как вы распределяете гарантированное время без каких-либо мер

Может быть, это иллюзия, что вы можете измерить человеческий разум и суждение. Если у вас есть компетентные коллеги и вы доверяете их суждениям, вы можете согласиться, когда они скажут вам «для этого модуля, увеличение покрытия кода принесет очень мало пользы. Поэтому давайте не будем тратить на это время» или «для этого модуля, который нам нужен Для максимально возможного охвата нам понадобится одна дополнительная неделя для проведения разумных модульных тестов. "

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

Джорджио
источник
Все верно и я уже согласен. Если вы заметили, я не поддерживаю 100% покрытие кода. Речь идет об улучшении его стоимости с помощью методов, инструментов и процессов беттет. Это также помогает полностью понять критерии покрытия кода (большинство предполагает, что это строка / утверждение). +1 за ваш отличный пост.
MickJ
2

«Команда будет реагировать, быстро создавая тесты низкого качества и, таким образом, тратить время, не добавляя при этом никакого существенного качества»

Это реальный риск, а не только теоретический.

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

«Предложение сочетать такие инструменты покрытия кода и практики / процессы с ними»

В дополнение ко всем другим предложениям, существует один метод автоматизации, который может оценить качество тестов: тестирование мутаций ( http://en.wikipedia.org/wiki/Mutation_testing ). Для кода Java работает PIT ( http://pitest.org/ ), и это первый инструмент для тестирования мутаций, с которым я столкнулся.

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

Xris - Flatbush Gardener
источник
1

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

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

Ozz
источник
2
Точки, которые не говорят, имеют тенденцию быть спорными . (Мне просто нравится игра слов - мое правописание часто исправляется).
1

Я всегда обнаруживал, что покрытие кода легко подвержено эффекту Хоторна . Это заставило меня спросить "почему у нас вообще есть какие-либо показатели программного обеспечения?" и ответ, как правило, заключается в том, чтобы обеспечить некоторое понимание текущего состояния проекта на высоком уровне, например:

"Насколько мы близки к завершению?"

"Как качество этой системы?"

"Насколько сложны эти модули?"

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

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

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

Метрика, которую я нашел полезной для создания хороших приближений, это Crap4J . Теперь он не работает, но вы можете легко перенести / реализовать его самостоятельно. Crap4J пытается связать покрытие кода с цикломатической сложностью , подразумевая, что более сложный код (ifs, whiles, fors и т. Д.) Должен иметь более высокое тестовое покрытие. Для меня эта простая идея действительно звучит правдоподобно. Я хочу понять, где есть риск в моей кодовой базе, и один действительно важный риск - это сложность. Таким образом, используя этот инструмент, я могу быстро оценить, насколько рискован мой код. Если это сложно, охват должен был пойти вверх. Если это не так, мне не нужно тратить время, пытаясь охватить каждую строку кода.

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

adambender
источник
Спасибо за отличное предложение использовать цикломатическую сложность для выбора кода, заслуживающего покрытия, и ссылки Crap4J. Я также нашел отличную статью, рассказывающую о том, как втискивать в cobertura удивительную привлекательность crap4j - schneide.wordpress.com/2010/09/27/…
MickJ
0

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

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

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

Майкл Браун
источник