C # / Visual Studio: размещение производственного и тестового кода - PullRequest
5 голосов
/ 26 мая 2010

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

До сих пор в моем опыте работы с C # / Visual Studio / ReSharper / NUnit я создал отдельные проекты (т.е. отдельные DLL) для производственного и тестового кода. Это идиома, или я с базы? Если это идиоматически правильно, как правильно разоблачать классы и методы в тестовых целях?

Спасибо

-Patrick

Ответы [ 4 ]

5 голосов
/ 26 мая 2010

Тестировать внутренний код очень просто: используйте [InternalsVisibleTo], чтобы заставить вашу производственную сборку "доверять" вашей тестовой сборке. Затем тестовая сборка будет иметь доступ ко всем внутренним элементам производственной сборки.

В приведенной выше документации MSDN приведен пример. Это очень просто.

Вы должны определенно разделить их, как вы делаете, IMO. Вы действительно не хотите, чтобы ваш тестовый код (или данные) попадал в рабочие сборки.

РЕДАКТИРОВАТЬ: Просто чтобы ответить на замечание Стивена о тестировании внутренних устройств: я думаю, что вполне разумно тестировать внутренние устройства. Я рассматриваю юнит-тесты как тесты белого ящика, а не черного ящика. Определенно есть место для тестирования только общедоступного API - особенно для интеграционных тестов - но я считаю, что есть много мест, где имеет смысл тестировать внутренних участников. Черт возьми, без этой способности, как вы собираетесь тестировать внутренние типы ? Иногда относительно небольшой общедоступный API накладывается поверх сложной внутренней реализации - и тестирование единиц этой реализации может быть сложным только с помощью общедоступного API.

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

Умеренность во всем, в основном.

0 голосов
/ 26 мая 2010

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

Вообще говоря, я крайне неохотно проверяю закрытые / защищенные методы моего SUT. Самое замечательное в TDD / UnitTesting заключается в том, что вы описываете внешнее поведение и оставляете детали реализации гибкими и «черными». После этого вы можете выполнять столько рефакторингов, сколько считаете нужным, и до тех пор, пока они не нарушают внешнее поведение, тесты менять не нужно.

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

Иногда у вас может быть внутренний класс / метод, который вы хотите проверить. В этом случае вы можете использовать атрибут [assembly: InternalsVisibleTo («Имя сборки сборки»)]] в файле рабочей сборки AssemblyInfo.cs и разрешить вашей пробной сборке просматривать внутренние компоненты вашей сборки сборки.

InternalsVisibleToAttribute в MSDN

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

Надеюсь, что это отвечает на ваши вопросы.

0 голосов
/ 26 мая 2010

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

0 голосов
/ 26 мая 2010

Тестовый код в производственном коде? Я понятия не имею, как Java справляется с этим, но для меня это звучит довольно страшно: -)

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

  • Разделение кода - я не уверен, как Java справляется с этим, но что мешает вам случайно отправить тестовый код в ваше приложение, если у вас есть все они в одном проекте? Надеюсь, это просто мое незнание того, как Java работает с точки зрения тестирования, а не реальная проблема.
  • Тестирование извне - Если вы вынуждены тестировать тестирование извне кода, это должно заставить вас задуматься о том, тестируете ли вы поведение тестируемого кода, а не реализацию , Вы можете обойти внутреннее состояние, используя такие вещи, как InternalsVisibleTo , но всякий раз, когда вы достигаете таких вещей, это может быть признаком того, что вы тестируете детали реализации, а не наблюдаемым извне поведением, которое приводит к хрупким тестам.

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

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