Разделы портала

Онлайн-тренинги

.
Введение в юнит тестирование в 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. Запись скриптов для веб тестирования
  3. Управление ручными тестами
  4. Нагрузочное тестирование

И многое другое.

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 Создание ссылки на тестовый проект

  1. Solution Explorer -> TestMathLib -> контекстное меню -> Add Reference
  2. Projects
  3. Выбрать проект MathLib

Рисунок 3. Добавление ссылки на тестируемый проект.

3. Тестирование

Перед нами встают вопросы:

  • Как организовать тесты: «Каждый в своем файле», «Все в одном»?

Попробуем и тот и другой подходы.

  • Использовать ли ручное тестирование?

Удалим ручной тест. В этом проекте мы ничего руками тестировать не будем.

  • Как именовать тесты?

У каждого свой взгляд на соглашение об именах. Я предложу следующий подход: тестовый класс должен содержать указания на тестируемую функциональность и класс эквивалентности. Тестовый метод должен явно указывать на класс эквивалентности. Идеальный вариант — код понятен без комментариев.

3.1 Первый тест

Переименуем заготовку в SimpleFactorial.sc [см. приложенные исходные файлы]

Добавим using MathLib;

Удалим «#region Additional test attributes». Нам не нужно ничего инициализировать и не нужно ничего удалять после проведения теста.

Проведем тест на равенство:

  • 5!==120

Код:

 using System; 
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MathLib;
 namespace TestMathLib 
{
[TestClass]
public class SimpleFactorial
{
     public SimpleFactorial()
     {
     }
          [TestMethod] 
          public void TestSimpleCalc()
          {
               IFactorial factorial = FactorialProvider.CreateInstance( FactorialType.Simple);
               Assert.AreEqual(120L, factorial.Calculate(5));
          }
     }
}

Пояснения:

  • [TestMethod] — Указание, что это тестовый метод, и он должен отображаться в менеджере тестов.
  • Assert.AreEqual () — Сравнение возвращаемого результата с эталонным.

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 — нет.

Число не пройденных блоков считается следующим образом:

  • if(number < 0 || number > 15) — 1 раз
  • throw new ArgumentOutOfRangeException("number"); — 2 раза
  • return 1L; — 1 раз

3.2 Продолжение тестирования

Тестирование граничных условий простого факториала

Новый тест

Создадим новый тест.

  • Solution Explorer -> TestMathLib -> Add... -> New test... -> Unit Test
  • Введем название: SimpleFactorialBoundTest.cs

Введем тесты на граничные условия (код смотри в приложении).

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

[ExpectedException( typeof( ArgumentOutOfRangeException))]

Больше ничего нового для написания тестов нам не понадобится.

3.2.2 Использование менеджера тестов

Тестов стало больше, и теперь нам необходимо средство управления.

  1. Test -> Windows -> Test Manager

Перед нами все наши тесты. Заметим, что не имеет никакого значения, в одном файле они созданы или в разных.

Сгруппируем тесты по тестируемой функциональности.

  1. Создадим списки для простого и двойного факториала
  2. Выделим тесты, относящиеся к тестированию простого факториала (сейчас это все тесты).
  3. Перенесем их в нужную папку методом drag&drop.

Выполним наши тесты.

  1. Укажем тесты, которые мы хотим выполнить. Взведем чекбокс «List of Tests»

    Рисунок 7. Пометка тестов, которые необходимо выполнить.
  2. Запустим тесты Ctrl+Shift+X

Результат: все тесты для простого факториала прошли, в коде вычисления простого факториала не осталось не оттестированных участков.

3.3 Дополнительные функции

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

Выстроим следующую шкалу приоритетов:

  • 0 — неустановлен (по умолчанию)
  • 1— минимальный
  • 2 — средний
  • 3 — максимальный

В окне свойств, зададим приоритет «3» для простого теста, «2» для тестов вне границ и «1» для прочих. Теперь мы можем запускать в качестве приемочных тестов только тесты с наивысшим приоритетом.

Рисунок 8. Группировка тестов по приоритетам.

Обратите внимание, на изменение кода. [TestMethod] изменился на [Priority(2), TestMethod]. Если кому-то удобней задавать приоритеты сразу в коде, то никто не мешает делать так.

4. Заключение

В новой студии появились прекрасные средства для модульного тестирования. Я даже осмелюсь высказать крамольную мысль: «NUnit умер». Действительно очень удобно. Все в одном месте, все жизненно необходимые функции есть. Легко тестировать, легко отлаживать. Конечно, мне как закоренелому критику некоторые вещи не нравятся (скорее, пока еще непонятны), но мне всегда что-нибудь не нравится.

Приложение