Покрытие кода в TFS Build 2010 с использованием NUnit - PullRequest
4 голосов
/ 29 июля 2011

Мне было интересно, имел ли кто-нибудь из вас опыт создания отчетов о покрытии кода в TFS Build Server 2010 при выполнении тестов NUnit.

Я знаю, что это легко сделать с помощью пакетной альтернативы (MSTest + включение покрытия в файле testrunconfig), но при использовании NUnit все немного сложнее.Я нашел кое-какую информацию, указывающую на NCover, но она кажется устаревшей.Интересно, есть ли другие альтернативы и действительно ли кто-то реализовал это или нет.

Вот дополнительная информация о нашей среде / потребностях: - TFS Build Server 2010 - Тесты находятся в простых библиотеках классов (не в библиотеках тестов - т.е., не связанные файлы testrunconfig), и реализованы в NUnit.У нас нет MSTests.- Мы заинтересованы в том, чтобы отчеты о покрытии работали как часть каждой сборки и, если возможно, устанавливали пороговые требования к покрытию для критериев прохождения / неудачи

1 Ответ

4 голосов
/ 30 июля 2011

Мы сделали это с NUnit-NCover и очень довольны нашими результатами.
За выполнением NUnit следует NUnitTfs , чтобы результаты нашего тестирования были опубликованы в журнале сборки.Затем включается NCover, генерируя наши результаты покрытия кода.

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

Недостатками могут быть две вещи:

  • NUnitTfs плохо работает с NCover (по крайней мере, я не смог найти способ выполнить оба на одном шаге, поэтому (поскольку NCover вызывает NUnit) мне нужно дважды запустить модульные тесты: (1) получить результаты теста и (2) получить результаты покрытия по NCover. Естественно, это делает мои сборки дольше.
  • Настройка аргументов для правильного вызова NCover не была тривиальной, но с тех пор, как я установил его, мне никогда не приходилось поддерживать его .

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

РЕДАКТИРОВАТЬ
Я постараюсь быстро и грязно представить, как я это реализовал, я надеюсь, что это может быть полезно. В настоящее время у нас есть NCover 3.4.12 на нашем сервере сборки.
Нашпростое именованиеЧто касается наших сборок NUnit, так это то, что если у нас есть производственная сборка «123.dll», то существует другая сборка с именем «123_nunit.dll», которая реализует свои тесты.Итак, каждая сборка имеет несколько интересующих сборок * _nunit.dll.

Часть в шаблоне процесса сборки в разделе «Если не отключить тесты» - это та, которая была переработана для достижения наших целей,в частности, раздел под названием «Запустить MSTest для тестовых сборок».Вся реализация - здесь , после некоторой очистки, чтобы облегчить понимание потока (рис. Был слишком большим, чтобы быть вставленным прямо сюда).

Сначала некоторые дополнительные аргументы реализованы вшаблон процесса сборки & затем доступны для установки в каждом определении сборки:
enter image description here

Затем мы формируем аргументы NUnit в «Formulate nunitCommandLine»:

String.Format("{0} /xml={1}\\{2}.xml", nunitDLL, TestResultsDirectory, Path.GetFileNameWithoutExtension(nunitDLL))

Это затем используется в «Invoke NUnit»
enter image description here

В случае успеха, и мы установили покрытие для этой сборки, мы переходим к «Создать NCover NCCOV» (файл покрытия для этогоконкретная сборка).Для этого мы вызываем NCover.Console.exe со следующими аргументами:

String.Format("""{0}"" ""{1}"" //w ""{2}"" //x ""{3}\{4}"" //literal //ias {5} //onlywithsource //p ""{6}""",
              NUnitPath,
              Path.GetFileName(nunitDLL),
              Path.GetDirectoryName(nunitDLL),
              Path.GetDirectoryName(Path.GetDirectoryName(nunitDLL)),
              Path.GetFileName(nunitDLL).Replace("_nunit.dll", ".nccov"),
              Path.GetFileNameWithoutExtension(nunitDLL).Replace("_nunit", ""),
              BuildDetail.BuildNumber)

Все они выполняются в цикле foreach «Для всех dunit dll».Когда мы выходим из цикла, мы вводим «Final NCover Activity» и сначала часть «Merge NCCovs», где NCover.Console.exe выполняется снова - на этот раз с разными аргументами:

String.Format("""{0}\*.nccov"" //s ""{0}\{1}.nccov"" //at ""{2}\{3}\{3}.trend"" //p {1} ",
              Path.GetDirectoryName(Path.GetDirectoryName(testAssemblies(0))),
              BuildDetail.BuildNumber,
              NCoverDropLocation,
              BuildDetail.BuildDefinition.TeamProject
              )

Когда этовыполнив, мы достигли точки, когда все файлы NCCOV этой сборки были объединены в один NCCOV-файл, названный в честь сборки + файл Trend (который следит за сборкой на протяжении всей ее жизни) был обновлен с помощью элементов этой текущей сборки.

Теперь нам нужно только сгенерировать окончательный отчет в формате HTML, это делается в «Генерации окончательного представителя NCover», где мы вызываем NCover.reporting со следующими аргументами:

String.Format(" ""{0}\{1}.nccov"" //or FullCoverageReport //op ""{2}\{1}_NCoverReport.html"" //p ""{1}"" //at ""{3}\{4}\{4}_{5}.trend"" ",
              Path.GetDirectoryName(Path.GetDirectoryName(testAssemblies(0))),
              BuildDetail.BuildNumber,
              PathForNCoverResults,
              NCoverDropLocation,
              BuildDetail.BuildDefinition.TeamProject,
              BuildType
              )
...