Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Онлайн-курс по SQL для новичков.
Теория, практика, поддержка, сертификат.
2008 г.

Технология Azov автоматизации массового создания тестов работоспособности

Р. С. Зыбин, В. В. Кулямин, А. В. Пономаренко, В. В. Рубанов, Е. С. Чернов

Назад Содержание Вперёд

2.3. Методическая основа технологии

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

Уточнение информации об интерфейсных операциях и типах их параметров сводится к следующим действиям.

  • Уточнение (специализация) типов.

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

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

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

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

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

    • При уточнении типов параметров иногда несколько параметров объединяются в один абстрактный объект, разные элементы которого используются в качестве их значений, и определяется специализированный тип такого составного объекта.
      Например, если параметрами операции являются указатель на начало строки типа char* и ее длина, можно определить специализированный тип «строка». Вместо первого параметра тогда нужно задавать указатель на первый элемент строки, а вместо второго — результат применения функции strlen() к этому указателю.
      При создании таких комплексных специализированных типов определяется код для получения значений отдельных параметров из комплексного объекта.

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

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

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

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

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

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

Основная процедура построения теста для заданного интерфейса выглядит так.

  • В начало теста вставляется код инициализации для работы данной операции.

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

    • Если значение типа определено явно, используется это значение.

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

    • Значения других типов строятся автоматически. Для примитивных типов (числа, символы, строки) используются некоторые простые генераторы значений. Значения производных типов — указателей, ссылок, массивов и пр. — строятся из значений их базовых типов. Для перечислений используется первое возможное значение. Объекты структурных типов строятся по их полям, причем поля заполняются по этой же процедуре.

  • Вставляется вызов тестируемой операции с построенными аргументами.

  • Затем вставляется код финализации для всех построенных значений, для которых это необходимо.

  • В конце вставляется код финализации после работы тестируемой операции.

  • Для всех вызовов операций, использованных в коде, вставляются проверки ограничений на их результаты, указанные в соответствующих специализированных типах. Кроме того, для всех указателей, которые возникают при вызовах и используются в дальнейшем, проверяется их неравенство NULL.

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

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

2.4. Пример построения тестов по технологии Azov

В данном разделе ряд элементов методики построения тестов в рамках описываемой технологии проиллюстрированы на примере функций работы с хранителем экрана (screen saver) в библиотеке Xlib, входящей в LSB.

Всего в этой библиотеке 5 таких функций.

  • int XSetScreenSaver(Display*, int, int, int, int) — устанавливает режим работы хранителя экрана для заданного дисплея.

  • int XGetScreenSaver(Display*, int*, int*, int*, int*) — возвращает текущие параметры работы хранителя экрана для данного дисплея, значения возвращаются по параметрам-указателям, соответствующим параметрам предыдущей функции.

  • int XForceScreenSaver(Display*, int) — активирует или дезактивирует хранитель экрана для заданного дисплея в зависимости от указанного второго параметра.

  • int XActivateScreenSaver(Display*) — активирует хранитель экрана для заданного дисплея.

  • int XResetScreenSaver(Display*) — дезактивирует хранитель экрана для заданного дисплея.

Документация [6] на функции библиотеки Xlib дает следующее уточнение интерфейса.

  • Второй и третий параметры функции XSetScreenSaver() являются интервалами времени в секундах, определяющими режим работы хранителя экрана. Можно ввести для них тип TimeIntervalInSeconds, определив для него возможное корректное значение 1. Второй и третий параметры XGetScreenSaver() являются указателями на этот же тип.

  • Четвертый и пятый параметры XSetScreenSaver(), а также второй параметр XForceScreenSaver() имеют на самом деле перечислимые типы, определяющие возможные режимы работы или активации/дезактивации хранителя экрана. Для них можно ввести типы, соответственно, BlankingMode, ExposuresMode и ForceMode. Корректные значения для них четко определены в тексте стандарта — это, соответственно, {DontPreferBlanking, PreferBlanking, DefaultBlanking}, {DontAllowExposures, AllowExposures, DefaultExposures} и {Active, Reset}. Четвертый и пятый параметры XGetScreenSaver() являются указателями на типы BlankingMode и ExposuresMode.

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

Анализ возможности получения значения типа Display* дает следующие результаты.

  • Всего в LSB упоминается 18 функций, возвращающих значение типа Display*, и две функции, возвращающие ссылку на значение типа Display, из которой можно построить нужный указатель.
    6 из этих функций находятся в рамках библиотеки Xlib: XDisplayOfIM(), XDisplayOfOM(), XDisplayOfScreen(), XOpenDisplay(), XcmsDisplayOfCCC(), XkbOpenDisplay(). Остальные функции находятся в других библиотеках — X Toolkit, GTK, Open GL и Qt. Для простейших тестов предпочтительно использовать функции той же библиотеки, поэтому далее анализируются только первые 6 функций.

  • Из 6 выбранных функций 4 не могут быть использованы, потому что сами косвенно требуют уже иметь некоторое значение типа Display*.
    Например, XDisplayOfIM() имеет параметр типа XIM, для получения значения которого есть только 2 функции — XOpenIM() и XIMOfIC(). Первая требует на вход Display*, вторая — XIC, который, в свою очередь, может быть создан только функцией XCreateIC(), которая снова требует значения XIM; XDisplayOfScreen() требует параметра типа Screen*, который в Xlib может быть получен только из XDefaultScreenOfDisplay() и XScreenOfDisplay(), а они обе требуют параметра типа Display*.
    Описание функции XkbOpenDisplay() отсутствует в документации на Xlib.
    Остается только функция XOpenDisplay(), которая может быть использована, поскольку требует только параметра типа const char*, могущего принимать значение NULL при штатном использовании этой функции.

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

  • В качестве значений параметра Display* используется результат вызова XOpenDisplay() с аргументом NULL.

  • В качестве значений интервала времени в секундах используется 1.

  • В качестве значений специализированных типов BlankingMode, ExposuresMode и ForceMode используются, соответственно, значения DontPreferBlanking, DontAllowExposures и Active.

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

  • Кроме того, корректность результатов, возвращаемых по указателям функцией XGetScreenSaver() через ее 4-й и 5-й параметры, можно проверять сравнением их с возможными значениями специализированных перечислимых типов BlankingMode и ExposuresMode.

Рисунок 2. Схема получения значений параметров и ограничений на результаты для функций работы с хранителем экрана (не показан тип ExposuresMode).

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

Данный пример показывает также, что основной источник повышения производительности создания тестов в рамках описываемой технологии — многократное использование специализированных типов. Один раз уточнив тип параметра функции XOpenDisplay(), мы можем получать значения типа Display*, необходимые для многих функций из библиотеки Xlib. В данном примере функций немного, а количество параметров с различным смыслом у них достаточно велико, поэтому снижения трудоемкости создания тестов ожидать не приходится. Если же реализовать многократное использование одних и тех же типов для параметров большого числа функций, становится возможным существенное повышение производительности.

Назад Содержание Вперёд

Новости мира IT:

Архив новостей

Последние комментарии:

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...