Каждый мастер должен иметь в своём арсенале надёжные и удобные инструменты. И для тестирования .NET приложений инструментов много MSTest, NUnit, MbUnit, XUnit и даже свой DSL для написания тестов – T#. Список не полный, но думаю понять объёмы популярности тестирования достаточно. Я не собираюсь устраивать сравнения между ними, слишком много для этого надо написать. Но для начала я бы рекомендовал NUnit. Он наиболее популярен в .NET мире, и наиболее прост для начинающего (опытные смогут выбрать сами ). Просто скачайте установщик с официального сайта, подключите к проекту ссылку на nunit.framework.dll. Всё готово для первого теста. Допустим, мы делаем класс, реализующий функционал работы с версиями. У класса есть четыре целочисленных свойства Major, Minor, Build и Revision. Конструктор класса должен принимать разделённую точками строку, как это принято в AssemblyVersionAttribute. Тогда тест может выглядеть вот так:
[TestFixture]public class VersionFixture{[Test]public void Constructor_parses_string_properly(){var version = new Version("1.2.330.400");//Обратите внимание, все сообщения консоли будут выведены в GUI NUnit
//Часто таким способом полезно "логгировать" прохождене теста
Console.WriteLine("Major={0} Minor={1} Build={2} Revision = {3}", version.Major, version.Minor, version.Build, version.Revision);
Assert.AreEqual(1, version.Major);Assert.AreEqual(2, version.Minor);Assert.AreEqual(330, version.Build);Assert.AreEqual(400, version.Revision);}}
Скомпилируйте проект, запустите NUnit, откройте скомпилированную dll с тестами, и жмите кнопку Run. В итоге должны увидеть нечто подобное:
Ошибочка, тест не прошёл. NUnit показывает, на какой строке произошла ошибка. Видимо я ошибся в “парсере” строки. Ладно, поправим код и попробуем запустить еще раз:
Так гораздо лучше! Я нашёл ошибку в процессе подготовки кода примеров для этого сообщения.
Тесты выше можно переписать с помощью нового FluentAPI NUnit:
Список ниже не полный, но содержит наиболее часто используемые атрибуты:[TestFixture]public class VersionFixture{[Test]public void Constructor_parses_string_properly_with_fluent_API(){var version = new Version("1.2.330.400");//Обратите внимание, все сообщения консоли будут выведены в GUI NUnit
//Часто таким способом полезно "логгировать" прохождене теста
Console.WriteLine("Major={0} Minor={1} Build={2} Revision = {3}", version.Major, version.Minor, version.Build, version.Revision);
Assert.That(version.Major, Is.EqualTo(1));Assert.That(version.Minor, Is.EqualTo(2));Assert.That(version.Build, Is.EqualTo(330));Assert.That(version.Revision, Is.EqualTo(400));}}
- TestFixture – Используется NUnit’ом для поиска классов тестов в сборке.
- TestFixtureSetUp – метод выполняется один раз перед всеми тестами.
- SetUp – метод выполняется перед каждым тестом.
- Test – обозначает метод-тест.
- TearDown - метод выполняется после каждого теста.
- TestFixtureTearDown - метод выполняется один раз после всех тестами.
- Ignore – не выполнять тест. Можно помечать методы класс.
- Explicit – тест выполнится только при явном запуске из GUI. Можно помечать методы и класс.
NUnit создаёт один экземпляр класса, отмеченного атрибутом TestFixture, и использует его для всех тестов в этом классе. Поэтому важно перед каждым тестом инициализировать и очищать состояние класса. Это можно сделать с помощью атрибутов Setup/Teardown TestFixtureSetUp/TestFixtureTearDown.
Иногда тест долго не удаётся сделать “зелёным”. Тогда можно временно исключить его из набора тестов с помощью атрибута Ignore. Почему просто не закомментировать? Потому что с атрибутом NUnit выдаст информативное сообщение, какие тесты временно отключены. Это хорошее напоминание – такие тесты надо как можно скорее приводить в рабочее состояние, и убирать атрибут Ignore. Explicit делает то же самое. Его применяют для демонстрации явных намерений “этот тест выполнятся, только если именно его и хотят запустить”.
Отличное описание атрибутов и Assert-методов есть в статье про NUnit 2.5. Настойчиво рекомендую ее изучить, и периодически заглядывать. Знание возможных вариантов будет весьма полезных для выбора наиболее подходящего к конкретному случаю, и позволит существенно упростить код тестов.
Не сводите все тесты к вызову Assert.True()/Assert.False(), например так:
[TestFixture]public class VersionFixture{[Test]public void Constructor_parses_string_properly_in_the_wrong_way(){var version = new Version("1.2.330.400");//Обратите внимание, все сообщения консоли будут выведены в GUI NUnit
//Часто таким способом полезно "логгировать" прохождене теста
Console.WriteLine("Major={0} Minor={1} Build={2} Revision = {3}", version.Major, version.Minor, version.Build, version.Revision);
//Так делать очень плохо, т.к.. в итоге сообщение об ошибке будет невыразительным
Assert.IsTrue(version.Major == 1);Assert.IsTrue(version.Minor == 2);Assert.IsTrue(version.Build == 330);Assert.IsTrue(version.Revision == 400);}}
В этом случае будет ничего не говорящее о сути происходящего сообщение:
Expected: True
But was: False
Используйте подходящий случаю Assert-метод (или его FluentAPI аналог). Не ленитесь, напишите несколько строк в сообщение об ошибке в методе Assert. В случае сломанного теста это сообщение сильно облегчает понимание проблемы.
Еще один штрих – все мы любим работать в Visual Studio, и хотелось бы запускать тесты прямо из IDE. Решений много, могу лишь упомянуть Resharper, TestDriven.Net, и еще бесплатный Visual NUnit 2010. Совсем простой вариант – настроить запуск NUnit как External Tool. (Кстати, таким образом можно еще и отлаживать код тестов).
Для вступления в автоматизированное тестирование достаточно. Код примеров здесь. Берите NUnit в руки, и смелее к тестам. В следующий раз расскажу о нескольких более продвинутых инструментах для тестирования.
Комментариев нет:
Отправить комментарий