Тестирование кода в Delphi
Представляю вашему вниманию модуль для тестирования кода Delphi <utests.pas>. Это результат долгих попыток найти некий баланс между "лишней" работой по созданию тестовых приложений и необходимостью тщательного тестирования кода, попыток собрать код и тестовые методы для него в одном месте чтобы минимизировать работу при рефакторинге кода, попыток максимально уменьшить код, требующийся для тестирования.

Прежде чем критиковать (зачем нужен еще один модуль для тестирования) или сравнивать с другими системами тестирования, давайте рассмотрим полный цикл тестирования и основные возможности этого модуля. Далее вы уже сами для себя решите стоит ли читать дальше, а тем более использовать этот модуль.

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

pascal
unit testClass1;
interface

uses Classes;

type
   TMyClass = class
   public
      function isPrime(N:integer) : boolean;
   end;

implementation

function TMyClass.isPrime(N:integer) : boolean;
var i:integer;
begin
   //result := false;
   //if N <= 1 then exit;
   result := true;
   if N <= 3 then exit;
   for i := 2 to trunc(sqrt(N)) do begin
      if N mod i = 0 then begin
         result := false;
         break;
      end;
   end;
end;

end.

comment
Первые две строки методы закомментированы специально. В связи с этим метод будет возвращать неправильное значение для чисел ≤ 1. Оставим в стороне эффективность такой проверки чисел на простоту, т.к. сейчас это не самое важное.

Подключим модуль utests и напишем для этого класса тестирующий метод. Вместе с кодом для тестирования получится следующее:

Здесь мы добавили тестирующий метод test_isPrime. Префикс test_ - это указание модулю тестирования, что нужно вызвать метод. В секции инициализации класс зарегистрирован для тестирования. Весь тестовый код заключен в условные директивы.

Теперь осталось вызван метод для тестирования кода. Для этого откроем исходный файл проекта и добавим первым вызовом (перед Application.Initialize)

pascal
   {$ifdef test}
   tests.Execute;
   {$endif}

Вот и все, что нужно сделать для подготовки тестирования. Теперь выполним наше приложение. При выполнении вызывается метод tests.Execute. Этот метод для всех зарегистрированных классов выполняет следующую последовательность действий:

  • При регистрации класса мы указали путь и имя файла, в котором находится его код. Сначала проверяется были ли изменения этого файла со времени последнего тестирования. Если последнее тестирование прошло успешно и файл не менялся, тестирование этого класса не производится.
  • Создается экземпляр тестируемого класса и последовательно вызываются все его методы, начинающиеся с префикса test_.

Как видите, у нас только один такой метод. При его вызове будут выполнены ряд вызовов tests.test. Это простое сравнение результата вызова isPrime с true. Если метод возвращает false, тест считается непройденным. (на самом деле алгоритм работы более сложный, но пока достаточно считать так).

Информация о неуспешных тестах выводится в окно Event log IDE. Более полная информация пишется в текстовый файл errors.txt. Посмотрим что у нас в этом файле:

output
 28.03.2010 20:36 Message : +TMyClass
 28.03.2010 20:36 Message : TMyClass.test_isPrime
 28.03.2010 20:36 Error   : [Pair  1]=[false]
                                  req=[true]
 28.03.2010 20:36 Error   : [Pair  2]=[false]
                                  req=[true]
                            
                  --------: VER180 Running: 1 Passed: 0 not Passed: 1
                  --------: Programm done. Started at : 28.03.2010 20:36:30 ------------------------

Первые две строки - это название тестируемого класса и тестирующего метода. Далее следуют две ошибки (в парах 1 и 2 метод вернул false, а предполагалось, что должно быть true). Последние строки - это просто информация о количестве методов и времени выполнения.

Кратко перечень других возможностей модуля:

Вызовы Assert() могут использоваться в тестирующих методах. Генерация Assertion failure при выполнении считается ошибкой и тест помечается как непройденный.

В лог-файл записывается информация обо всех исключениях.

Модуль позволяет анализировать время выполнения методов.

Модуль позволяет отслеживать правильность распределения памяти.

Запись в log-файл информации об исключениях можно использовать не только во время тестирования, но и в окончательной версии программы.

Модуль позволяет делать профилировку кода.

  Изменения 

Downloads
Модуль utests.pas v.1.02 (tests.zip) (8.7 Кб, просмотров: 615 )

Comments
15.10.2011 11:23 lizametrika
 Хороший сайт, отличный материал. Обновляйте почаще.
 
Вы можете оставить комментарий или задать вопрос
Ваше имя:

Текст сообщения:


Copyright © 2009-2014 by