Вы ставите модульные тесты в один проект или другой проект?


вы помещаете модульные тесты в один и тот же проект для удобства или вы помещаете их в отдельную сборку?

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

12 124

12 ответов:

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

  1. модульные тесты поставляются с кодом производства. Единственное, что поставляется с кодом продукта-это производственный код.
  2. сборки будут излишне раздуты модульными тестами.
  3. модульные тесты могут влиять на процессы сборки, такие как автоматизированные или непрерывные строить.

Я действительно не знаю никаких плюсов. Наличие дополнительного проекта (или 10) не является мошенничеством.

Edit: дополнительная информация о сборке и доставке

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

подводя итог, вот общая идея для ежедневной сборки и тестирования и доставки битов и других файлов:

  1. Производственная сборка выполняется, помещая производственные файлы в определенный каталог "производство".
    1. строить только производственные проекты.
    2. копировать скомпилированные биты и другие файлы в "каталог продукции".
    3. скопируйте биты и другие файлы в каталог кандидатов на выпуск, он же каталог рождественского выпуска будет "Release20081225".
  2. Если Производственная сборка выполнена успешно, выполняется модульная тестовая сборка.
    1. скопируйте производственный код в каталог "тесты".
    2. построить модульные тесты в каталог "тесты".
    3. выполнить модульные тесты.
  3. отправка уведомлений о сборке и модульных тестов результаты для разработчиков.
  4. когда кандидат на выпуск (например, Release20081225) принимается, Отправьте эти биты.

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

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

Если вам нужен доступ к внутренним членам производственный код, используйте InternalsVisibleTo.

Я не понимаю частых возражений против развертывания тестов с производственным кодом. Я возглавлял команду на небольшом микрокапе (вырос с 14 до 130 человек). У нас было полдюжины или около того Java-приложений, и мы сочли чрезвычайно ценным развернуть тесты в поле, чтобы выполнить их на конкретные машина, которая демонстрировала необычное поведение. Случайные проблемы возникают в полевых условиях и возможность бросить несколько тысяч единичных тестов на тайну с нулевой стоимостью была неоценима и часто диагностировали проблемы в считанные минуты...в том числе проблемы с установкой, проблемы с шелушащейся оперативной памятью, Проблемы с машиной, проблемы с шелушащейся сетью и т. д. и т. д. Я думаю, что это невероятно ценно, чтобы поставить тесты в этой области. Кроме того, случайные проблемы появляются в случайные моменты времени, и приятно иметь модульные тесты, сидящие там, уже ожидая выполнения в момент уведомления. Место на жестком диске дешево. Так же, как мы пытаемся сохранить данные и функции вместе (OO design), я думаю, что есть что-то принципиально ценно в сохранении кода и тестов вместе (функция + тесты, которые проверяют функции).

Я хотел бы поместить свои тесты в тот же проект в C#/.NET/Visual Studio 2008, но я все еще не исследовал этого достаточно, чтобы достичь этого.

одно большое преимущество держать Foo.cs в том же проекте, что и FooTest.cs - это то, что разработчики постоянно напоминают, когда класс пропускает тест брата! Это способствует улучшению практики кодирования на основе тестирования...отверстия больше очевидный.

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

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

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

и вы можете удалить модульные тесты из производственного кода, используя теги компиляции (если #Debug).

автоматические интеграционные тесты (сделанные i NUnit) должны быть в отдельном проекте, поскольку они не принадлежат ни к одному из них проект.

мои модульные тесты всегда идут в отдельном проекте. Фактически, для каждого проекта, который у меня есть в моем решении, есть отдельный тестовый проект, который идет вместе с ним. Тестовый код не является кодом приложения и не должен быть смешан с ним. Одно преимущество к держать их в отдельных проектах -- по крайней мере используя TestDriven.Net -- это то, что я могу щелкнуть правой кнопкой мыши на тестовом проекте и запустить все тесты в этом проекте, Протестировав всю библиотеку кода приложения одним щелчком мыши.

Если Нанит используется фреймворк, есть дополнительная причина поставить тесты в том же проекте. Рассмотрим следующий пример производственного кода, смешанного с модульными тестами:

public static class Ext
{
     [TestCase(1.1, Result = 1)]
     [TestCase(0.9, Result = 1)]
     public static int ToRoundedInt(this double d)
     {
         return (int) Math.Round(d);
     }
}

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

обновление: Я знаю, что такое использование TestCase атрибут не был тем, что разработчики NUnit намеревались, но почему бы и нет?

я колеблюсь между одним и тем же проектом и разными проектами.

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

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

я помещаю их в отдельные проекты. Имя сборки отражает имя пространств имен, как общее правило для нас. Так что если есть проект под названием Компания.Товар.Особенность.sln, он имеет выход (имя сборки) компании.Товар.Особенность.файл DLL. Тестовый проект-это компания.Товар.Особенность.Тесты.СЛН, уступая компании.Товар.Особенность.Тесты.файл DLL.

лучше всего хранить их в одном решении и управлять выводом через Configuration Manager. У нас есть имя конфигурация для каждой из основных ветвей (разработка, интеграция, производство) вместо использования отладки и выпуска по умолчанию. После того, как вы настроили свои конфигурации, вы можете включить или исключить их, нажав на флажок "построить" в Configuration Manager. (Чтобы получить Configuration Manager, щелкните правой кнопкой мыши решение и перейдите в Configuration Manager.) Обратите внимание, что я нахожу CM в Visual Studio, чтобы быть глючит время от времени. Пару раз мне приходилось заходить в проект и / или файлы решения для очистки целевых объектов, которые он создал.

кроме того, если вы используете Team Build (и я уверен, что другие инструменты сборки .NET одинаковы), вы можете связать сборку с именованной конфигурацией. Это означает, что если вы не создаете модульные тесты для своей "производственной" сборки, например, проект сборки также может знать об этом параметре и не создавать их, поскольку они были помечены как таковые.

кроме того, мы использовали, чтобы сделать xcopy падает от сборки машина. Сценарий просто опустит копирование чего-либо с именем *.Тесты.Dll файлы могут быть развернуты. Это было просто, но сработало.

Я бы сказал, держать их отдельно.

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

Я действительно вдохновлен структурой модульного тестирования Flood NN library Роберт Лопез. Он использует другой проект для каждого отдельного тестируемого класса и имеет одно решение, содержащее все эти проекты, а также основной проект, который компилирует и запускает все тесты.

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

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

почему?

во-первых, я очень склонен сохранять структуру папок основного проекта с тестовым проектом. Итак, если у меня есть файл под Providers > DataProvider > SqlDataProvider.cs тогда я создаю такую же структуру в своих проектах модульного тестирования, как Providers > DataProvider > SqlDataProvider.Tests.cs

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

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

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

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

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

особенно для Js и Python вам не нужно будет импортировать ссылки из другого пути, вы можете просто использовать один и тот же путь тестируемого целевого файла.

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

отдельные проекты, хотя я спорю с самим собой, должны ли они делиться одним и тем же svn. На данный момент я даю им отдельные репозитории svn, один называется

"MyProject" - для самого проекта

и

"MyProjectTests" - для тестов, связанных с MyProject.

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

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

MyProject
|\Trunk
| |\Code
|  \Tests
|\Tags
| |.1
| | |\Code
| |  \Tests
|  .2
|   |\Code
|    \Tests
\Branches
  \MyFork
   |\Code
    \Test

мне было бы интересно узнать, что другие люди думают об этом решении.