Как стать автором
Обновить
0

Собственные шаблоны тестов CodeRush. Тестируем порядок вызовов методов

Время на прочтение4 мин
Количество просмотров8.1K
В своей работе нам приходится писать много тестов. Чтобы делать это быстро, мы используем шаблоны CodeRush. В этой статье мы расскажем вам, как создавать собственные шаблоны для тестирования. В качестве примера возьмём такую задачу: протестировать правильный порядок вызовов защищенных методов класса. Будем использовать только NUnit без применения библиотек типа NMock и им подобных.




Объект для тестирования


Итак, начнём с подопытного объекта. Напишем простой класс, содержащий несколько методов и имеющий определённый порядок их вызовов.
public class SimpleClass {
   public void DoAction() {
       BeforeAction();
       try {
           DoActionCore();
       }
       finally {
           AfterAction();
       }
   }
   protected virtual void BeforeAction() { }
   protected virtual void AfterAction() { }
   protected virtual void DoActionCore() { }
}


В даннном классе необходимо проверить, что в результате вызова метода DoAction гарантированно будут выполнены методы BeforeAction, DoActionCore и AfterAction в нужной последовательности и нужное количество раз.

Тестирование будем основывать на написании наследника класса SimpleClass, который при вызове определенного метода будет фиксировать, что данный метод был вызван. Для простоты, в качестве trace-объекта возьмем обычную строку и будем дописывать туда имя вызванного метода. В тесте будем сверять полученную строку с ожидаемым результатом.

Определим соглашение по именованию таких классов как TestИмя_Исходного_Класса. Этим мы упростим себе написание шаблона для тестов.

Настройка шаблонов


Кратко о шаблонах CodeRush: они позволяют быстро вставлять часто используемые фрагменты кода в редакторе, следуя определённым правилам подстановки имен, форматированию и т.д. Они сродни code-snippets, но отличаются от них бОльшей интеллектуальностью, предоставляя ряд преимуществ, таких как контексты применения, способность анализировать существующий код, наличие команд, провайдеров строк, филдов, линков и прочее.

Теперь приступаем к написанию собственного шаблона для наследника класса, содержащего trace-строку. Откроем окно настроек, перейдём в группу Editor -> Templates, группу опций для NUnit. Заметим, что CodeRush уже содержит предопределённый набор шаблонов для написания NUnit-тестов, но нам необходимо создать другой.



Рис.1 — Создание нового шаблона для NUnit

Зададим шаблону короткое имя, например, stu (от stub-class) и напишем тело шаблона. Спроектируем шаблон таким образом, что при его активации имя исходного класса будет храниться в буфере обмена и после вставки будет создан код, отражающий определённые выше правила для имен.
#region Test«Paste» (stub class)
public class Test«Paste» :«Paste» {
 string trace = string.Empty;
 public  Test«Paste»(«Caret») : base() {
 }
 public string Trace { get { return trace; } set { trace = value; } }
}
#endregion



Рис. 2 — Написание тела шаблона, используя предопределенные команды

При написании шаблона используем предопределённый набор команд, выбирая их их списка. Такими командами здесь являются «Paste» и «Caret».


Теперь важно указать, где этот шаблон может выполняться. Для этого настроим параметры использования Use, установив необходимые значения. Укажем для него параметр Line.OnEmptyLine.



Рис. 3 — Задание областей использования шаблона

Аналогично первому, напишем шаблон atr (add trace) для добавления trace-строки в метод.
trace += "->«Member»";
«Caret»

В данном случае имя текущего метода будет автоматически вставляться при активации шаблона и нет необходимости предварительно копировать его в буфер обмена. Зададим такие области использования шаблона как InClass, InMethod



Рис. 4 — Шаблон для вставки trace-строки

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

Пишем тесты быстро


Как это всё работает? Попробуем написать тест для SimpleClass.

Нам необходим класс-наследник для тестов. Скопируем в буфер обмена имя SimpleClass и напечатаем stu. На месте курсора вставится шаблон для наследуемого класса, содержащий свойство Trace.



Рис. 5 — Активация шаблона и вставка кода


Теперь добавим trace-информацию для каждого интересующего нас метода. Для этого перекроем эти методы. В Visual Studio для этого наберем «over», затем нажмем пробел и выберем нужные имена методов из выпавшего списка, при этом поблагодарив IntelliSense за то, что вам не пришлось мучительно вспоминать их названия. В результате все необходимые методы перекрыты и пока просто вызывают базовые.


Теперь самое время включить в работу наш шаблон atr. Пройдёмся по этим методам, активируем шаблон для вставки trace-строки. В результате мы получим методы, которые будут добавлять к свойству Trace свое имя после вызова.

#region TestSimpleClass (stub class)
public class TestSimpleClass : SimpleClass {
   string trace = string.Empty;
   public TestSimpleClass()
       : base() {
   }
   public string Trace { get { return trace; } set { trace = value; } }
 
   protected override void BeforeAction() {
       base.BeforeAction();
       trace += "->BeforeAction";
   }
   protected override void AfterAction() {
       base.AfterAction();
       trace += "->AfterAction";
   }
   protected override void DoActionCore() {
       base.DoActionCore();
       trace += "->DoActionCore";
   }
}
#endregion
 


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


Вернёмся непосредственно к тесту. Создадим TextFixture для группы тестов нашего класса. Кстати, для ускорения её создания вы можете также написать свой шаблон, который будет включать в себя методы для SetUp и TearDown. Объявим экземпляр нашего класса-наследника, проинициализируем его и напишем тест на метод DoAction. Тест будет заключаться в сравнении свойства Trace класса-наследника после вызова метода с ожидаемым результатом, который отражает правильную последовательность вызовов защищенных методов класса.

#region SimpleClassTests
[TestFixture]
public class SimpleClassTests {
   TestSimpleClass testClass;
   
   [SetUp]
   public void Setup() {
       testClass = new TestSimpleClass();
   }
   [TearDown]
   public void Teardown() {
       testClass = null;
   }
   [Test]
   public void DoActionMethod() {
       testClass.Trace = string.Empty;
       testClass.DoAction();
       string expectedTrace = "->BeforeAction->DoActionCore->AfterAction";
       Assert.AreEqual(expectedTrace, testClass.Trace);
 
   }
}
#endregion


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


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


Удачи в создании удобных шаблонов тестирования!
Теги:
Хабы:
+29
Комментарии22

Публикации

Изменить настройки темы

Информация

Сайт
www.developersoft.ru
Дата регистрации
Дата основания
1998
Численность
201–500 человек
Местоположение
Россия

Истории