<i>Метод тестирования классов объектно-ориентированного программного обеспечения</i> Текст научной статьи по специальности «<i>Компьютерные и информационные науки</i>»

Метод тестирования классов объектно-ориентированного программного обеспечения Текст научной статьи по специальности «Компьютерные и информационные науки»

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Киселев Алексей Викторович

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

Похожие темы научных работ по компьютерным и информационным наукам , автор научной работы — Киселев Алексей Викторович

CLASS TESTING METHOD IN OBJECT-ORIENTED SOFTWARE ENGINEERING

An analysis has been carried out of existing approaches to class testing of object-oriented software (OOS). An OOS class testing method has been proposed on the basis of class code structural analysis.

Текст научной работы на тему «Метод тестирования классов объектно-ориентированного программного обеспечения»

Информационные технологии Вестник Нижегородского университета им. Н.И. Лобачевского, 2012, № 2 (1), с. 210-215

МЕТОД ТЕСТИРОВАНИЯ КЛАССОВ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ

© 2012 г. А.В. Киселев

Нижегородский государственный технический университет им. Р.Е. Алексеева

Поступила в редакцию 08.12.2011

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

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

Объектно-ориентированная (ОО) парадигма играет ключевую роль в разработке современного программного обеспечения (ПО) и компьютерных систем. Различная структура и поведение ОО ПО помогают в решении или смягчении многих проблем процедурного ПО, однако появляются другие классы ошибок, которые требуют новых техник тестирования.

Основным элементом ОО программы является класс. Класс представляет собой абстрактный тип данных и единственный тип модуля в ОО системе. Он инкапсулирует в себе данные -атрибуты класса - и методы, которые объект данного класса может выполнять по отношению к атрибутам.

В отличие от традиционного процедурного программирования в ОО ПО элементом тестирования является не подпрограмма, а класс, имеющий набор атрибутов и методов поведения.

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

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

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

Существующие методы тестирования класса основаны либо на спецификации состояний класса, либо на анализе потока данных. Большинство методов, основанных на состоянии класса, привязывают генерацию тестового случая к существующей спецификации класса [1]. Удобным средством описания ОО ПО (в частности, класса) является модель, построенная на основе теории конечных автоматов: она обладает ясностью семантики (трактовки элементов модели), наглядностью и выразительностью, и в то же время достаточно строга и формальна. Среди отечественных ученых отметим Шалыто А.А., котрому принадлежит множество работ по проблеме проектирования и реализации ПО с помощью конечных автоматов. Представление программы с использованием элементов автоматной модели (состояний, событий, действий, переходов) позволяет повысить эффективность тестирования ПО за счет проверки не только возвращаемых кодов, но и содержащихся в объекте данных. Однако данный подход приме-ним в основном для аппаратных систем.

К сожалению, часто нам приходится тестировать программное обеспечение, спецификация которого неполноценна или даже отсутствует. Существующие методики для извлечения информации в каждом состоянии объекта из исходного кода обычно требуют большой ответственности за код, который анализируется. Например, метод, определенный Куном и другими [2], может применяться только к ска-

лярным переменным без взаимозависимости. Этот метод не может применяться по мере сильного увеличения тестируемого кода. Методы, основанные на потоке данных [3], применяются скорее для алгоритмов и не принимают во внимание методологические аспекты тестирования. Таким образом, эти методы представляют важную основу для тестирования классов, но они не полностью покрывают проблемы генерации тестовых сценариев.

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

• разработка нового подхода к тестированию классов ОО ПО, основанного на технике структурного тестирования;

• минимизация количества тестовых сценариев, обеспечивающих наиболее исчерпывающее тестирование классов ОО ПО и более полное покрытие кода.

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

Орграф G = (X, и) называется управляющим графом (р-графом, графом переходов), если выполнены следующие условия:

1) X - это непустое множество вершин или узлов;

2) и - это множество (упорядоченных) пар различных вершин, называемых дугами или ориентированными рёбрами;

