Подтвердить что ты не робот

С# - исключая модульные тесты из версии версии вашего проекта

Как обычно вы идете разделять свою кодовую базу и связанные с ней модульные тесты? Я знаю людей, которые создают отдельный проект для модульных тестов, который я лично считаю запутанным и сложным в обслуживании. С другой стороны, если вы смешиваете код и его тесты в одном проекте, вы получаете двоичные файлы, связанные с вашей инфраструктурой unit test (будь то NUnit, MbUnit или что-то еще) и ваши собственные двоичные файлы рядом.

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

Одно из решений, которое я нашел, заключается в том, чтобы заключить все ваши модульные тесты в директивы #if DEBUG - #endif: когда код не ссылается на единичную тестовую сборку, компилятор достаточно умен, чтобы опустить ссылку в скомпилированном коде.

Есть ли другие (возможно, более удобные) варианты для достижения аналогичной цели?

4b9b3361

Ответ 1

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

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

Ответ 2

Как отмечают другие, отдельный тестовый проект (для каждого нормального проекта) - хороший способ сделать это. Я обычно зеркально отражаю пространства имен и создаю тестовый класс для каждого нормального класса с добавлением "test" к имени. Это поддерживается непосредственно в среде IDE, если у вас есть Visual Studio Team System, которая может автоматически генерировать тестовые классы и методы в другом проекте.

Одна вещь, которую следует помнить, если вы хотите протестировать классы и методы с помощью "внутреннего" доступа, - это добавить следующую строку в файл AssemblyInfo.cs для каждого тестируемого проекта:

[assembly: InternalsVisibleTo("UnitTestProjectName")]

Ответ 3

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

Ответ 4

Еще одна альтернатива использованию директив компилятора в файле или создание отдельного проекта - это просто создать дополнительные .cs файлы в вашем проекте.

С некоторой магией в самом файле проекта вы можете указать, что:

  • nunit.framework DLL ссылаются только на сборку отладки и
  • ваши тестовые файлы включены только в сборки отладки

Пример .csproj excerpt:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

   ...

   <Reference Include="nunit.framework" Condition=" '$(Configuration)'=='Debug' ">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\debug\nunit.framework.dll</HintPath>
   </Reference>

   ...

   <Compile Include="Test\ClassTest.cs" Condition=" '$(Configuration)'=='Debug' " />

   ...
</Project>

Ответ 5

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

Поддержание параллельных пространств имен и использование разумного соглашения об именах для тестов (например, MyClass и MyClassTest) помогут вам поддерживать поддерживающую кодбазу.

Ответ 6

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

например. для сборки, называемой, например, "Acme.BillingSystem.Utils", будет тестовая сборка под названием "Acme.BillingSystem.Utils.Test".

Исключить его из версии для доставки вашего продукта, не отправляя эту DLL.

Ответ 7

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

Сложная часть, разумеется, заключается в том, что бизнес имеет 55 проектов в решении, а 60% из них - тесты. Считайте себя счастливым.

Ответ 8

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

Ответ 9

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

Ответ 10

Еще одна вещь, которую следует учитывать, это версии VisualStudio до 2005 года, которые не позволяют ссылаться на проекты сборки EXE из других проектов. Поэтому, если вы работаете над устаревшим проектом в VS.NET, ваши варианты будут такими:

  • Поместите модульные тесты в один проект и используйте условную компиляцию, чтобы исключить их из релизов.
  • Переместите все в сборки dll, чтобы ваш exe был просто точкой входа.
  • Обходите среду IDE, взломав файл проекта в текстовом редакторе.

Из трех условных компиляций наименьшая вероятность ошибки.

Ответ 11

Я определенно согласен со всеми остальными, что вы должны отделить тесты от вашего производственного кода. Однако, если вы настаиваете на этом, вы должны определить условную константу comiplation, называемую TEST, и обернуть все ваши классы unit test с помощью

#if TEST
#endif

сначала, чтобы убедиться, что тестовый код не компилируется в производственном сценарии. Как только это будет сделано, вы должны либо исключить тестовые DLL из своего производственного развертывания, либо даже лучше (но более высокое обслуживание), создать NAnt или MSBuild для производства, который компилируется без ссылок на тестовые DLL.

Ответ 12

Я всегда создаю отдельный проект Acme.Stuff.Test, который компилируется отдельно.

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

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

Ответ 13

Если тег #if (DEBUG) допускает чистую версию "выпуска", зачем вам нужен отдельный проект для тестов. Пример nunit LibarryA/B (да, я знаю его пример) делает это. В настоящее время борьба со сценарием. Был использован отдельный проект, но это, по-видимому, позволяет улучшить производительность. Тем не менее, гумины и гавин.