Я собираюсь запустить новый проект на работе и хочу заняться модульным тестированием. Мы будем использовать Visual Studio 2008, C# и материалы ASP.NET MVC. Я собираюсь использовать либо NUnit, либо встроенные тестовые проекты, которые есть в Visual Studio 2008, но я открыт для исследования других предложений. Одна система лучше другой или, возможно, проще в использовании / понимании, чем другая?
Я надеюсь, что этот проект станет своего рода «лучшей практикой» для наших дальнейших усилий по развитию.





Пользуюсь NUnit два года. Все в порядке, но я должен сказать, что система модульного тестирования в Visual Studio довольно хороша, потому что она находится внутри графического интерфейса и может более легко выполнять тест для частной функции без необходимости возиться.
Кроме того, модульное тестирование Visual Studio позволяет выполнять покрытие и другие вещи, которые не может выполнить только NUnit.
Щелкните правой кнопкой мыши частную функцию и выберите «Создать частный аксессуар».
Не трогайте интимные места. Помимо шуток, одна школа мысли состоит в том, что все, что вам нужно для теста, - это общедоступные методы. Вызов всех ваших общедоступных методов должен вызывать все ваши частные методы. Если частный метод не вызывается через общедоступный, частный метод является избыточным.
@Lieven: если вы тестируете рядовых, хотя и публику, вы на самом деле проводите интеграционный тест, а не модульный тест. (Конечно, я не фанат TDD и, наверное, просто протестирую публику ... но мне хочется помочь начать драку)
@Matthew, интеграционное тестирование - это тестирование двух или более модулей вместе. Тестирование частных методов - это просто (огромное) нарушение инкапсуляции и может привести к нестабильным модульным тестам, которые необходимо модифицировать каждый раз при изменении реализации.
+1 за упоминание покрытия кода в Visual Studio, что очень круто, вы можете дважды щелкнуть класс или метод, и редактор выделит код, который покрывается, и код, который не покрывается вашими модульными тестами. Позволяет легко приблизиться к 100% покрытию кода.
Вы также можете использовать [assembly: InternalsVisibleTo (...)] с директивой компилятора, чтобы удалить его, когда вы делаете сборку RTM.
Я все время прикасаюсь к своим частным лицам :) Я думаю, что есть смысл специально тестировать частные члены, чтобы избежать накладных расходов на тестирование вызывающих, которые требуют много сложной настройки.
Как сейчас делают большинство фанатиков TDD, методы интерфейса заняли место публичных методов, а публичные методы заменили частные методы. Итак, у вас есть «общедоступные» методы, но вы не можете получить к ним доступ через интерфейс, поэтому на самом деле они частные, но все же тестируемые. Многие будут пытаться оправдать это так или иначе, но на самом деле они лгут себе - единственная причина, по которой они делают это таким образом, заключается в том, что вам нужен интерфейс для имитации, и вы не можете тестировать частные методы. (продолжение)
(продолжение) Если бы технология позволяла им тестировать классы без создания интерфейса для все, большинство из них это сделали бы. И они будут тестировать свои частные методы, как и следует - вы хотите протестировать как можно меньшие единицы, чтобы уменьшить объем любых сбоев как можно меньше.
ПРОБЛЕМА GUI: волшебный Resharper (найдите его) имеет средство запуска тестов для Visual Studio. ЧАСТНАЯ ПРОБЛЕМА: если вы хотите протестировать частный метод, скорее всего, он не должен быть частным - вероятно, извлеченным в отдельный класс и введенным вместо этого. Возможность протестировать частный метод - минус в моей книге.
Даок назвал всех профи тестовых проектов Visual Studio 2008. Вот плюсы NUnit.
Также я считаю, что модульное тестирование VS недоступно в профессиональной версии Visual Studio (по крайней мере, в VS2005 этого не было). Группа MS Patterns and Practices предоставляет как MS, так и NUnit версии своих модульных тестов, поэтому они, очевидно, признают это проблемой для многих из нас, более бедных пользователей!
Кажется, я помню, что в 2008 году все изменилось. Хотя я не уверен. Мой босс дал мне командную версию со всевозможными функциями, которые нельзя игнорировать :-)
По моему опыту, низкая производительность вызвана средством тестирования в VS, а не самой средой тестирования. Вы также можете использовать TestDriven.Net на MSTest, и, насколько я могу судить, производительность сравнима с NUnit.
@Kjetil Klaussen: Это полезная информация, я обновлю свой ответ.
Разве вы не можете просто использовать mstest.exe для запуска тестов MSTest вне среды IDE?
Наличие у Nunit фреймворка для фиксации не является большим преимуществом. Я использовал проекты модульных тестов VS 2008 с фреймворком Moq, который использует новый подход, используя деревья выражений LINQ: code.google.com/p/moq
Еще один плюс для Nunit, во всяком случае для меня, заключается в том, что Resharper имеет очень приятный пользовательский интерфейс, который намного быстрее, чем компоненты тестирования VS. Он даже связывает трассировку стека неудачных тестов с вашим кодом.
@DSO - К вашему сведению, Rhino Mocks 3.5 также поддерживает деревья выражений.
Модульное тестирование включено в профессиональную версию VS 2008.
@Jeff Putz: Resharper также может запускать модульные тесты Visual Studio, даже вне тестового проекта.
NUnit имеет настройку уровня Test и Fixture, а также тестирование на основе строк с TestCase ... Кроме того, у него есть выходной файл xml, который можно агрегировать в CC.net.
Фреймворк модульного тестирования на самом деле не имеет большого значения, потому что вы можете конвертировать тестовые классы с отдельными файлами проекта и условной компиляцией (например, Visual Studio → NUnit):
#if !NUNIT using Microsoft.VisualStudio.TestTools.UnitTesting; #else using NUnit.Framework; using TestClass = NUnit.Framework.TestFixtureAttribute; using TestMethod = NUnit.Framework.TestAttribute; using TestInitialize = NUnit.Framework.SetUpAttribute; using TestCleanup = NUnit.Framework.TearDownAttribute; using TestContext = System.String; using DeploymentItem = NUnit.Framework.DescriptionAttribute; #endif
Плагин TestDriven.Net хорош и не очень дорог ... Имея только простую Visual Studio 2008, вам нужно найти тест из своего тестового класса или списка тестов. С помощью TestDriven.Net вы можете запускать свой тест прямо из класса, который вы тестируете. В конце концов, модульные тесты должны быть простыми в обслуживании и находиться рядом с разработчиком.
Я проголосовал против этого, потому что NUnit имеет более богатый синтаксис, чем MSTest, что означает, что вы можете перейти от MSTest -> NUnit, но не наоборот, если вы не ОЧЕНЬ осторожны. История показывает, что по крайней мере один из нас - нет.
Я согласен с Томасом. Это будет работать, если вы используете самые простые операторы assert, но модель ограничений NUnit является очень мощной и достаточной причиной для выбора NUnit вместо MSTest.
Я считаю, что этот подход используется группой шаблонов и практики ms в тестах EntLib.
Также существуют значительные ограничения, идущие от MSTest -> NUnit. MSTest имеет конструкции (например, PrivateObject) для доступа к закрытым членам класса для тестирования; NUnit этого не делает.
@Dan Neely, если вы тестируете рядовых, вы делаете это неправильно :(
@JDPeckham Когда у вас есть сотни LOC за одним общедоступным методом, выполняющим сложные вычисления (например, проприетарное сжатие с потерями), и никаких внешне значимых промежуточных продуктов, создаваемых частными функциями, получающими хорошее покрытие кода, в то время как только тестирование черного ящика нецелесообразно. Не существует каких-либо основных автоматизированных фреймворков тестирования, не разработанных вокруг концепции модульного тестирования, что оставляет либо использование одного для тестирования частных методов (оскорбление сторонников модульного тестирования, либо предоставление частных методов только для тестирования (и рискуют взломать код потребителей, потому что они пытались использовать методы, которые они не должны)
@JDPeckham Я не говорю, что соглашения о том, что следует / не следует делать с помощью инструмента, не важны, но, в конце концов, выполнение работы является самым важным. Если это означает забивать гвоздь тыльной стороной топора, потому что продавцы инструментов не продают молотки, то производителям топоров просто придется смириться с возмущением.
Теги @ThomasEyde NUnit (Lite) не поддерживаются Visual Studio. В этом случае тесты NUnit (Lite) и MSUnit отображаются в окне Test View.
Прокрутите вниз, чтобы увидеть другой путь (NUnit-> VS) ...
@DanNeely - пуристы не заставили бы электрика проверить проводку в их доме. В конце концов, это личное, а не для потребителей. Просто включите сеть, и если что-то пойдет не так, это не удастся. Сказав, что получение кода в тестируемом состоянии - это хорошо. Единственное, что вы можете сделать, - это создать внутренние классы и предоставить к ним доступ только к вашей тестовой .dll для более глубокого тестирования. Затем вы можете протестировать только общедоступные свойства этих внутренних классов.
xUnit - еще одна возможность для нового проекта. Возможно, у него более интуитивно понятный синтаксис, но он не совсем совместим с другими фреймворками.
Сначала я хочу исправить неправильный оператор: вы можете запустить MSTest вне Visual Studio с помощью командной строки. Хотя некоторые инструменты CI, такие как TeamCity, лучше поддерживают NUnit (вероятно, изменится, когда MSTest станет более популярным).
В моем текущем проекте мы используем и то, и другое, и с единственной большой разницей мы обнаружили, что MSTest всегда работает как 32-битный, а NUnit - как 32-битный или 64-битный тесты, что имеет значение только в том случае, если ваш код использует собственный код, который зависит от 32/64 бит.
Насколько мне известно, в настоящее время для модульного тестирования с .NET доступны четыре фреймворка:
NUnit всегда был впереди, но за последний год или около того разрыв сократился. Я по-прежнему предпочитаю NUnit, тем более что они недавно добавили свободный интерфейс, который делает тесты очень удобочитаемыми.
Если вы только начинаете работать с модульным тестированием, это, вероятно, не имеет большого значения. Как только вы освоитесь, вы сможете лучше понять, какой фреймворк лучше всего подходит для ваших нужд.
Одно небольшое раздражение в среде тестирования Visual Studio заключается в том, что она создает множество файлов тестового запуска, которые, как правило, загромождают каталог вашего проекта, хотя это не так уж и важно.
Кроме того, если у вас нет такого плагина, как TestDriven.NET, вы не можете отлаживать свои модульные тесты NUnit (или MbUnit, xUnit и т. д.) В среде Visual Studio, как это можно сделать с помощью встроенной среды тестирования Microsoft Visual Studio.
Вы можете отлаживать тестирование NUnit в Visual Studio 2005.
Вы также можете отлаживать xunit, но не очевидно, как это настроить (страница свойств)
Вы можете легко отлаживать NUnit, подключив отладчик к запущенному процессу NUnit, как сказал Гримус. Здесь нет реального недостатка.
1: Количество тестов, настраиваемых в настройках VS - я установил его равным единице. 2: Согласитесь с приведенными выше комментариями - возможно, но неудобно, 3: В целом, я предпочитаю встроенную среду тестирования VS.
Преимущества / изменения встроенной среды модульного тестирования Visual Studio 2008:
Я действительно думаю, что это все еще говорит о взгляде Microsoft на тестирование, что оно НЕ в стандартной версии, а только в версии Professional и выше.
Согласитесь, хотелось бы увидеть его в стандарте и выше. В экспресс-версиях для новичка будет перебор.
@J Wynia: Чтение их решения включить его только в Professional и выше как высказывание чего-то об их взгляде на тестирование - это слишком много для него. Это скорее бизнес-решение, чем философское.
@Simara Тестирование должно быть неотъемлемой частью жизненного цикла разработки. Он должен быть предоставлен в экспресс-изданиях.
Немного не по теме, но если вы выберете NUnit, я могу порекомендовать использовать ReSharper - он добавляет несколько кнопок в пользовательский интерфейс Visual Studio, которые значительно упрощают запуск и отладку тестов из среды IDE.
Этот обзор немного устарел, но объясняет это более подробно:
Использование ReSharper как неотъемлемой части вашего набора инструментов TDD
С плагином Gallio для R # вы также можете запускать MSTest.
CodeRush помещает значки в тесты прямо в коде, поэтому вы можете запустить один тест или все тесты в классе или в пространстве имен. Смотрите здесь: community.devexpress.com/blogs/markmiller/archive/2009/11/16 /…
Resharper также будет запускать тесты MSTest.
MSTest - это, по сути, немного переработанный NUnit с несколькими новыми функциями (такими как настройка и разборка сборки, а не только фиксация и тестовый уровень), и в нем отсутствуют некоторые из лучших элементов (например, новый синтаксис ограничений 2.4). NUnit более зрелый, и его больше поддерживают другие поставщики; и, конечно же, поскольку он всегда был бесплатным (тогда как MSTest вошел только в Профессиональную версию Visual Studio 2008, а до этого он был более дорогим SKU), и большинство проектов ALT.NET используют его.
Сказав это, есть некоторые компании, которые невероятно неохотно используют что-то, на чем нет ярлыка Microsoft, и особенно код OSS. Таким образом, наличие официальной среды тестирования Microsoft может быть мотивацией, необходимой этим компаниям для прохождения тестирования; и давайте будем честными, важно именно тестирование, а не то, какой инструмент вы используете (а с помощью Код Туомаса Хиетанена вы почти можете сделать свою тестовую среду взаимозаменяемой).
Мне нравится синтаксис ограничений NUnit, но я думаю, вы должны прочитать это относительно атрибутов SetUp и TearDown: jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html
Что такое "Артикул"? Полагаю, это не Коммунистический союз молодежи Швеции (Sveriges Kommunistiska Ungdomsförbund).
@PeterMortensen - это подразделение по хранению запасов, по-видимому, для отслеживания запасов - в данном случае инвентарь программных продуктов. Таким образом, каждая версия Visual Studio имеет свой собственный SKU - один для Professional, один для Enterprise.
Но, может быть, молодые шведские коммунисты любят продукты Microsoft больше, чем большинство людей?
Я получил сообщения, что "файловая структура NUnit богаче, чем VSTest" ... Конечно, если вы предпочитаете файловую структуру NUnit, вы можете использовать это решение другим способом, например (NUnit → Visual Studio):
#if !MSTEST
using NUnit.Framework;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestFixture = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute;
using Test = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
using SetUp = Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute;
using TearDown = Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute;
#endif
Или любое другое преобразование ... :-) Это использование здесь просто псевдоним компилятора.
Я не понимаю, о чем вы здесь говорите.
нет настройки / разборки уровня приспособлений :( или они предполагают, что мы используем ctor и dtor?
Моя основная проблема с модульными тестами Visual Studio над NUnit - это создание тестов Visual Studio, как правило, вводит кучу сгенерированного кода для доступа к частным членам.
Кто-то может захотеть протестировать свои частные методы, а кто-то нет. Это другая тема.
Меня беспокоит то, что когда я пишу модульные тесты, они должны строго контролироваться, чтобы я точно знал, что я тестирую и как именно это тестирую. Если есть автоматически сгенерированный код, я теряю часть этих прав.
Я бы предпочел использовать небольшую тестовую среду MS, но пока придерживаюсь NUnit. Проблемы с MS обычно (для меня)
Предостережения
Мне намного проще просто написать свои тесты и запустить NUnitGUI или один из других интерфейсов (testDriven намного дороже). Настроить отладку с версией командной строки также довольно просто.
Прямо сейчас я использую Resharper для запуска тестов MS, поэтому я не возражаю против них. Я предпочитаю CodeRush + RefactorPro, хотя мы здесь не используем его. Может быть, у них теперь есть достойный бегун для MS Test.
Я начал с MSTest, но перешел по одной простой причине. MSTest не поддерживает наследование методов тестирования из других сборок.
Мне не нравилась идея писать один и тот же тест несколько раз. Особенно в большом проекте, где методы тестирования могут легко превратиться в сотни тестов.
NUnit делает именно то, что мне нужно. Единственное, что отсутствует в NUnit, - это надстройка Visual Studio, которая может отображать красный / зеленый статус (например, VSTS) каждого теста.
Я сделал несколько TDD, используя оба и (может быть, я немного тупой) NUnit кажется мне намного быстрее и проще в использовании. И когда я говорю много, я много имею в виду.
В MSTest слишком много атрибутов повсюду - код, который выполняет настоящие тесты, представляет собой крошечные строчки, которые вы можете прочитать здесь и там. Большой беспорядок. В NUnit код, выполняющий тест, просто доминирует над атрибутами, как и должно быть.
Кроме того, в NUnit вам просто нужно щелкнуть тесты, которые вы хотите запустить (только один? Все тесты, охватывающие класс? Сборка? Решение?). Один клик. И окно ясное и большое. Вы получите четкие зеленый и красный свет. Вы действительно знаете, что происходит с одного взгляда.
В VSTS список тестов забит внизу экрана, он маленький и некрасивый. Вам нужно дважды посмотреть, чтобы узнать, что произошло. И нельзя запустить только один тест (ну я еще не узнал!).
Но я, конечно, могу ошибаться - я только что прочитал около 21 сообщения в блоге на тему «Как сделать простой TDD с помощью VSTS». Я должен был прочитать больше; ты прав.
Для NUnit я прочитал один. И в тот же день я был в TDD. С удовольствием.
Кстати, я обычно люблю продукты Microsoft. Visual Studio - действительно лучший инструмент, который может купить разработчик, но управление TDD и рабочими элементами в Visual Studio Team System - отстой.
Если вы рассматриваете MSTest или NUnit, я рекомендую вам взглянуть на MbUnit. Мои причины
using.Изначально я выбрал MbUnit из-за его функциональности [RowTest ....] и не нашел ни одной причины для возврата. Я переместил все свои активные наборы тестов из NUnit и никогда не оглядывался назад. С тех пор я обратил на преимущества две разные команды разработчиков.
Мне не нравится встроенная среда тестирования Visual Studio, потому что она заставляет вас создавать отдельный проект, а не проводить тесты как часть проекта, который вы тестируете.
На самом деле вы можете обмануть Visual Studio, вручную отредактировав файлы проекта и добавив в значения ProjectTypeGuids, которые используются для идентификации тестовых проектов: & lt; ProjectTypeGuids & gt; {3AC096D0-A1C2-E12C-1390-A8335801FDA B}; {FAE04EC0-301F- 11 D3-BF4B-00C04F79EFBC} & lt; / ProjectTypeGui ds & gt;
С выпуском Система кодовых контрактов в .NET 4.0 и доступностью статическая проверка теоретически потребуется писать меньше тестовых примеров, и такой инструмент, как Pex, поможет идентифицировать эти случаи. В связи с обсуждаемым вопросом, если вам нужно меньше делать с модульными тестами, потому что ваши контракты закрывают ваш хвост, то почему бы просто не пойти дальше и не использовать встроенные части, поскольку это одна зависимость, которую нужно контролировать. В наши дни я люблю простоту. :-)
Смотрите также:
Интересно, как я могу протестировать частную функцию с помощью VS? Я нашел единственный способ сделать его общедоступным. Есть другой способ?