3) граф G не содержит параллельных дуг;

4) в множестве вершин графа выделена одна вершина 5 - вход графа;

5) в множестве вершин графа выделена хотя бы одна вершина t - выход графа;

6) каждая вершина достижима из входа 5;

7) каждая вершина достигает выхода t.

Каждой программе можно поставить в

соответствие два графа, определяемых двумя типами связей, существующими в программе:

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

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

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

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

Необходимо обратить внимание, что в работе рассматривается тестирование классов изолированно.

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

На рисунке 1 показан код для класса СотБох, на рисунке 2 - соответствующий управляющий граф для класса СотБох.

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

class CoinBox j

unsigned totalQtrs; unsigned curQtrs; unsigned allowVend;

totalQtrs = 0; allowVend = 0; curQtrs = 0;

curQtrs = curQtrs + 1; if (curQtrs > 1) allotfVend = 1;

totalQtrs = totalQtrs + curQtrs; curQtrs = 0; allowVend = 0;

Рис. 1. Класс CoinBox

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

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

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

du-пара для переменной v состоит из двух вершин, sd и su, таких, что обе они содержатся в классе С, sd определяет значение переменной v, su использует значение переменной v. Мы поме-

чаем методы, содержащие 5а и 5и, используя та и ти, и записываем для обозначения пары (5й, 5и, V). Путь для du-пары (5й, 5и, V) - это путь от 5й и 5и, который не содержит дополнительных определений переменной V.

В таблице представлены du-пары для класса СотБох. Номера вершин в скобках соответствуют управляющему графу для класса СотБох на рисунке 2. Здесь также отмечены пары, которые являются невыполнимыми. Невыполнимыми считаются du-пары, если нельзя вызвать методы, содержащие определение и использование переменной, избежав какого-либо дополнительного определения той же переменной.

du-пары, вычисленные с помощью анализа потока данных, показывают, какие методы определяют значения переменных, используемые далее другими методами. Чтобы определить ряд тестовых сценариев, необходимо установить для каждой du-пары возможный ряд путей через методы, которые содержат определение и использование в du-паре, если такой ряд существует. Последовательность не может содержать дополнительные определения переменной между ее определением и использованием, которые идентифицируются du-парой. Для вычисления таких выполнимых путей необходима следующая информация для каждого пути внутри каждого метода: 1) условия прохождения пути; 2) взаимозависимости между входными и выходными значениями переменных для метода по отношению к пути; 3) ряд переменных, определяемых через весь путь. Вся описанная необходимая информация вычисляется через символьное выполнение каждого метода тестируемого класса.

Информация, полученная в результате символьного выполнения, используется для составления последовательности вызовов методов, которые выполняют du-пары, определенные в ходе анализа потока данных. Последовательность методов для du-пары должна начинаться с конструктора класса и заканчиваться методом ти, который выполняет оператор использования (т.е. 5и) в du-паре. К тому же последовательность должна содержать метод тй, который выполняет оператор определения (т.е. 5й) в du-паре, и прозрачный путь от 5й к 5и.

Получаемая du-пара й = (5й, 5и, V), выполнимая последовательность методов, осуществляющая й, - последовательность ть т2. тп, подлежат следующим ограничениям. Во-первых, т\ должен быть конструктором тестируемого класса. Во-вторых, выполнение метода тп

- это результат выполнения оператора 5и, который использует V. В-третьих, при выполнении последовательности оператор 5й, который оп-

Рис. 2. Управляющий граф класса CoinBox

# переменная md (вершина) mu (вершина) комментарий

01 curQtrs CoinBox (4) addQtr (14a)

02 curQtrs CoinBox (4) addQtr (15) невыполнимая

0З allowVend CoinBox (З) vend (19)

04 totalQtrs CoinBox (2) vend (20a)

05 curQtrs returnQtrs (11) addQtr (14a)

06 curQtrs returnQtrs (11) addQtr (15) невыполнимая

07 curQtrs returnQtrs (11) vend (20a)

