Введение в юнит тестирование в VisualStudio 2005 Team Suite |
29.09.2008 13:11 |
Автор: Сергей Мартыненко Статья написана в стиле «Давайте начнем». На простом примере рассматривается модульное тестирование в среде VisualStudio 2005 Team Suite. Исходная задача: Требуется создать библиотеку для вычисления факториалов. Для работы нам понадобится VisualStudio 2005 Team Suite. VisualStudio 2005 Express Edition или VisualStudio 2005 Professional не поддерживает модульное тестирование. Никакой глубины или широты обзора не предполагается. В данной статье не рассматривается стратегия «Разработки Ведомой Тестированием», стратегия тестирования, подходы к написанию тестов и многое другое. В стороне остались такие интересные вещи как:
И многое другое. 1.2 Исходная задачаТребуется создать библиотеку для вычисления факториалов. Библиотека должна вычислять:
Библиотека должна выдавать исключение, в случае выхода за пределы допустимого диапазона. Библиотека должна вычислять 0! и 0!! Библиотека должна возвращать длинное целое. Библиотека должна возвращать значение двойной точности, с плавающей запятой в случае больших целых. В этом случае вычисление проводится по формуле Стирлинга. (в первой версии не реализуется) Правила вычисления согласно: http://ru.wikipedia.org/wiki/ 1.3 Средство разработкиДля работы нам понадобится VisualStudio 2005 Team Suite. VisualStudio 2005 Express Edition или VisualStudio 2005 Professional не поддерживает модульное тестирование . 1.4 ПроектТестируемы проект MathLib. Исходный код в приложении. Почему именно так, а не по другому в данной статье не рассматривается. Данный код разрабатывался с использованием TDD, но сейчас мы пойдем другим путем. Будем считать, что код уже есть и его надо оттестировать. 2. Подготовка к тестированию2.1 Создание проекта тестирования в солюшенеFile -> New -> Project Рисунок 1. Создание тестового проекта. Не забудьте указать имя проекта (согласно соглашению о наименованиях, в качестве имени тестового проекта берут имя тестируемого проекта и добавляют префикс «Test») и выбрать опцию «Добавить в проект». Рисунок 2. Создание тестового проекта. Шаг два. Будет создан проект тестирования с заготовками тестов. Проект тестирования можно создать другими способами (см. документацию). Но я всегда следовал простой логике: сначала создаем контейнер, потом наполнение. 2.2 Создание ссылки на тестовый проект
Рисунок 3. Добавление ссылки на тестируемый проект. 3. ТестированиеПеред нами встают вопросы:
Попробуем и тот и другой подходы.
Удалим ручной тест. В этом проекте мы ничего руками тестировать не будем.
У каждого свой взгляд на соглашение об именах. Я предложу следующий подход: тестовый класс должен содержать указания на тестируемую функциональность и класс эквивалентности. Тестовый метод должен явно указывать на класс эквивалентности. Идеальный вариант — код понятен без комментариев. 3.1 Первый тестПереименуем заготовку в SimpleFactorial.sc [см. приложенные исходные файлы] Добавим using MathLib; Удалим «#region Additional test attributes». Нам не нужно ничего инициализировать и не нужно ничего удалять после проведения теста. Проведем тест на равенство:
Код: using System;
namespace TestMathLib [TestMethod] Пояснения:
3.1.1 Прогон тестаЗапустим наш тест. Shift+Alt+X. Также тест можно запустить через панель инструментов или главное меню: Test-> Start Selected Test Project with Debugger . 3.1.2 Результаты прогонаЧерез некоторое время получаем результат. Успешно пройден один тест. Рисунок 4. Результат первого тестирования. Кроме того, мы видим закладку «Code Coverage Results» (покрытие кода). Рисунок 5. Покрытие кода первым тестированием. Посмотрим, какие участки кода не были пройдены. Двойным щелчком на методе, откроем файл SimpleFactorial.cs [см. приложенные исходные файлы] Рисунок 6. Просмотр участков кода, непокрытых тестами. Красным показаны не покрытые участки кода, розовым — частично покрытые. Так проверка number < 0 была сделана, проверка number > 15 — нет. Число не пройденных блоков считается следующим образом:
3.2 Продолжение тестированияТестирование граничных условий простого факториала Новый тестСоздадим новый тест.
Введем тесты на граничные условия (код смотри в приложении). Т.к. мы тестируем выход за границы, одним сравнением полученного результата с эталонным нам не обойтись. При выходе за границы ожидается не значение, а исключение. Воспользуемся методом ожидания исключения: [ExpectedException( typeof( ArgumentOutOfRangeException))] Больше ничего нового для написания тестов нам не понадобится. 3.2.2 Использование менеджера тестовТестов стало больше, и теперь нам необходимо средство управления.
Перед нами все наши тесты. Заметим, что не имеет никакого значения, в одном файле они созданы или в разных. Сгруппируем тесты по тестируемой функциональности.
Выполним наши тесты.
Результат: все тесты для простого факториала прошли, в коде вычисления простого факториала не осталось не оттестированных участков. 3.3 Дополнительные функцииТесты занимают некоторое время. При большом количестве тестов есть желание прогонять только часть. Один из способов — группировка по функциональности, другой способ — группировка по приоритетам. Выстроим следующую шкалу приоритетов:
В окне свойств, зададим приоритет «3» для простого теста, «2» для тестов вне границ и «1» для прочих. Теперь мы можем запускать в качестве приемочных тестов только тесты с наивысшим приоритетом. Рисунок 8. Группировка тестов по приоритетам. Обратите внимание, на изменение кода. [TestMethod] изменился на [Priority(2), TestMethod]. Если кому-то удобней задавать приоритеты сразу в коде, то никто не мешает делать так. 4. ЗаключениеВ новой студии появились прекрасные средства для модульного тестирования. Я даже осмелюсь высказать крамольную мысль: «NUnit умер». Действительно очень удобно. Все в одном месте, все жизненно необходимые функции есть. Легко тестировать, легко отлаживать. Конечно, мне как закоренелому критику некоторые вещи не нравятся (скорее, пока еще непонятны), но мне всегда что-нибудь не нравится. Приложение
|