Опубликован: 25.07.2012 | Уровень: специалист | Доступ: платный
Лекция 8:

Применение генераторов кода

< Лекция 7 || Лекция 8: 12 || Лекция 9 >

Пример генерации документации совместно с кодом

В этом варианте генерация документации выполняется параллельно с генерацией кода. Из шаблонов, метаданных и правил предметной области одновременно с кодом генерируется текст документации. Комментарии должны быть включены в метаданные. Документация может генерироваться в форматах HTML, Word, PDF и других.

Рассмотрим пример. Пусть мы имеем следующий файл метаданных:

<?xml-stylesheet type="text/xsl" href="packagecomments.xsl"?>
<packages>
  <package name="pkg_book">
    <comment>
      <![CDATA[ Пакет для выполнения операций над таблицей tbl_book.
        Он делает много хороших вещей.]]>
    </comment>
    <procedure name="SetValues" type="procedure">
      <comment>
        <![CDATA[ Служит для установки значений по идентификатору.]]>
      </comment>
      <parameters>
        <param name="ID" type="number"/>
        <param name="title" type="varchar2"/>
        <param name="author" type="varchar2"/>
      </parameters>
    </procedure>
    <procedure name="GetTitle" type="function">
      <comment>
        <![CDATA[ Служит для извлечения названия книги по идентификатору.]]>
      </comment>
      <parameters>
        <param name="ID" type="number"/>
      </parameters>
    </procedure>
    <procedure name="GetAuthor" type="function">
      <comment>
        <![CDATA[ Служит для извлечения имени автора по идентификатору.]]>
      </comment>
      <parameters>
        <param name="ID" type="number"/>
      </parameters>
    </procedure>
  </package>
</packages>
    
Пример 7.1.

В приведенном XML-файле содержатся данные о процедурах пакета вместе с параметрами. Для каждой процедуры и для каждого пакета даются комментарии, которые будут включены в программный код, а также в отдельный файл документации. Дан следующий файл стиля:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>
  <xsl:template match="packages/package">
    --<xsl:value-of select="comment"/><br/>
    create or replace package <xsl:value-of select="@name"/>
    <br/><br/>
    <xsl:for-each select="procedure">
      --<xsl:value-of select="comment"/><br/>
      <xsl:choose>
        <xsl:when test ="@type='procedure'">procedure </xsl:when>
        <xsl:otherwise>function </xsl:otherwise>
      </xsl:choose> 
      <xsl:value-of select="@name"/>
      (<xsl:for-each select="parameters/param">
        <xsl:value-of select="@name"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="@type"/>
        <xsl:if test="not(position()=last())">, </xsl:if>
      </xsl:for-each>);
      <br/>
    </xsl:for-each>
    <br/>
    end <xsl:value-of select="@name"/>
  </xsl:template>
</xsl:stylesheet>
    
Пример 7.2.

Данный стиль XSLT предназначен для генерации кода совместно с комментариями. Так как вывод будет осуществляться в формате HTML, то ставим инструкцию xsl:output в значение html. Далее для каждого пакета выполняется шаблон, включенный в xsl:template. Выполняется проход по каждой процедуре и функции, осуществляется вывод сигнатуры и комментариев. Результат будет следующим:

-- Пакет для выполнения операций над таблицей tbl_book. Он делает много хороших вещей. 
create or replace package pkg_book

-- Служит для установки значений по идентификатору. 
function SetValues (ID number, title varchar2, author varchar2); 
-- Служит для извлечения названия книги по идентификатору. 
function GetTitle (ID number); 
-- Служит для извлечения имени автора по идентификатору. 
function GetAuthor (ID number); 

end pkg_book
    
Пример 7.3.

Теперь рассмотрим шаблон для генерации самой документации:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>
  <xsl:template match="packages/package">
    Пакет <xsl:value-of select="@name"/>
    <br/>
    <xsl:value-of select="comment"/><br/>
    Содержит следующие процедуры и функции:<br/><br/>
    <xsl:for-each select="procedure">
      <xsl:choose>
        <xsl:when test ="@type='procedure'">Процедура </xsl:when>
        <xsl:otherwise>Функция </xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="@name"/><br/>
      <xsl:value-of select="comment"/><br/>
      имеет следующие параметры:
      <xsl:for-each select="parameters/param">
        Название: <xsl:value-of select="@name"/>;
        <xsl:text> </xsl:text>
        Тип: <xsl:value-of select="@type"/>;
        <br/>
      </xsl:for-each>
      <br/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
    
Пример 7.4.

Он работает аналогично предыдущему стилю. Предлагаю читателю самостоятельно разобраться в его работе. Результатом будет следующий текст:

Пакет pkg_book
Пакет для выполнения операций над таблицей tbl_book. Он делает много хороших вещей. 
Содержит следующие процедуры и функции:

Функция SetValues
Служит для установки значений по идентификатору. 
имеет следующие параметры: Название: ID; Тип: number; 
Название: title; Тип: varchar2; 
Название: author; Тип: varchar2; 

Функция GetTitle
Служит для извлечения названия книги по идентификатору. 
имеет следующие параметры: Название: ID; Тип: number; 

Функция GetAuthor
Служит для извлечения имени автора по идентификатору. 
имеет следующие параметры: Название: ID; Тип: number;
    
Пример 7.5.