08 curQtrs addQtr (14b) addQtr (14a)

09 curQtrs addQtr (14b) addQtr (15)

110 curQtrs addQtr (14b) vend (20a)

111 allowVend addQtr (16) vend (19)

112 totalQtrs vend (20b) vend (20a)

11З curQtrs vend (21) addQtr (14a)

114 curQtrs vend (21) addQtr (15) невыполнимая

115 curQtrs vend (21) vend (20a) невыполнимая

116 allowVend vend (22) Vend (19)

117 curQtrs CoinBox (4) vend (20a)

ределяет переменную V, должен выполниться, по крайней мере, один раз. Возможен случай, что , г е [1, п ] , есть последний метод в последовательности, результат которого - исполнение 5й. Это должен быть случай, когда тг = = та. В-четвертых, для каждого у е [г +1, п] выполнение метода ту не должно содержать какого-либо дополнительного определения V. (В случае метода тп данный метод может содержать определение V, но оно должно исполняться только после того как 5и будет выполнен.)

Получив du-пару d = (sd, su, v), мы генерируем последовательность методов для d в реверсном (обратном) порядке, начиная с метода mu, который содержит оператор su, и принимая ряд обратно-связанных дедукций. Наша начальная цель

- Path-Condition Using (PCU), предусловия на метод mu, выполняющий su. Если есть метод, чьи постусловия включают в себя PCU, то этот метод ставится в начало последовательности. Если такой метод не найден, мы ищем метод mk, чьи постусловия не противоречат PCU, и мы вставляем в начало последовательности этот метод.

Рис. 3. Дерево методов для du-пары #7

Условия, которым удовлетворит результирующая последовательность, определяются следующим образом: 1) текущее условие упрощается исключением тех условий (если они есть), которые выполняют постусловия т^; 2) упрощенное условие и предусловия т^ объединяются; 3) далее упрощается полученное результирующее условие, если это возможно.

Изображается дедуктивный процесс для du-пары й = (5й, 5и, V) в виде дерева. На рисунке 3 изображено дерево методов для du-пары #7.

Для класса СогпБох результирующая последовательность вызовов методов для du-пары #7: СотБох() -> addQtr() -> addQtr() -> returnQtr5() -> vend().

Очевидно, предлагаемый метод более эффективен, когда все три техники успешно применимы. В этом случае мы получаем последовательности методов, которые выполняют все осуществимые du-пары в тестируемом классе.

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

дения последовательности методов, которые покрывают du-пары, определенные ранее.

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

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

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

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

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

Все три этапа разработанного метода могут быть автоматизированы, что позволяет понизить затраты на поддержание надежности ПО.

1. Макгрегор Дж., Сайкс Д. Тестирование объектно-ориентированного программного обеспечения.

Практическое пособие: Пер. с англ. ООО «ТИД ДС», 2002. 432 с.

2. Kung D., Gao J., Hsia P. and et al. Developing and object-oriented software testing and maintenance environment // Communications of the ACM. 1995. V. 38. № 10. P. 75-86.

3. Souter A.L., Pollock L.L., Hisley D. Inter-class def-use analysis with partial class representations // Proceedings of the ACM SIGPLAN-SIGSOFT Workshop on Program Analysis for Software Tools and Engineering PASTE'99, Toulouse (France), September 1999.

4. Мейер Б. Объектно-ориентированное конструирование программных систем. M.: Русская Редакция, 2005.

5. Pasareanu S., Willem Visser. A survey of new trends in symbolic execution for software testing and analysis // Int. J. Soft Tools Technol. Transfer. 2009. № 11. P. 339-353.

CLASS TESTING METHOD IN OBJECT-ORIENTED SOFTWARE ENGINEERING

An analysis has been carried out of existing approaches to class testing of object-oriented software (OOS). An OOS class testing method has been proposed on the basis of class code structural analysis.

Keywords: software, class, testing, data flow analysis, symbolic execution, graph.

📎📎📎📎📎📎📎📎📎📎