А теперь напишем код на языке C#, который запускает трансформацию и позволит сгенерировать оба файла:

string styledoc = "packagecomments.xsl";
string styleprog = "package.xsl";
string document = "package.xml";
string outputdoc = "package.txt";
string outputprog = "package.html";
XslCompiledTransform xt = new XslCompiledTransform();
xt.Load(styledoc);
xt.Transform(document, outputdoc);
xt.Load(styleprog);
xt.Transform(document, outputprog);
Console.Read();
    
Пример 7.6.

Мы рассмотрели пример генерации программного кода и документации из одного файла метаданных. Над одним и тем же документом XML выполняются два преобразования. Одно из них генерирует код с комментариями, а другое - документацию. Это очень удобно, так как из одного источника метаданных за один запуск метода формируется несколько результатов.

Генерация разбором кода

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

Такой способ генерации документации уместно использовать для кода, созданного вручную. Чем ближе при этом документация расположена к самому коду, тем больше шансов того, что она будет обновляться. Такой подход является наиболее простым способом ее ведения. Нет ничего проще, чем модифицировать комментарии в коде, а документацию генерировать автоматически.

Преимущества генерации документации

Преимущества генерации документации следующие:

  • Документация становится в большей степени согласованной с программным кодом, то есть более точной и актуальной.
  • Экономится значительное количество времени и усилий, требуемых для разработки документации. Освобождаемые время и ресурсы можно применить для улучшения качества документации.
  • Более простым становится процесс изменения формата или стиля подачи документации. При наличии собственного генератора не надо менять формат каждого документа, достаточно изменить шаблон.
  • Документация формируется значительно быстрее.

Существующие генераторы документации

Практически для каждого популярного языка созданы программы, документирующие код. Для C#, VB и других языков платформы .Net имеется программа NDoc, позволяющая составлять документацию. Имеется приложение Doxygen, используемое в основном для C++, но можно генерировать документацию также для Си, Java, C#, PHP и других языков. Есть Javadoc для Java, PHPDoc для PHP и множество других.

Применение генераторов документации

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

  • проектирования документации,
  • создания пользовательской документации,
  • документирования отдельных команд в приложении построчно.

При генерации документации необходимо:

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

Манипуляция данными

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

  1. Преобразование из одного формата в другой. Форматы могут быть совершенно разными. Они могут быть файлами, базами данных, вводом с клавиатуры, выводом на экран, оперативной памятью и т.п.
  2. Проверка корректности данных, соответствия шаблонам и правилам.

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

Преимуществами применения генераторов кода для манипуляции данными являются:

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

Манипуляция данными и их форматами является хорошим кандидатом для применения генерации кода. Позволяет абстрагировать формат файла, выводить данные в нескольких форматах и за минимальное время.

Генерация в тестировании

Качественно выполненное тестирование приложения позволяет убедиться, что практически во всех предусмотренных заранее вариантах возникновения ошибок код будет работать правильно. Поблочное тестирование позволяет пройтись по методам приложения, проверить их на самых разных тестовых данных и сообщить, прошел тест удачно или нет.

Создание и сопровождения тестов является рутиной работой, отнимает много времени и сил. Для создания тестирующего кода эффективней воспользоваться генерацией, чем писать его вручную.

Для лучшей генерации и модернизации систему тестирования желательно создавать простой и удобной. Хорошей идеей является хранение тестовых данных рядом с тестируемыми методами. Система тестирования должна быть наглядной и удобной для запуска и получения отчетов о его результатах. Отчеты и тесты должны быть многоуровневыми и допускать получение результатов тестирования, как для всего приложения, так и отдельных его частей по выбору.

Таким образом:

  • тесты должны легко создаваться и модифицироваться;
  • тестовая система должна быть наглядной и удобной для запуска, как всех тестов, так и его частей;
  • должна существовать возможность вывода отчетов о тестировании как для всего приложения, так и его отдельных частей и аспектов тестирования.

Возможные применения генерации в тестировании

Поблочное тестирование. Интерфейсы API проверяются поблочным тестированием методом белого ящика. Тестовые данные записываются в виде комментариев непосредственно перед методом. Генератор считывает комментарии, и создает код запуска метода с тестовыми данными, сравнения возвращенного значения с ожидаемым уведомлением об успехе или неудаче теста. Тесты могут быть не только одношаговыми, но и запускаемыми в определенной последовательности.

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

  • положительный результат путем отправки правильных данных.
  • отрицательный результат путем отправки неправильных данных или неправильного вызова.
  • устойчивость к так называемым стресс-тестам при отправке большого объема запросов.

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

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

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

Веб роботы используют те же данные, что и тестировщик баз данных, только загружает их через пользовательский интерфейс. Это позволяет протестировать сразу все уровни приложения. Однако тестовый робот не должен проверять клиентские скрипты, вроде Javascript, VBscript, так как не является полноценным браузером.

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

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

Выводы

Таким образом, применение генерации в тестировании позволяет:

  • экономить время, затрачиваемое на тестирование;
  • эффективно применять тестирование на всех этапах жизни приложения, улучшить качество тестирования;
  • более уверенно и быстро изменять существующий код, зная, что есть инструмент тестирования, позволяющий автоматически проверить важные аспекты работы приложения.
< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Дмитрий Клочков
Дмитрий Клочков
Россия, Рубцовск
Волков Олег
Волков Олег
Украина, Днепропетровск