МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ
РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«РОССИЙСКИЙ ЭКОНОМИЧЕСКИЙ УНИВЕРСИТЕТ
ИМЕНИ Г.В. ПЛЕХАНОВА»
Институт цифровой экономики и информационных технологий
Базовая кафедра цифровой экономики института развития информационного
общества
«Допустить к защите»
Заведующий базовой кафедрой цифровой
экономики института развития информационного общества
д.э.н., профессор А.И. Уринцов
«
2020 г.
»
ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ РАБОТА
Направление 09.04.01 «Информатика и вычислительная техника»
Магистерская программа «Управление ИТ-инфраструктурой цифровой экономики»
ТЕМА Методика проектирования ИТ-инфраструктуры контроля качества
системы учета ценных бумаг
Выполнил студент Платонов Александр Александрович
Группа 291М-08/18м
Научный руководитель выпускной
квалификационной работы
Мамедова Н.А., д.э.н., доцент
(подпись)
Автор
(подпись)
Москва – 2020
СОДЕРЖАНИЕ
ВВЕДЕНИЕ .............................................................................................................. 4
ГЛАВА 1. Характеристика задачи тестирования единой информационной
системы группы компаний «Гарант» ...................................................................... 7
1.1. Анализ единой информационной системы группы компаний «Гарант» ..... 7
1.2. Анализ существующих практик тестирования ........................................... 11
1.3. Анализ существующих программных продуктов для автоматической
генерации тестов ................................................................................................. 17
1.4. Постановка задачи на разработку методики автоматизации процесса
создания автотестов ПО ...................................................................................... 28
ГЛАВА
2.
Разработка
и
реализация
методики
проектирования
ИТ-
инфраструктуры контроля качества единой информационной системы группы
компаний «Гарант» ................................................................................................ 33
2.1. Разработка методики автоматизированного тестирования единой
информационной системы группы компаний «Гарант» ................................... 33
2.2. Разработка методики проектирования ИТ-инфраструктуры контроля
качества системы учета ценных бумаг ............................................................... 36
2.3. Анализ используемых аппаратных и программных средств ...................... 41
2.4. Анализ архитектуры единой информационной системы ........................... 46
2.5. Состав и структура разрабатываемого программного средства ................ 54
2.6. Документация на разработанное программное средство ........................... 65
ГЛАВА 3. Оценка технико-экономических
показателей
разработанного
модуля тестирования .............................................................................................. 72
3.1. Описание результатов испытаний ............................................................... 72
3.2. Оценка качественных показателей разработанного программного
средства................................................................................................................ 74
2
3.3. Оценка экономической эффективности ...................................................... 79
ЗАКЛЮЧЕНИЕ ...................................................................................................... 89
СПИСОК ЛИТЕРАТУРЫ ...................................................................................... 93
3
ВВЕДЕНИЕ
На
сегодняшний день информатизация
проникла
во
все
сферы
деятельности человека. Большинство компаний переходит на электронный
документооборот, так как это позволяет быстро и удобно применять различные
программные средства к имеющимся данным. Например, совершая покупку и
продажу товаров в электронном виде, можно легко и быстро подключить
программное
обеспечение,
занимающееся
защитой
платежей,
анализом
тенденций рынка, выявлением интересов отдельных групп покупателей или
правовой поддержкой совершаемых сделок. Исключительной особенностью
внедрения информационных технологий в бизнес-процессы является появление
возможности взаимодействия в режиме реального времени организаций,
географически удаленных друг от друга.
Одной их таких организаций с высоким уровнем информатизации
является группа компаний «Гарант». Основным направлением ее деятельности
является выполнение функций специализированного депозитария. Применение
информационных технологий позволяет «Гаранту» оперативно обрабатывать
огромные объемы бухгалтерских данных клиентов, а также формировать
финансовую отчетность об их деятельности для последующего предоставления
ее в государственные контролирующие органы в лице Центробанка РФ. Для
этих целей в «Гаранте» была разработана собственная единая информационная
система (ЕИС), на основе которой строится вся работа компании. Данное
программное обеспечение представляет собой сложную структуру из набора
модулей, выполняющих огромное количество разнообразных функций, начиная
с расчета стоимости активов клиентов и заканчивая повышением мотивации
сотрудников за счет внедрения системы «достижений». В силу высокой степени
интеграции рассмотренной информационной системы в бизнес-процессы,
компания предъявляет высокие требования к качеству ЕИС, удовлетворение
которых из-за сложности программного обеспечения требует значительных
трудовых и стоимостных затрат.
4
Объектом исследования данной выпускной квалификационной работы
являются процессы разработки и поддержки программного обеспечения
Изучение этих процессов особенно ценно для компаний, по специфике работы
похожих на «Гарант», поскольку значительная часть их расходов приходится
именно на эту сферу. Этим обуславливается и актуальность ВКР, так как
оптимизация данных процессов неизбежно ведет и к оптимизации затрат
фирмы, что является приоритетной задачей любого участника рынка.
Предметом
же
исследования
является
организация
тестирования
программного обеспечения. Тестирование – важнейшая часть жизненного
цикла ПО [2], которая позволяет контролировать стабильность его работы и не
допускать внесения некорректных правок в его исходный код. Учитывая
масштабы ЕИС и высокую цену попадания в рабочую версию необнаруженных
ошибок, становится очевидно, что организация тестирования – сложный
комплексный процесс, который протекает в «Гаранте» каждый день и требует
большого количества внимания и времени сотрудников.
Целью данной выпускной квалификационной работы является разработка
методики организации тестирования, которая бы позволила оптимизировать
затраты компании на создания автотестов.
В процессе выполнения данной выпускной квалификационной работы
необходимо решить следующие задачи:
проанализировать
широко
применяемые
практики
контроля
разработки собственной
методики
качества программного обеспечения;
обосновать необходимость
тестирования ПО;
сформулировать требования к разрабатываемой методике;
разработать
методику
проектирования
контроля качества программного обеспечения;
5
ИТ-инфраструктуры
реализовать
модуль
кодогенерации
автотестов
на
основе
пользовательских действий для единой информационной системы группы
компаний «Гарант»;
проанализировать результаты применения данного модуля;
Научная новизна данной ВКР заключается в том, что на рынке не
представлено инструментов для автоматизированного создания качественных
тестов,
не
требующих
значительного
преобразования
архитектуры
тестируемого ПО, а успешно разработанная методика тестирования может
помочь компаниям существенно оптимизировать их затраты на контроль
качества разрабатываемых программных средств.
Основные положения, выносимые на защиту, включают в себя:
обоснование целесообразности автоматизации процесса создания
тестов;
описание
разработанной
методики
проектирования
ИТ-
инфраструктуры контроля качества программного обеспечения;
реализация
разработанной
методики
на
примере
единой
информационной системы группы компаний «Гарант»;
обоснование
экономической
эффективности
от
применения
разработанной методики;
Представленная выпускная квалификационная работа описывает все
этапы разработки этой методики, а именно: предварительный анализ
требований,
анализ
существующих
решений
на
рынке
тестирования
программного обеспечения, постановку задачи, проектирование, кодирование,
тестирование и оценку результатов. Как итог, данная ВКР всесторонне
описывает решение проблемы оптимизации затрат компании на поддержание
стабильности ее программного обеспечения.
6
ГЛАВА 1. ХАРАКТЕРИСТИКА ЗАДАЧИ ТЕСТИРОВАНИЯ ЕДИНОЙ
ИНФОРМАЦИОННОЙ СИСТЕМЫ ГРУППЫ КОМПАНИЙ «ГАРАНТ»
1.1.
Анализ единой информационной системы группы компаний
«Гарант»
Как
было
указано
во
введении,
целью
данной
выпускной
квалификационной работы является оптимизация процесса тестирования для
единой информационной системы, разработанной и поддерживаемой группой
компанией «Гарант». В первую очередь перед поиском возможных решений
необходимо провести обзор самой системы, в которую будет интегрироваться
разрабатываемое решение, чтобы иметь полное понимание возлагаемых на него
ожиданий, а также описать, с чем ему придется работать.
Итак, представленная информационная система используется в двух
основных подразделениях:
ООО
«СДК
«Гарант».
Данная
компания
является
специализированным депозитарием – участником рынка ценных бумаг,
который осуществляет депозитарную деятельность, а также, при работе с
инвестиционными
негосударственными
фондами,
паевыми
пенсионными
инвестиционными
фондами,
осуществляет
фондами,
контрольные
функции за соответствием деятельности управляющих компаний и самих
фондов законодательству [28]. Депозитарной деятельностью признается
оказание услуг по хранению сертификатов ценных бумаг и/или учету и
переходу прав на ценные бумаги.
ООО «Регистратор «Гарант». Регистратор – профессиональный
участник рынка ценных бумаг, осуществляющий деятельность по ведению
реестра владельцев именных ценных бумаг на основании договора с эмитентом.
7
Из описания деятельности компаний, можно понять, что спектр
предоставляемых информационной системой возможностей весьма широк.
Общее количество доступных для исполнения действий постоянно меняется, но
на момент написания данной выпускной квалификационной работы оно
колеблется около семи сотен. Самые же крупные и наиболее важные
компоненты системы описаны ниже:
1. Ведение комплекса неизменяемых справочников. Наличие данной
функции обусловлено тем, что некоторые данные должны присутствовать в
системе для более удобной интеграции разных компонент, но при этом
изменение этих данных будет противоречить объективной реальности и может
повлечь за собой нарушение целостности всех остальных данных. Например, к
таким данным относятся курсы валют на прошедшие даты – они необходимы
для расчета стоимости сделок, проведенных в иностранной валюте, и при этом
зарегистрированный курс валюты не может измениться после окончания
операционного дня.
2. Ведение комплекса изменяемых справочников. Очевидно, что
многие данные со временем меняются, и это должно быть отражено в системе.
Примером таких данных может служить регистрационная информация любой
компании-клиента – ее адрес, контактный телефон, имена руководителей.
3. Ведение
комплекса
документов
со
строго
определенными
правилами добавления, изменения и удаления данных. Одно из направлений
деятельности специализированного депозитария – контроль правомерности
действий клиента. Ограничения этих действий обусловлены законодательством
РФ и, естественно, должны контролироваться информационной системой.
Примером такого документа могут служить банковские переводы компанийклиентов, которые должны быть привязаны к какому-либо договору и
операционному дню. Необоснованный перевод крупных средств – операция,
которая может привести к нарушению налогового законодательства и закрытию
фирмы.
8
4. Удобные
способы
просмотра
и
редактирования
данных
с
соответствующими операциями контроля правомерности вносимых изменений.
Набор программных модулей, относящихся к данному слою, включают в себя
аутентификацию, авторизацию, аудит и логирование всех действий в системе, а
также наличие различных настраиваемых персональных прав каждого
пользователя на создание, редактирование или удаление отдельных сущностей.
5. Расчет
стоимостей
проведенных
за
день
транзакций
для
последующего сравнения полученной суммы с реальными затратами компанииклиента. Депозитарная деятельность включает в себя контроль и перепроверку
бухгалтерии клиентов. При этом совершаемые операции могут иметь сильно
разнящуюся природу, и, как следствие, расчет их окончательной стоимости
должен производиться по разным алгоритмам с разными параметрами. На
момент написания данной выпускной квалификационной работы количество
реализованных алгоритмов в системе насчитывает более сотни элементов.
6. Формирование отчетов. Одна из наиболее важных функций,
подытоживающая результаты предыдущих этапов работы с данными клиента.
Отчеты так же могут сильно различаться по своей структуре в зависимости от
того, по каким операциям и для кого они строятся. Большинство отчетов
являются
официальными документами,
отправляемыми на
проверку в
Центральный Банк РФ. Нарушения в формировании таких отчетов могут
привести к отзыву у компании-клиента лицензии, то есть прекращению ее
деятельности.
7. Ведение истории изменений справочников/документов. Благодаря
наличию данной функции в системе присутствует возможность получить
данные на любую дату в прошлом в том виде, в котором они находились в то
время. Например, это нужно для формирования отчетов на прошлый месяц.
8. Импорт, экспорт и синхронизация данных. Единая информационная
система поддерживает различные форматы для импорта и экспорта данных:
файлы Excel, Word, базы данных SQL, XML. И этот список в любой момент
9
может быть расширен. Синхронизация данных позволяет поддерживать
актуальное
и
согласованное
состояние
между
несколькими
отдельно
работающими системами.
9. Выполнение
действий
по
расписанию.
Данный
функционал
позволяет еще больше автоматизировать работу системы, а также перенести
лишнюю нагрузку на сервер на нерабочие часы, тем самым увеличив
производительность в рабочее время. Стабильная работа этой компоненты
очень важна, так как сбой в работе ночных действий может сделать
невозможной работу большинства сотрудников компании в первые несколько
часов рабочего дня. Примером таких ночных действий могут служить
перепроверка проведенных за день операций, создание истории изменений,
очистка временных файлов и создание резервной копии баз данных.
10.
Электронные голосования. ООО «Регистратор «Гарант»
является регистратором, то есть ведет реестр владельцев ценных бумаг. Как
дополнение к этой деятельности, компания предоставляет удобную площадку
для проведения электронных голосований акционеров. Это позволяет сделать
«Гарант» более привлекательным для клиентов, но также накладывает
дополнительную ответственность за стабильность, надежность и открытость
проводимых голосований.
Описанные возможности единой информационной системы компании
позволяют оценить разнообразие доступного функционала. И что особенно
важно, этот функционал постоянно изменяется и расширяется. Система
спроектирована таким образом, чтобы добавление нового действия не
требовало никаких дополнительных манипуляций разработчика, кроме как
написания кода самого действия.
В
контексте
частых
изменений
структуры
и
возможностей
информационной системы перед компанией возникла другая важная задача –
повышение стабильности и надежности работы различных компонент. Если по
какой-либо причине одна из упомянутых выше компонент начнет работать
10
некорректно, то работа всей компании может остановиться до исправления
ошибок. Что еще хуже, потеря данных клиента или их некорректная обработка
может привести к нарушению законодательства, судебным разбирательствам, и,
как
следствие,
потере
репутации
компании.
Кроме
того,
постоянно
добавляемые новые действия системы также должны работать стабильно и
корректно решать возлагаемые на них задачи, начиная с момента их ввода в
эксплуатацию.
На
основе
проведенного
обзора
можно
отметить,
что
единая
информационная система группы компаний «Гарант» является сложным
многомодульным продуктом, который решает множества различных задач
пользователей, постоянно развивается и при этом требует поддержания
высокого уровня качества программного обеспечения. Контролировать такую
систему вручную невозможно. Одна из хорошо зарекомендовавших себя
практик по повышению надежности программного обеспечения – покрытие
кода тестами. Тестовая база ЕИС насчитывает несколько тысяч тестов.
Поддержание актуальности и полноты этой базы занимает значительную долю
времени разработчиков, поэтому у компании появилась необходимость в
автоматизации этого процесса. Но перед проработкой методики автоматизации
тестирования необходимо проанализировать, какие подходы к тестированию
существуют и какие из них лучше всего подходят для проверки корректности
бизнес-процессов специализированного депозитария.
1.2.
Анализ существующих практик тестирования
Тестирование – это проверка соответствия между реальным поведением
программы
и
ее
ожидаемым
поведением
в
специально
заданных,
искусственных условиях. Разберем это определение по частям.
Специально заданные, искусственные условия, – те условия, где
осуществляется тестирование. При этом ключевым аспектом здесь является
11
наличие
тестов
–
воспроизводимых
шагов
манипуляции
с
системой,
приводящих к ее некорректной работе. Концепция теста очень важна, так как
необходимо не просто обнаружить некорректное поведение системы, а создать
и зафиксировать алгоритм воспроизведения ошибки – чтобы повторить его для
разработчика или чтобы разработчик сам смог воспроизвести ошибку. Если
ошибка не воспроизводится, то нет возможности ее исправить.
Ожидаемое поведение программы. Исходной информацией для
тестирования является знание о том, как система должна себя вести, то есть
требования к ней или к ее отдельной части. Самым распространенным
способом тестирования является тестирование методом черного ящика (рис.
1.1), когда реализация системы недоступна тестировщикам, а тестируется
только ее интерфейс. Часто это закрепляется и организацией коллектива –
тестировщики
оказываются
отдельными
сотрудниками
и
в
некоторых
компаниях они даже принципиально не общаются с разработчиками, чтобы
минимально знать детали реализации и максимально полно выступить в роли
проверяющей инстанции.
На рисунке 1.1 видно, что на основе требований к системе создается
реализация и тестовая модель системы. Тестирование есть сопоставление двух
этих представлений с целью выявить их несоответствия. Чем независимее друг
от друга будут эти представления, тем больше пользы от их сопоставления.
Иначе, если тестировщики существенно используют информацию о реализации
системы при составлении тестов, то они могут невольно внести в тесты ошибки
реализации. С другой же стороны, найденное при тестировании несоответствие
– это еще не ошибка, поскольку сами тестировщики могли неправильно понять
требования, в тестах и средствах тестирования могли быть ошибки.
12
Требования
Реализация
системы
Тестовая модель
Тестирование
Несоответствия
Рисунок 1.1. Тестирование методом черного ящика
Источник: Тестирование / НОУ ИНТУИТ [27]
Альтернативным же подходом является тестирование методом белого
ящика. Оно предполагает, что внутренняя структура/устройство/реализация
системы известны тестировщику. Входные значения выбираются, основываясь
на знании кода, который будет их обрабатывать. Точно так же известен и
результат этой обработки. Общая задача такого тестирования - обеспечить
проверку каждого шага по алгоритму программы. Основное преимущество всех
типов стратегий тестирования «белый ящик»: при тестировании принимается
во внимание структура всей программы, что облегчает обнаружение ошибок
даже
в
том
случае,
когда
спецификации
программного
обеспечения
недостаточно определенные или неполные [10]. Стратегия Белого ящика
включает в себя следующие методы тестирования:
покрытие
операторов
(подразумевает
оператора программы, по крайней мере, один раз)
13
выполнение
каждого
покрытие решений (необходимо составить такое число тестов, при
которых каждое условие в программе примет как истинное, так и ложное
значение)
покрытие условий (если после составления тестов у нас останутся
не покрытые операторы, то необходимо дополнить набор тестов таким образом,
чтобы каждый оператор выполняется не менее одного раза)
покрытие решений и условий (необходимо составить тесты так,
чтобы результаты каждого условия выполнялись хотя бы один раз, результаты
каждого решения так же выполнялись хотя бы один раз, и каждый оператор
должен быть выполнен хотя бы один раз)
комбинаторное покрытие условий (все возможные комбинации
результатов условий в каждом решении, а также каждый оператор выполнились
по крайней мере один раз)
Результирующий набор тестов получается достаточно большим даже при
небольшом размере тестируемого кода. Поэтому данный вид тестирования
имеет смысл применять только для отдельных частей программы, а не для всей
системы в целом.
Тесты могут быть «ручными» и автоматизированными [16]. «Ручной»
тест – это последовательность действий тестировщика, которую он (или
разработчик) может воспроизвести, и ошибка повторится. Как правило, в
средствах контроля ошибок такие последовательности действий содержатся в
описании ошибки. Автоматический тест – это некоторая программа, которая
воздействует на систему и проверяет то или иное ее свойство. Автоматический
тест, по сравнению с «ручным», можно легко воспроизводить без участия
человека. Можно создавать наборы тестов и прогонять их регулярно например, в режиме регрессионного тестирования.
Описанные выше подходы декларируют, каким образом тесты должны
создаваться или выполняться. Однако их форма зависит так же и от общей
стратегии тестирования, выбор которой обуславливается целями и масштабами
14
проводимой проверки. Наибольшее распространение получили следующие
виды тестирования:
модульное тестирование – тестируется отдельный модуль, в отрыве
от остальной системы. Самый распространенный случай применения –
тестирование модуля самим разработчиком, проверка того, что отдельные
модули, классы, методы делают действительно то, что от них ожидается.
Созданные разработчиком модульные тесты часто включаются в пакет
регрессионных тестов и, таким образом, могут запускаться многократно.
интеграционное
тестирование
–
два
и
более
компонента
тестируются на совместимость. Это очень важный вид тестирования, поскольку
разные компоненты могут создаваться разными людьми, в разное время, на
разных технологиях. Этот вид тестирования, безусловно, должен применяться
самими программистами, чтобы, как минимум, удостовериться, что все живет
вместе в первом приближении. Далее тонкости интеграции могут исследовать
тестировщики. Необходимо отметить, что такого рода ошибки – «ошибки на
стыках» - непросто обнаруживать и устранять. Во время разработки все
компоненты вместе не готовы, интеграция откладывается, а в конце
обнаруживаются трудные ошибки (в том смысле, что их устранение требует
существенной работы). Здесь выходом является ранняя интеграция системы и
использование практики постоянной интеграции в дальнейшем.
системное тестирование – это тестирование всей системы в целом,
как правило, через ее пользовательский интерфейс. При этом тестировщики,
менеджеры и разработчики акцентируются на том, как ПО выглядит и работает
в целом, удобно ли оно, удовлетворяет ли оно ожиданиям заказчика. При этом
могут открываться различные дефекты, такие как неудобство в использовании
тех или иных функций, забытые или «скудно» понятые требования.
регрессионное тестирование – тестирование системы в процессе ее
разработки и сопровождение на регресс. То есть проверяется, что изменения
системы не ухудшили уже существующей функциональности. Для этого
15
создаются пакеты регрессионных тестов, которые запускаются с определенной
периодичностью – например, в пакетном режиме, связанном с процедурой
непрерывной интеграции.
нагрузочное тестирование – тестирование системы на корректную
работу с большими объемами данных. Например, проверка баз данных на
корректную обработку большого (предельного) объема записей, исследование
поведение серверного ПО при большом количестве клиентских соединений,
эксперименты с предельным трафиком для сетевых и телекоммуникационных
систем, одновременное открытие большого числа файлов, проектов и т.д.
стрессовое тестирование – тестирование системы на устойчивость к
непредвиденным ситуациям. Этот вид тестирования нужен далеко не для
каждой системы, так как подразумевает высокую планку качества.
приемочное тестирование – тестирование, выполняемое при
приемке системы заказчиков.
Жизненный цикл единой информационной системы в группе компаний
«Гарант» построен в соответствии с принципами Continuous Integration
(непрерывная интеграция). Они подразумевают, что каждое изменение в коде
перед тем, как стать частью развертываемой системы, обязано пройти стадию
автоматического тестирования. Практика тестирования была введена с самого
начала разработки системы, и на момент написания данной выпускной
квалификационной работы набор применяемых тестов включает в себя около
двух тысяч модульных и интеграционных тестов. Их написанием занимаются
разработчики, и это занимает до 20% их рабочего времени. Поэтому
руководством
компании
было
принято
решение
о
необходимости
автоматизации процесса создания и поддержки автотестов.
Кроме того, необходимо также учитывать тот факт, что вся система
написана на языке программирования C#, а окружающая ее инфраструктура
выполняется и взаимодействует с операционной системой Windows 10 и .NET
16
Framework 4.6. Поэтому при поиске решения задачи автоматического создания
тестов необходимо рассматривать только те варианты, которые работают в той
же среде. Использование другого окружения (например, популярных на
сегодняшний день языков Python и Java и их сред исполнения), внесет
дополнительный побочный эффект, связанный с взаимодействием с .NET
Framework и CLR. Как результат, тесты могут начать сигнализировать об
ошибке даже тогда, когда тестируемая программа работает корректно. Также
внедрение таких решений потребует дополнительных затрат от компании на
конфигурацию и поддержку новых сред исполнения.
Таким образом, тестирование может проводиться различными способами
в зависимости от специфики тестируемого программного обеспечения. В
контексте контроля качества ЕИС наиболее интересным и полезным является
регрессионное интеграционное тестирование алгоритмов обработки данных с
помощью программных средств и фреймворков, работающих с C# и CLR.
Автоматизация процесса написания тестов – это отдельная проблема, которая
подразумевает автоматическую генерацию кода тестов.
1.3.
Анализ существующих программных продуктов для автоматической
генерации тестов
Покрытие кода тестами – актуальная задача для любого крупного
проекта,
который
имеет продолжительный жизненный цикл.
Поэтому
профессия тестировщика на сегодняшний день не менее популярна, чем
профессия разработчика. Однако, как и многие другие процессы, создание
тестов профессиональным тестировщиком уже имеет автоматизированные
альтернативы [14].
Попытки создать
универсальные
инструменты для
генерации тестов можно найти как в публичных проектах с открытым
исходным кодом, так и в законченных коммерческих продуктах. Поэтому перед
собственного инструмента автоматизации тестирования необходимо
17
ознакомиться с уже имеющимися аналогами. Их анализ поможет, в первую
очередь, определить актуальность проблемы создания собственного нового
программного обеспечения. В частности, необходимо оценить возможность
применения
рассмотренных
готовых
продуктов
к
имеющейся
единой
информационной системе компании и качество создаваемых тестов. Кроме
того, в процессе ознакомления с программными средствами, решающими
похожую задачу, можно найти новые идеи для определения функционала
будущего собственного решения или найти прототипы, чей код можно будет
частично использовать в своей реализации.
Итак,
программные
средства,
предоставляющие
возможности
по
автоматической генерации тестов, можно разделить на две категории, исходя из
основополагающей методики тестирования – методом черного или белого
ящика.
Pex (Program EXploration) является утилитой для создания тестов
методом белого ящика [36]. Она является хорошим помощником программисту
и выводит парадигму программирования через тестирование (test driven
development, TDD) на новый уровень. Pex анализирует .NET программы и
создает параметризованные модульные тесты с высоким уровнем покрытия
кода.
В дополнение,
если созданные
тесты падают,
Pex предлагает
программисту пути исправления выявленных ошибок [34].
Основные возможности Pex:
1.
Pex автоматически генерирует параметризованные тесты и тестовые
наборы входных и выходных данных. Новые наборы тестовых данных
создаются, основываясь на анализе результатов использования предыдущих.
2.
Легко интегрируется с популярными фреймворками тестирования
(VSTS, NUnit, MsUnit, и другие). Pex предоставляет атрибуты для обозначения
классов и методов, подлежащих тестированию.
3.
Легко вызывается из контекстного меню Visual Studio.
18
4.
Созданные параметризованные тесты могут быть преобразованы в
классические модульные тесты, которые можно запускать и без Pex. Также для
них создаются необходимые атрибуты и xml документация.
5.
Во время анализа тестируемого кода Pex также выявляет некоторые
ошибки времени исполнения. Например, выход за границы массива. Для
найденных уязвимостей также создаются отдельные наборы входных данных,
позволяющие засечь возможную ошибку.
6.
Результаты работы Pex формируются в удобный для чтения отчет.
Он включает в себя информацию о каждом тесте, обнаруженных ошибках,
возможных путях их исправления, степени покрытия кода и т.п.
7.
Легко интегрируется в отдельный тестовый проект. Pex также
следит за отсутствием дублей и устаревших тестов.
8.
Pex дополнительно предоставляет утилиту командной строки для
исполнения созданных тестов.
Pex – это интересный молодой проект, но он слабо применим для
тестирования бизнес-логики приложения, так специализируется на статическом
анализе кода и позволяет выявлять именно ошибки кодирования.
Parasoft
программного
dotTEST.
Parasoft
обеспечения,
–
это
независимый
специализирующийся
на
производитель
автоматизации
тестирования и безопасности приложений [32]. Parasoft dotTEST – это набор
утилит для тестирования .NET приложений, который дополнительно может
работать как плагин Visual Studio. Он поддерживает такие практики, как
статический анализ кода, генерация модульных тестов и их исполнение,
покрытие кода и метрики кода. Существует два режима создания тестов:
1.
сценариев
Unit Test Genie: Позволяет создать фабрику тестовых методов и
тестирования
благодаря
разработанному
мастеру
настройки
dotTEST. Благодаря ему, можно детально настроить процесс генерации тестов.
19
2.
Автоматическая генерация тестовых наборов. С помощью данного
режима можно создать большое число маленьких тестов, тем самым добившись
высокой степени покрытия кода.
dotTEST также позволяет анализировать и запускать тесты, создавать
отчеты их выполнения. Он работает с популярным фреймворком NUnit, но
также поддерживается и Microsoft Unit Tests. Кроме того, dotTEST включает
себя модуль статического анализа, который позволяет анализировать угрозы
безопасности приложения. Для обнаруженных угроз также предусмотрена
функция генерации теста, выявляющая уязвимость.
Parasoft dotTEST – коммерческий продукт. Его стоимость на 10
пользователей на год равняется $192,699.42, что делает неприемлемым его
использования в качестве генератора тестов для программного обеспечения
«Гаранта».
NStub – генератор шаблонов модульных тестов сборок .NET с открытым
исходным кодом [35]. Данное программное обеспечение имеет графический
интерфейс, позволяющий указать сборки и методы, для которых необходимо
создать тесты. После этого на каждый указанный метод будет создан пустой
тест с соответствующей документацией, готовый для интеграции с выбранным
фреймворком тестирования. После этого остается наполнить сгенерированные
методы логикой. NStub является полностью расширяемым, то есть его
достаточно легко адаптировать под любой язык платформы .NET, под любой
проект или фреймворк тестирования. Конечно же, он не является полноценным
генератором тестов, но существенно облегчает работу по формированию
инфраструктуры тестов.
Все вышеописанные продукты позволяют создавать тесты методом
белого ящика, то есть основываются на имеющемся коде. Это может быть
полезно для создания базы регрессионных тестов, которые проверяют, что с
каждым новым обновлением поведение тестируемого участка кода не
20
изменилось, а значит существующий функционал не нарушил свою работу. Но
одной из специфических особенностей единой информационной системы в
группе компаний «Гарант» являются частые изменения в большинстве
компонентов, а особенно – в слое бизнес-логики. Сгенерированные тесты
потеряют свою актуальность в течение месяца, а значительную часть рабочего
времени придется уделять удалению устаревших тестов. К тому же такие
небольшие модульные тесты позволяют проверить элементарные блоки кода
ограниченного
размера.
Задачи
же,
возлагаемые
на
разрабатываемый
инструмент автоматизации тестирования, больше относятся к проверке
корректности работы бизнес процессов, которые могут выполняться как на
маленьких участках кода, так и внутри больших последовательностей действий,
охватывающих несколько модулей и их взаимодействие.
Другой же парадигмой тестирования является тестирование методом
черного ящика. Оно больше подходит для решения поставленных задач, так как
тесты, написанные в соответствии с данной методологией, будут проверять
корректность
именно
бизнес-процессов,
без
привязки
к
постоянно
изменяющейся реализации.
MSpec
–
фреймворк,
реализующий
принципы
behaviour-driven
development (BDD, разработка, основанная на описании поведения) [39]. Он
позволяет писать тесты, проверяющие ожидаемое поведение системы без
лишних деталей реализации. Особенностью данного фреймворка, как и подхода
BDD в целом, является близость исходного кода тестов к чистому
разговорному английскому языку. Он декларирует несколько вспомогательных
классов, название которых совпадает с английскими словами (Establish,
Because, It, Cleanup и другие) и которые формируют «каркас» теста. С одной
стороны, они являются скелетом исполнения действий теста. С другой же
стороны, они заставляют разработчика структурировать исходный код теста в
связный английский текст. Данные конструкции также участвуют в
21
формировании результатов теста. В итоге, сообщения об обнаруженных
ошибках при падении теста представляют собой связный английский текст и
могут быть поняты не только квалифицированным программистом.
Пример теста, написанного с помощью данного фреймворка приводится в
листинге 1.1:
[Subject("Authentication")]
public class When_authenticating_an_admin_user
{
Establish context = () => Subject = new SecurityService();
Because of = () => Token = Subject.Authenticate("username", "password");
It should_indicate_the_users_role = () => Token.Role.ShouldEqual(Roles.Admin);
It should_have_a_unique_session_id = () => Token.SessionId.ShouldNotBeNull();
static SecurityService Subject;
static UserToken Token;
}
Листинг 1.1. Исходный код теста, написанный с помощью MSpec
Даже без знания используемого языка программирования C# из кода
можно понять, что данный тест устанавливает определенный контекст
исполнения, с помощью которого получает токен по логину и паролю и
проверяет, что полученный токен принадлежит роли администратора и имеет
уникальный идентификатор сессии.
Такой инструмент позволяет сократить время на написание тестов и
сделать их более читаемыми, но на создателе автотестов все так остается задача
кодирования, знания внутренней архитектуры приложения, что ограничивает
область его применения.
Другой популярной реализацией концепции BDD является фреймворк
SpecFlow [38]. Процесс создания тестов строится в два простых этапа:
1.
Описание ожидаемого поведения с помощью синтаксиса, близкого
к чистому английскому языку. На этом же этапе автоматически составляется и
документация.
22
2.
Привязка описанных спецификаций к реальному приложению.
После завершения первого этапа, SpecFlow сгенерирует шаблоны тестов, в
которые необходимо подставить ссылки на реальные классы и методы
тестируемой системы.
После завершения второго шага тесты готовы для выполнения. Они так
же имеют выразительный синтаксис, близкий к разговорному языку, и
понятные обычному человеку отчеты об ошибках.
Оба описанных выше инструмента являются программным обеспечением
с открытым исходным кодом и, как следствие, бесплатны для использования.
Они значительно упрощают понимание того, что происходит в тесте и где
возникает ошибка для обычного человека. Но несмотря на всю их
выразительность и близость к натуральному языку, тесты пишутся напрямую
на языке программирования C#, и, как следствие, накладывают жесткие
ограничения на используемые конструкции. Кроме того, они должны вручную
связываться с реальными классами в исходном коде единой информационной
системы. Для разработчиков это может потребовать дополнительного времени,
а для аналитиков делает невозможным создание собственных тестов, так как
они не имеют доступа к коду. Кроме того, кажущееся простым действие по
написанию какого-либо теста, в процессе выполнение может столкнуться с
наличием множества неочевидных побочных эффектов и зависимостей,
связанных
со
сложностью
тестируемой
системы.
Таким
образом,
рассмотренные выше продукты могут помочь в тестировании небольшого или
архитектурно прямолинейного проекта, но в контексте рассматриваемой ЕИС
группы компаний «Гарант» их преимущества и удобства сводятся к нулю в
виду высокой сложности тестируемого кода.
Отдельную нишу на рынке поддержки процесса разработки и, в
частности, тестирования ПО занимаются продукты компании IBM [25]. IBM
стремится полностью интегрировать клиентов в свою экосистему, предоставляя
23
решения для всех этапов жизненного цикла ПО. Для автоматизации
тестирования компания так же предлагает несколько инструментов, каждый из
которых может быть интересен тому или иному покупателю в зависимости от
его потребностей и типа разрабатываемого программного комплекса.
IBM Rational Tau используется для стандартизованной разработки
программного обеспечения и сложных систем на основе моделей [37].
В этой модели пользователь может задать в любой последовательности
входные воздействия для просмотра результатов воздействия требуемого
функционала. В системе есть возможность отслеживания значений переменных
и нахождения ошибок на ранних этапах. Кодогенераторы генерируют почти
100% готовый код на 4 языках. Такой подход позволяет сосредоточить усилия
разработчиков именно на создании модели и ее функционала, а не на написание
кода, который неизбежно ведет к ошибкам. При изменении операционной
системы или процессора нужно лишь изменить настройки кодогенератора.
Дополнительное преимущество – поддерживается возможность следовать
рекомендациям OMG-группы, а именно: перейти от широко используемой в
прошлом стратегии CDA [Code-Driven Architecture] к новой стратегии MDA
[Model-Driven Architecture].
Возможности IBM Rational Tau:
•
поддержка разработки сервис-ориентированной архитектуры (SOA)
•
автоматическая проверка ошибок
•
анализатор на базе моделей.
•
возможность совместной работы пользователей
•
автоматизация документирования
•
автоматическая генерация и выполнение тестов
•
открытая архитектура, основанная на UML 2.1
24
•
установка на операционные системы: Windows, Sun Solaris.
•
использование MSС-диаграмм (Message Sequence Chart)
•
кодогенераторы C#, Java, С, С++.
Компания IBM предоставляет средства для генерации автотестов в
рамках семейства продуктов Rhapsody, к которому помимо Tau можно также
отнести и два дополнения к нему – Rhapsody Auto Test Generator (ATG) и
Rhapsody Test Conductor Add-on.
Rhapsody Auto Test Generator (ATG) – это инструмент генерации
тестовых наборов, использующий Unified Modeling Language (UML). ATG
использует C++ для разработки.
Возможности ATG:
•
с помощью ATG можно провести модульное, интеграционное или
регрессионное тестирование.
•
генерация кода тестов происходит на основе описанной модели
•
автоматически поддерживается статистика покрытия кода тестами
Test Conductor Add-on – дополнение, которое позволяет создавать тесты
с помощью графического интерфейса.
Возможности Test Conductor Add-on:
возможность проведения юнит и интеграционного тестирования
создание тестов для C++, C, Java, Ada на основе последовательностей
состояний
создание тестов для C и C++ на основе блок-схем
расширенные возможности визуального анализа успешного срабатывания
тестов
Как уже было указано выше, IBM Rational Tau вместе со своими
дополнениями специализируется на разработке ПО согласно парадигме Model25
Driven Architecture. Такой подход декларирует, что первичной в программе
должна быть модель (данных, преобразования данных). И на основе описанной
модели должен уже создавать и код, и тесты для него. При этом значительная
часть кода уже создается в автоматическом режиме, то есть генерируется. Эта
архитектура является интересным решением, которое может существенно
облегчить и повысить качество разработки многих продуктов. Но применение
IBM Rational Tau к единой информационной системе группы компаний
«Гарант» потребовало бы полного перестроения архитектуры приложений,
которое разрабатывалось на протяжении многих лет, и, вероятно, не дало бы
ожидаемого качества продукта в виду высокой сложности и запутанности
бизнес-процессов (то есть модели, в терминологии MDA).
Помимо описанных выше продуктов, IBM предлагает и другое решение,
подходящее
для
«классических»
приложений,
архитектура
которых
описывается в виде кода: IBM Rational Functional Tester (RFT). RFT — это
платформа для тестирования функциональности и регрессии программного
продукта. Она поддерживает языки программирования: Java, SAP, .Net, Flex и
Ajax. Главной ее особенностью является функция storyboard testing, благодаря
которой все действия пользователей записываются и визуализируются в виде
последовательных изображений – скриншотов приложений на различных
этапах их тестирования.
Возможности:
запись регрессивного тестирования
использование ScriptAssure для повышения отказоустойчивости
проверка динамического и статического содержимого приложений
поддержка наборов тестовых данных для каждого отдельного теста
Очевидно,
такой
подход
идеально
подходит
для
тестирования
графического интерфейса, так как создание теста и способ проверки реального
поведения тесно связаны с визуализированной составляющей. В случаях, когда
26
эта визуальная составляющая достаточно тесно связана с внутреннем
состоянием системы, RFT подойдет и для проверки бизнес-логики приложения.
К сожалению, этого нельзя сказать о единой информационной системе группы
компаний «Гарант». По причине большого количества факторов, влияющих на
результат выполнения операции и участвующих в этой операции неявно, без
отображения в графическом интерфейсе, применение RFT к ЕИС «Гаранта»
приведет к генерации большого количества ложно срабатывающих тестов.
Также стоит отметить, что целевая аудитория компании IBM – компании,
занимающиеся крупной корпоративной разработкой. IBM предоставляет
удобные продукты, но все они имеют enterprise лицензию с соответствующей
ценовой политикой. Преимущества от работы с IBM становятся очевидными
тогда, когда компания интегрирует их инструменты в процесс разработки на
нескольких (или всех) этапах, чего нельзя сказать о группе компаний «Гарант».
Таким
образом,
рассмотрев
несколько
готовых
решений
для
кодогенерации автотестов ПО, можно отметить, что на рынке существует
множество проектов, которые могут помочь разработчикам сократить время на
написание тестов и повысить их качество. Но каждое из них не подходит для
автоматизации тестирования ЕИС ГК «Гарант» по одной из следующих
причин:
Требуется существенная переработка кодовой базы для соответствия
требованиям кодогенератора к общей архитектуре приложения.
Кодогенератор специализируется на другом типе приложений и, как
следствие, не способен тестировать наиболее важную часть бизнес-логики
Сгенерированные тесты не рассчитаны на частые изменения в коде
приложения, приводят к большому количеству ложных срабатываний
Сгенерированные тесты требуют значительных доработок со стороны
разработчика
27
Идеального
инструмента
общего
назначения
для
кодогенерации
автотестов не существует из-за того, что для высокого качества теста он должен
быть тесно завязан на код приложения, на его архитектуру и ключевые классы,
методы [26]. В корпоративном сегменте разработки ПО большая часть
продуктов
опирается
на
собственную,
закрытую
архитектуру
с
нестандартными, специфичными для предметной области решениями. Тем не
менее, исследование существующих продуктов имеет практическую пользу и
для разработки собственного инструмента автоматизации создания тестов, так
как после изучения различных подходов со своими индивидуальными
преимуществами и недостатками, можно принять взвешенное решение о
предъявляемых
требованиях
к
собственному
решению,
форме
его
взаимодействия с пользователем и выбрать оптимальный способ его
реализации.
1.4.
Постановка задачи на разработку методики автоматизации процесса
создания автотестов ПО
Основная цель, которую компания планирует достичь благодаря
разрабатываемой методике автоматизации процесса создания автотестов ПО –
это сократить свои расходы на создание новых автотестов, проверяющих
корректность
бизнес-логики
различных
алгоритмов
обработки
пользовательских данных. Это означает, что разрабатываемая методика не
обязана быть универсальным инструментом, позволяющим писать тесты на все
компоненты единой информационной системы. Это существенно упрощает
возможную реализацию данной методики и сужает ее возможности, сферу
применения, но вместе с тем позволяет получить более качественный продукт
за счет разумных издержек. Типичный тест, автоматически созданный
посредством разработанного инструмента, описывается следующим сценарием:
28
1.
Создать акционный портфель и связанные с ним сущности
(например, юридическое лицо, к которому относится данный портфель)
2.
Провести проверяемую операцию (например, покупку акций на
бирже)
3.
Рассчитать стоимость портфеля
4.
Сверить полученную на шаге 3 стоимость с ожидаемым значением
Кроме того, помимо расчета стоимостей акционных портфелей в
обязанности специализированного депозитария входит проверка корректности
совершаемых клиентом действий. Таким образом, второй типовой сценарий
описывается следующим алгоритмом:
1.
Создать портфель акций и связанные с ним сущности
2.
Попытаться провести проверяемую операцию
3.
Убедиться, что проводимая на втором шаге операция завершилась с
ошибкой
Однако при разработке методики автоматического создания автотестов,
нужно учитывать, что ее внедрение может дать как положительный эффект в
виде оптимизации затрат на создание новых тестов, так и отрицательный
эффект в виде дополнительных затрат на поддержание автоматически
созданных тестов [8]. Поэтому при постановке требований к будущей методике
необходимо отметить требования качества выходных тестов. Здесь существует
два аспекта качества:
1.
Детализация тестов. Слишком детализированные тесты могут
проверять множество внутренних промежуточных этапов обработки данных,
тем самым ограничивая разработчиков в возможностях реализации. Такие
тесты потребует при внесении изменений в основной код дублировать эти
изменения в код тестов, что снизит скорость разработки основной бизнеслогики. При высокой изменчивости бизнес-требований и алгоритмов обработки
данных в единой информационной системе группы компаний «Гарант»
29
внедрение таких тестов существенно замедлит общую скорость разработки
нововведений.
Другая же крайность некачественных тестов – это тесты, которые не
способны отловить ошибки в тестируемом коде. Такое поведение могут
демонстрировать тесты со слишком низкой детализацией, либо тесты, которые
оторваны от реальных условий использования проверяемых алгоритмов и
привязаны к тестовому окружению. Пользы от таких тестов практически нет,
они несут с собой лишь вред за счет создания некорректного представления об
уровне покрытия кода тестами.
2.
Поддерживаемость самих тестов. Автоматические тесты – это тоже
код, который так же, как и основной код бизнес-логики, со временем может
меняться по объективным на то причинам. Например, если клиент в новых
требованиях указал, что комиссия при переводе денежных средств должна
составлять не 10%, а 5%, это должно быть отражено и в коде тестов тоже, так
как вместе с изменением требований меняется и ожидаемое конечное состояние
системы. Поэтому код тестов должен быть таким же понятным, читаемым и
легко модифицируемым, как и основной код приложения.
Еще один ключевой фактор, который необходимо учесть при разработке
реализации
данной
методики
–
это
ее
интегрируемость
в
единую
информационную систему. Данная система представляет собой набор из 20
несвязанных между собой простых модулей, нескольких конечных модулей,
собирающих в себе функционал простых модулей, и модулей ядра системы – 10
тесто связанных сборок .NET Framework, от которых зависят все остальные
элементы системы. Такая архитектура позволяет относительно легко и
независимо разрабатывать и поддерживать каждый отдельный модуль,
реализующий свою конкретную задачу. Как результат – любой модуль может
быть легко расширен без необходимости в изменении других компонентов
системы. Исходя из этого формируются дополнительные требования к
разрабатываемой методике: она должен быть так же легко расширяема, как и
30
система в целом. При разработке методики стоит учитывать, что ее реализация
будет работать в окружении многомодульной системе на платформе .NET
Framework.
Выводы по первой главе
В первой главе данной выпускной квалификационной работы проводится
анализ предметной области и обосновывается решение о необходимости
разработки
методики
автоматизированного
тестирования
для
единой
информационной системы группы компаний «Гарант».
В первой части главы проводится обзор деятельности компании и ее
программного
комплекса
(ЕИС).
ЕИС
представляет
собой
сложный
многомодульный продукт, решающий множество задач по учету и обработке
ценных бумаг. Корректность его работы является чрезвычайно важной для
компании, так как ошибки в его работе могут привести к финансовым потерям,
судебным разбирательствам, отзыву лицензии. В ГК «Гарант» высокая
надежность
программного
обеспечения
достигается
всесторонним
и
непрерывным тестированием. Из-за высокой доли затрат на проведение этого
процесса компания решила рассмотреть возможность его оптимизации.
Вторая часть главы посвящается исследованию зарекомендовавших себя
методик тестирования. Рассматривается тестирование методами белого и
черного ящика, их преимущества и недостатки. По итогам обзора принято
решение об использовании «черного» ящика в виду более высокого качества
тестов в условиях постоянно меняющейся кодовой базы тестируемого
продукта. Также здесь приводится классификация тестов по типу решаемых
ими задач. Наиболее интересными в контексте ЕИС являются модульные,
интеграционные и регрессионные тесты.
31
В третьей части главы проводится обзор существующих готовых
продуктов на рынке кодогенерации автотестов. Рассматриваются различные
решения, создающие автотесты на основе имеющегося кода, модели данных,
UML
диаграмм,
графического
интерфейса
тестируемого
продукта.
Инструменты, следующие популярной парадигме разработки BDD, (такие как
MSpec и SpecFlow) предоставляют удобный интерфейс для создания легко
читаемых тестов, текст которых похож на разговорный английский язык и
может быть понятен людям, не знакомым с программированием. Тем не менее,
написание таких тестов все равно требует навыков программирования и
погружение в кодовую базу приложения. Широкий спектр инструментов для
автоматизации тестирования предоставляет компания IBM, но их применение
оправдано только при более глубокой интеграции процессов разработки в
экосистему продуктов IBM. Как итог проведенного обзора, принято решение о
необходимости
разработки
собственного
решения,
более
тесно
интегрированного в архитектуру тестируемого приложения, и вбирающего в
себя наиболее интересные преимущества рассмотренных ранее программных
средств.
В конце главы приводятся более формализованные требования к
разрабатываемому инструменту: он должен позволить создавать автотесты
бизнес-логики за счет меньших затрат, но при этом качество автоматически
созданных тестов должно соответствовать качеству уже существующих тестов:
они должны проверять корректность алгоритмов обработки пользовательских
данных без погружения в детали реализации этих алгоритмов, а код тестов
должен быть читаемым и легко модифицируемым.
32
ГЛАВА 2. РАЗРАБОТКА И РЕАЛИЗАЦИЯ МЕТОДИКИ
ПРОЕКТИРОВАНИЯ ИТ-ИНФРАСТРУКТУРЫ КОНТРОЛЯ КАЧЕСТВА
ЕДИНОЙ ИНФОРМАЦИОННОЙ СИСТЕМЫ ГРУППЫ КОМПАНИЙ
«ГАРАНТ»
2.1.
Разработка методики автоматизированного тестирования единой
информационной системы группы компаний «Гарант»
Для того, чтобы автоматизировать любой процесс, необходимо для
начала формализовать этот процесс в виде алгоритма, последовательности
действий для достижения желаемого результата [11]. Для того, чтобы
автоматизировать создание тестов, необходимо формализовать вопросы, на
которые отвечает разработчик при ручном написании теста:
Каким образом тест должен воспроизводить тестируемое поведение
системы?
Какое поведение системы ожидаемое?
Каким
образом
сравнить
реальное
состояние
системы
с
ожидаемым?
Для разработчика ответы на эти вопросы очевидны: разработчик знает,
где располагается тестируемый код, как подготовить для него тестовое
окружение и как его запустить; понимает, какое поведение системы ожидаемое;
и знает, каким образом из системы вычленить необходимую часть итогового
состояния и сравнить его с эталоном. Однако уже здесь кроется основной
недостаток подхода к написанию тестов разработчиками – он, как автор кода,
при неправильном понимании ожидаемого поведения системы допустит
ошибку дважды – в реализации алгоритма и в реализации теста, проверяющего
этот алгоритм.
33
В случае автоматического создания тестов ответить на эти вопросы
становится значительно сложнее. Исходя из рассмотренных в первой главе
существующих решениях можно отметить два подхода к решению этой
проблемы:
1.
Кодогенерация тестов на основе документации. Такой подход
перекладывает ответственность за контроль качества единой информационной
системы на персонал, который будет заниматься составлением документации,
на основе которой будут генерироваться автотесты. Безусловно, он имеет
некоторые преимущества, уменьшая влияние человеческого фактора на
качество итоговых тестов, но вместе с тем, он несет с собой и некоторые
недостатки, а именно:
Кодогенераторы потребляют в качестве входных данных не
текстовое
описание
алгоритма,
а
его
структурированное
описание
в
специализированном формате. Это означает, что внедрение подобного решения
потребует дополнительного обучения персонала не только культуре написания
качественных тестов, но изучения соответствующего формата описания
алгоритмов.
Кодогенераторы не способны сгенерировать интегрированный в
единую информационную систему код автотестов. Для их внедрения так же
понадобится тратить ресурсы на адаптацию кодогенераторов под код, шаблоны
и интерфейсы ЕИС.
2.
Кодогенерация
тестов
на
основе
записанных
действий
пользователя. Качество тестов при этом остается на том же уровне,
поскольку написанием тестов могут заниматься уже не разработчики, а
аналитики/бизнес-пользователи. Недостаток в виде необходимости написания
кодогенератора в этом подходе так же присутствует, однако кодогенераторы
на вход потребляют уже свой собственный формат представления записанных
пользовательских действий, что упрощает разработку самих кодогенераторов.
34
Основным преимуществом записи действий пользователя является то, что для
создания теста не требует дополнительного изучения форматов представления
алгоритмов обработки данных - пользователь продолжает работать в
привычном для себя интерфейсе системы.
Таким образом, наиболее удобный способ автоматического создания
тестов
–
это
кодогенерация
тестов
на
основе
записанных действий
пользователя. В отличие от использования готовых решений собственная
разработка
позволяет
тесно
интегрировать
кодогенератор
в
единую
информационную систему, предоставив пользователям удобный интерфейс для
записи тестов и получив на выходе читаемые, легко поддерживаемые тесты,
использующие привычные для разработчиков интерфейсы и шаблоны
разработки.
Типовой сценарий взаимодействия пользователя с системой для записи
теста выглядит примерно следующим образом:
1. Нажать на кнопку «Начать запись теста»
2. Произвести манипуляции в системе, воспроизводящие тестируемое
поведение
3. Создать контрольные точки, проверяющие корректность выполненных
действий.
4. Нажать на кнопку «Завершить запись теста».
В результате должен быть сгенерирован исходный код записанного теста.
Таким
образом,
люди,
специализирующиеся
на
бизнес-процессах
компании, смогут контролировать корректность работы информационной
системы напрямую, без участия посредника в лице программиста.
35
2.2.
Разработка методики проектирования ИТ-инфраструктуры контроля
качества системы учета ценных бумаг
Конечно, для успешного внедрения какой-либо технологии в проект
недостаточно обладать лишь внедряемой технологией. Состояние самой
системы, куда интегрируется новая функциональность, также является
немаловажным фактором успешности и даже возможности его расширения или
изменения. В первой части работы было рассмотрено несколько коммерческих
продуктов, позволяющих автоматизировать процесс создания тестов. Но, как
же было отмечено, все они выглядят либо более затратными, либо менее
качественными, чем собственная разработка. Это связано с тем, что каждый
такой
внешний
инструмент
предъявляет
определенные
требования
к
инфраструктуре предприятия, без удовлетворения которых этот инструмент не
способен работать. Например, IBM Rational Tau требует перестроения всей
архитектуры системы в соответствии с принципами Model-Driven Architecture, а
Rhapsody Auto Test Generator требует от пользователей знание языка UML.
Собственная же разработка позволяет спроектировать внедряемую методику
так, чтобы ее требования были удовлетворены минимальными усилиями. Но и
она не лишена недостатка в виде необходимости модификации инфраструктуры
предприятия при внедрении.
Итак, разработанная методика проектирования ИТ-инфраструктуры
контроля
качества
программного
обеспечения
состоит
из
следующих
компонент:
применение расширяемой, открытой к тестированию архитектуры
информационной системы;
разработка
интегрируемого
в
информационную
систему
собственного кодогенератора автотестов на основе пользовательских действий;
проведение непрерывного автоматического тестирования всех
вносимых в кодовую базу изменений;
36
обучение
пользователей,
вовлеченных
в
процесс
создания
автотестов, базовым принципам тестирования программного обеспечения;
организация
процесса
доставки
сгенерированных на
основе
пользовательских действий тестов в общие тестовые контуры.
Ниже приводятся обоснования важности каждой из компонент, а также
даются рекомендации по их реализации на практике.
Первым и самым важным фактором является тестируемость самой
информационной
системы.
Современные
подходы
к
проектированию
программного обеспечения уделяют этому фактору особое внимание, так как
наиболее подходящими для автоматизации являются методики модульного и
интеграционного тестирования [17]. Они подразумевают проверку не всей
системы в целом и за один раз, а проведение валидации корректности работы
отдельных частей системы с помощью множества независимых тестов. Такой
подход позволяет быстро локализовать появляющиеся ошибки и ускорить сам
процесс тестирования, но также он требует от системы возможности запуска
отдельных ее частей в отрыве от всей системы. Достичь такой модульности
программного обеспечения можно с помощью организации кода с применением
методологии инверсии зависимостей (inversion of control, IoC). В соответствии с
этой методологией код должен быть разбит на отдельные модули, а
зависимости каждого модуля должны поставляться ему извне. Таким образом
при необходимости протестировать какой-либо отдельный модуль тест имеет
возможность подменить образ окружающей модуль системы с помощью
специальных имитаторов, подать подготовленные тестовые данные на вход и
сверить полученные выходные данные с эталоном.
Помимо открытости к тестированию от информационной системы
требуется наличие возможности легко интегрировать в нее новый модуль
кодогенерации автотестов, а также предоставить модулю возможность
расширяться и поддерживать новый функционал вместе с ростом самой
37
системы. Разработка основной функциональности и ее тестирование – это два
раздельных процесса, возможно сильно разнесенных по времени. Тесты могут
писаться как до реализации проверяемого сценария, так и одновременно с ней,
или даже сильно позднее. Поэтому инструмент для кодогенерации автотестов
на основе действий пользователя должен быть внешней единицей в общей
системе, и не блокировать процесс разработки и внедрения основной
функциональности. Но при этом разработка самого инструмента не должна
требовать больших усилий от разработчиков, иначе он потеряет свою
актуальность. Достигается такая легкая интегрируемость за счет продуманной
архитектуры приложения [15]. Но для крупных проектов, перед которыми
стоит
потребность
в
автоматизации
процесса
создания
автотестов,
легкорасширяемая архитектура – это жизненно необходимый фактор, без
которого невозможно динамичное развитие самого проекта. Поэтому можно
утверждать, что для компаний, заинтересованных во внедрении разработанной
методики контроля качества программного обеспечения, не потребуется
вносить существенных изменений в структуру проекта для успешной
интеграции нового инструмента кодогенерации автотестов.
Также для построения эффективной архитектуры ИТ-инфраструктуры
контроля качества программного обеспечения необходимо, чтобы в компании
были налажены процессы непрерывного автоматизированного тестирования.
Непрерывное
тестирование
подразумевает
проверку
корректности
всех
вносимых в кодовую базу изменений. Обычно тестирование проводится как
минимум в два этапа:
1.
Тестирование изменений разработчиком до внесения их в общую
кодовую базу. На этом этапе разработчик имеет возможность отладить свои
правки и не допустить публикации заведомо некорректных изменений.
2.
Тестирование изменений после внесения их в общую кодовую базу.
Даже с учетов успешного прохождения первого этапа тестирования,
38
существует возможность одновременного внесения двух или более корректных,
но не совместимых друг с другом изменений. Поскольку каждое изменение
перед публикацией тестируется независимо, необходимо дополнительно
контролировать корректность интеграции всех изменений.
Такой подход позволяет максимально быстро обнаружить, локализовать и
исправить возникающие ошибки.
На сегодняшний день широкое распространение получили методики
непрерывной интеграции и непрерывной доставки изменений (continuous
integration, continuous delivery, CI/CD) [20]. Большинство инструментов для
реализации данных методик (например, TeamCity, Jenkins) позволяют в рамках
процесса непрерывной интеграции настроить и автоматическое тестирование.
Таким образом, за счет внедрения CI/CD компания получает не только
упрощение процессов интеграции и доставки изменений, но также и повышает
эффективность
проводимого
тестирования.
Конечно,
организовать
непрерывное тестирование возможно и с помощью других подходов и
инструментов, но за счет широкого распространения CI/CD процессы
разработки
в
большинстве
компаний
фактически
уже
удовлетворяют
требованию наличия проверки всех вносимых в кодовую базу изменений [29].
Внедрение же разработанной методики автоматического создания тестов
позволяет заметно повысить качество проводимого непрерывного тестирования
за счет увеличения количества тестов и, как следствие, доли покрытого кода
тестами.
Разработанная
методика
кодогенерации
автотестов
подразумевает
участие пользователей информационной системы в процессе тестирования
самой информационной системы. Такой подход подразумевает высокий
уровень доверия к пользователям, и как следствие, делает невозможным
применение данной методики в большинстве информационных систем. Для
компаний, где пользователями системы являются внутренние сотрудники, это
ограничение не является препятствием к внедрению кодогенерации автотестов
39
на основе действий пользователя, но оно может потребовать дополнительных
затрат компании на обучение сотрудников культуре написания тестов. Важно
понимать, что не любые пользовательские действия в системе проверяют
корректность бизнес-логики приложения, а некачественные тесты неизбежно
приведут к отрицательному эффекту за счет наличия большого количества
ложноположительных или ложноотрицательных результатов тестирования. В
группе компаний «Гарант» наиболее подходящим слоем пользователей для
создания автотестов является отдел системной аналитики, так как его
сотрудники с одной стороны достаточно погружены в бизнес-процессы
компании, а с другой стороны обладают техническим образованием и по роду
деятельности часто сталкиваются с необходимостью формализовать бизнестребования в виде пользовательского сценария и ожидаемого конечного
состояния системы.
Также
компания
при
внедрении
разработанной
методики
автоматического создания тестов на основе действий пользователя должна
наладить процессы доставки созданных тестов в тестовые контуры. Типичная
организация процесса создания новых автотестов предполагает внесение кода
автотеста в общую тестовую базу либо разработчиком, либо тестировщиком
[23]. Создание же автотестов через пользовательский интерфейс предоставляет
возможность исключить ручную работу с тестовой базой и автоматизировать и
процесс доставки тестов. На первом этапе внедрения качество тестов может
потребовать дополнительной модерации со стороны ответственных за
тестирование лиц, но при масштабировании такого подхода неизбежно
появится
необходимость
в
дополнительных
программных
решениях,
помогающих исключить посредников из этого процесса. Современные системы
контроля версий и репозитории предоставляют все необходимые интерфейсы
для реализации такой интеграции. Таким образом, техническая часть
реализации рассматриваемого инструмента не ограничивает предприятие в
спектре потенциальных возможностей, но целесообразность разработки такого
40
инструмента и набор предоставляемых функций должен определяться самой
компанией на основе ранее рассмотренных факторов, таких как уровень
квалификации пользователей, наличие и качество систем автоматизированного
тестирования, открытость к расширению самой информационной системы.
Таким образом, эффективная ИТ-инфраструктура контроля качества не
ограничивается лишь использованием разработанной методики кодогенерации
автотестов. Она также затрагивает и вопросы проектирования архитектуры
тестируемого программного обеспечения, включает в себя комплекс мер по
обучению
сотрудников
и
организации
процессов
автоматического
тестирования. Применение разработанной методики целесообразно, когда
существующая ИТ-инфраструктура компании уже удовлетворяет некоторым
перечисленным
ранее
требованиям,
но
ее
внедрение
может
помочь
предприятию существенно сократить расходы на процесс написания тестов.
Как часть реализации данной методики в группе компаний «Гарант» в
работе приводится описание процесса разработки модуля кодогенерации
автотестов для единой информационной системы. Приведенная архитектура
программного средства не является единственно правильной, но позволяет
продемонстрировать, что при наличии расширяемой архитектуры самой
системы разработка нового модуля, автоматизирующего процесс написания
автотестов, является относительно простой задачей, и позволяет за счет
небольших затрат на разработку нового инструмента существенно сократить
расходы на поддержание существующих процессов написания автотестов.
2.3.
Анализ используемых аппаратных и программных средств
Первое, что необходимо сделать, чтобы создать модуль для любой
системы и успешно интегрировать его в эту систему, – это провести анализ
используемых программных и аппаратных средств. Это необходимо, чтобы
41
понять, почему применяются именно эти технологии, а не их аналоги, и
разобраться, как использовать их достоинства и как обходить их недостатки.
В группе компаний «Гарант» работает несколько сотен человек. И почти
все они большую часть времени работают в единой информационной системе.
При этом есть несколько групп пользователей, характер работы которых в
системе сильно разнится в связи с их должностными обязанностями. И, исходя
из этого, система предоставляется им в трех различных формах, что требует
применения различных аппаратных средств. Стоит отметить, что несмотря на
представленные выше различия, все персональные компьютеры и сервера
работают под управлением операционных систем семейства Windows и
используют в своей работе .NET Framework версии 4.5 и выше. Итак,
рассмотрим взаимодействие различных групп пользователей с системой с точки
зрения аппаратной составляющей:
Бизнес пользователи. К данной категории относятся все работники
«Гаранта», производящие операции с реальными данными клиентов. Их работа
– выполнение функций специализированного депозитария или регистратора (в
зависимости от подразделения). Для данного слоя пользователей наиболее
важным является стабильность работы и актуальность данных. Для выполнения
этих функций в компании имеется единый мощный сервер. На нем хранится
база данных с данными клиентов, и исполняется код самой единой
информационной системы. Пользователи же подключаются к нему с
персональных компьютеров через веб-интерфейс.
Разработчики. Разработчики занимаются поддержкой и развитием
ЕИС. Данный процесс подразумевает постоянное внесение нестабильных
правок в работу программного комплекса. Поэтому разработчикам важна
изолированность от реальных данных и от правок других разработчиков.
Каждый разработчик имеет собственную копию единой информационной
системы на персональном компьютере. Также у разработчиков есть общий
42
репозиторий,
хранящийся
на
отдельном
сервере,
куда
отправляется
работающий код. Все вносимые правки автоматически тестируются на
нескольких серверах, используемых исключительно для этих целей.
Аналитики. Данные пользователи являются прослойкой между
разработчиками и бизнес пользователями. Они также занимаются поддержкой
и развитием единой информационной системы, но их работа больше связана с
анализом потребностей бизнес пользователей и выявлением ошибок в работе
программного комплекса. Соответственно, при выборе аппаратных средств для
аналитиков необходимо было найти компромисс между изолированностью,
стабильностью и актуальностью кода и данных. Поэтому у каждого аналитика
есть собственная копия ЕИС, но все они расположены на нескольких
специальных серверах, а работа с ними происходит с помощью персональных
компьютеров. Данные в этих копиях обновляются раз в сутки, а версия системы
может быть выбрана аналитиком самостоятельно.
Программное обеспечение же, в отличие от аппаратного, у всех
пользователей одинаковое, хотя поведение системы может отличаться в
зависимости от того, где она работает (это регулируется переменными
окружения и файлами конфигурации). Единственным исключением является
тип операционной системы: на персональных компьютерах стоит Windows 10
Pro, в то время как серверы работают под управлением Windows Server 2016.
Это позволяет добиться лучшей производительности и более удобного
конфигурирования ОС, но на поведение работающего программного комплекса
влияние практически не оказывает.
ЕИС написана на языке программирования C# с использованием
технологии ASP.NET MVC – веб-фреймворка, разработанного компанией
Microsoft. Аббревиатура MVC расшифровывается как Model-View-Controller
(Модель-Представление-Контроллер)
[19].
Это
архитектура
приложения, в рамках которой оно разделяется на три компоненты:
43
построения
Модель (Model) – предоставляет данные для Представлений в ответ
на запросы Контроллера, содержит бизнес-логику приложения, которая
включает все правила и алгоритмы, связанные с предметной областью
решаемой задачи. Это ядро создаваемого приложения.
Представление (View) – отвечает за пользовательский интерфейс,
отображает данные, полученные от Модели.
Контроллер (Controller) – обрабатывает команды пользователя.
Контролер играет роль связующего звена между Моделью и Представлением.
При этом он стремиться как можно меньше знать о подробностях их
реализаций. Его задача определить Модель для обработки полученной команды
и Представление, которое будет получить итоговые данные.
Рассматриваемая архитектура подразумевает, что изменения в любой из
компонент
оказывают
минимальные
воздействия
на
остальные
части.
Уменьшается зависимость между частями приложения, что увеличивает его
гибкость и расширяемость. Кроме того, заметно увеличивается тестируемость
приложения – появляется возможность разрабатывать тесты для отдельных
компонент, что очень важно в контексте разработки модуля тестирования.
Единая информационная система жестко реализует описанный шаблон
проектирования, разделяя свой код на несколько проектов, реализующих
различные уровни архитектуры MVC.
Любое веб-приложение реализует лишь логику обработки запроса. Такие
приложения должны работать вместе с веб-сервером – программой, которая
принимает HTTP-запросы и отдает HTTP-ответы. В качестве такого веб-сервера
в группе компаний «Гарант» выступает IIS 10 (Internet Information Services –
информационные службы Интернета). Когда он был впервые реализован, IIS
представлял собой базовый веб-сервер. С годами IIS развился в сложный сервер
приложений, предоставляющий широкое множество функциональных средств,
наиболее важным из которых является поддержка хостинга приложений
ASP.NET. IIS поддерживает протоколы HTTP, HTTPS, FTP, POP3, SMTP,
44
NNTP. IIS оперирует пулами приложений [30]. Каждый такой пул является
независимым процессом и может включать в себя несколько сайтов. При этом
ошибки, возникающие в одном пуле, не оказывают влияния на другие пулы.
В качестве базы данных в компании используется Microsoft SQL Server
2017. Данная СУБД представляет собой высокопроизводительную платформу
обработки и анализа данных для бизнеса любого размера, которая отвечает
всем современным требованиям по работе с данными любых типов и
поддержке удобной и быстрой разработки приложений [31]. В базах данных
SQL
Server
2017
можно
хранить
любую
структурированную
или
неструктурированную информацию, такую, например, как изображения и
мультимедиа из самых разнородных источников данных. Продукт предлагает
большой
набор
интегрированных
служб,
расширяющих
возможности
обработки, который позволяет составлять запросы, выполнять поиск, проводить
синхронизацию, формировать отчеты и анализировать данные. SQL Server
обеспечивает обращение к данным из любого приложения, разработанного с
применением технологий Microsoft .NET.
Одной из наиболее важных компонент, поставляемых вместе с SQL
Server и используемых в ЕИС, является SQL Server Reporting Services – службы
отчетов, которые позволяют значительно повысить производительность
построения отчетов и осуществлять быструю обработку запросов.
Кроме
Microsoft
SQL
Server
для
хранения
некоторых
данных
используется MongoDB – документно-ориентированная система управления
базами данных с открытым исходным кодом, не требующая описания схемы
таблиц. Она классифицирована как NoSQL и использует JSON-подобные
документы и схему базы данных [9]. Благодаря своей нереляционной природе,
MongoDB хорошо подходит для хранения неструктурированной информации.
Такой, как логи или аудит производимых действий.
Последней
рассмотренной
технологией
является
используемый
фреймворк тестирования – NUnit. Он был портирован с языка Java (библиотека
45
JUnit) [40]. Первые версии NUnit были написаны на J#, но затем весь код был
переписан на C# с использованием новшеств .NET. Сейчас NUnit – это
библиотека, поставляемая в виде nuget пакета, которая содержит класс Assert,
имеющий множество методов для проверки различных условия (True, NotNull,
DoesNotThrow и т.д.), а также набор атрибутов, необходимых для настройки
тестовых проектов. С помощью этих атрибутов также можно управлять
состоянием системы до и после запуска набора тестов или создавать
параметризованные тесты. Тесты, написанные на NUnit, можно запускать с
помощью консольного приложения либо в используемой среде разработке с
установленным адаптером, который поддерживается командой NUnit.
Таким образом, разработка собственного модуля будет происходить в
окружении нескольких коммерческих и бесплатных продуктов. Большинство из
них конкурирует на рынке программного обеспечения уже долгие годы и за это
время успело доказать свою надежность и удобство. Остальные же являются
молодыми перспективными проектами, которые поддерживаются крупными
сообществами
программистов
и
снабжены
достаточным
объемом
сопутствующей литературы. Это позволяет сделать процесс разработки
собственного модуля быстрым и экономичным, а также уменьшить количество
ошибок, связанных с неправильным использованием этих программных
средств. А применение одинакового набора внешних сервисов во всех частях
единой информационной системы гарантирует единство интерфейсов и
компонент, и, как следствие, облегчает интеграцию модуля и ядра ЕИС.
2.4.
В
Анализ архитектуры единой информационной системы
данном
разделе
рассматриваются
детали
реализации
единой
информационной системы на уровне кода. Для того, чтобы успешно
интегрировать модуль тестирования, необходимо понимать, как работает
система внутри, какие классы и интерфейсы являются основополагающими в ее
46
работе, как устроено взаимодействие ядра системы и множества независимых
модулей. Также нужно разобраться, как устроены тестируемые участки кода,
как можно получить информацию о контексте их исполнения во время записи
теста и воспроизвести этот контекст в тесте. Кроме того, в данном разделе
рассматриваются некоторые примеры неочевидного поведения, которое
необходимо учитывать при работе с системой.
Как
уже
говорилось
в
главе
1,
все
модули
представленной
информационной системы можно разделить на три класса:
Ядро системы состоит из 27 проектов, разделенных на 5 категорий:
модель, представление, контроллер, вспомогательные утилиты и тесты. Первые
три из них в своих зависимостях реализуют шаблон проектирования MVC.
Вспомогательные утилиты содержат различные классы, которые не привязаны
к какой-либо конкретной логике, но могут быть использованы везде. Тестовые
проекты содержат архитектуру тестирования самого ядра и других модулей. В
целом, в данном наборе модулей содержатся классы, необходимые для
поддержания работы системы в самом простом ее виде, без конкретной бизнес
логики и многих функций, используемых конечными пользователями. Также
здесь содержатся классы, которые не являются ключевыми в построении
работы системы, но используются в других модулях. Несмотря на то, что
большинство используемых функций системы расположены не в ядре, оно
является самой критической частью системы, так как ошибки в работе ядра
влияют на все другие модули.
Simple (простые) модули. Данный класс включает в себя около 20
модулей. Каждый такой модуль состоит из 3 проектов: контроллер, веб-проект
(необходим для запуска системы в веб интерфейсе) и тестовый проект.
Большинство простых модулей не имеет связей с другими простыми модулями,
но все они зависят от проектов ядра. Каждый модуль охватывает одну
конкретную функциональную область системы и содержит тесты для нее.
47
Например, существуют модули email рассылки, отчетов, аудита, импорта
данных, документации.
Конечные модули. Таких модулей в системе всего 4. Они не связаны
друг с другом и отвечают за работу различных подразделений компании: 2 из
них предназначены для работы с разными клиентами специализированного
депозитария, 1 – для работы регистратора, и 1 – для взаимодействия с
внешними сервисами, не привязанными к конкретному подразделению.
Конечные модули ссылаются на множество простых модулей и, как следствие,
на ядро. Каждый модуль включает 4 проекта: модель, контроллер, веб-проект и
тесты. В этих модулях сосредоточена бизнес логика, необходимая для работы в
конкретном подразделении, и не предоставляемая простыми модулями или
ядром.
В
сердце
взаимодействия
модулей,
которые
даже
не
знают
о
существовании друг друга, лежит такая ключевая возможность языка C# и
платформы .NET как рефлексия (reflection, отражение). Рефлексия представляет
собой процесс выявления типов во время выполнения приложения [5]. Каждое
приложение содержит набор используемых классов, интерфейсов, а также их
методов, свойств и т.п. Рефлексия как раз и позволяет определить все эти
составные элементы приложения. Кроме того, рефлексия позволяет работать с
такой
особенностью
платформы
.NET,
как
атрибуты
[18].
Атрибуты
представляют собой специальные инструменты, которые позволяют встраивать
в сборку дополнительные метаданные. Атрибуты можно применить к самой
сборке, к классу, методу, конструктору, параметру и т.п. Атрибуты могут
принимать аргументы. С помощью рефлексии во время исполнения программы
из них можно получить заложенную во время компиляции информацию об
элементе.
Также ключевым принципом, на котором построена работа единой
информационной системы, является абстрагирование. Фундаментальная его
идея состоит в разделении несущественных деталей реализации подпрограммы
48
и характеристик, существенных для корректного её использования [13]. Такое
разделение в объектно-ориентированном программировании выражается с
помощью абстрактных классов и интерфейсов. Они являются контрактом,
декларирующим, что реальные объекты, реализующие эти абстракции, также
реализуют и какое-то поведение, то есть обязательно имеют определенный
набор свойств и методов.
Рефлексия с использованием интерфейсов и абстрактных классов
позволяют одним модулям работать с элементами другого, неизвестного
модуля. С помощью методов рефлексии ядро системы собирает информацию
обо всех имеющихся типах во всех модулях, а с помощью абстрагирования уже
работает с ними. Рассмотрим конкретный пример:
В ядре имеется интерфейс IActionExecuteSubscriber, декларирующий два
метода: ActionExecuting и ActionExecuted. Как можно понять из названия
интерфейса,
классы,
реализующие
IActionExecuteSubscriber,
являются
подписчиками на событие исполнения некоторого действия. С помощью
методов этого интерфейса, можно уведомить подписчика о том, что действие
начало и закончило свою работу. В ядре присутствует класс, реализующий
данный интерфейс – он пишет информацию о выполнении действия в логи. Но
также существует класс, реализующий IActionExecuteSubscriber, и в модуле
Audit. Он ведет аудит выполненных действий – какой пользователь его
запустил, сколько времени действие выполнялось, каков его результат. Ядро
при выполнении действия с помощью рефлексии находит всех подписчиков
среди всех классов текущей сборки (а если сборка ссылается на модуль Audit,
то класс аудита также присутствует в этом наборе) и уведомляет их, вызывая
методы ActionExecuting и ActionExecuted. При этом ядру не нужно знать о том,
объект какого именно класса используется – достаточно лишь наличия
контракта существования данных методов.
49
Рассмотренный пример демонстрирует также и другой важный принцип,
используемый в организации кода единой информационной системы, - принцип
инверсии зависимостей. Этот принцип можно сформулировать следующим
образом: «Модули верхнего уровня не должны зависеть от модулей нижнего
уровня. И те, и другие должны зависеть от абстракций.». В описанном выше
примере ни модуль Audit не зависит о реализации ядра, ни ядро не зависит от
модуля
Audit.
Они
оба
зависят
от
абстракции
–
интерфейса
IActionExecuteSubscriber. Данный принцип получил широкое распространение
в программировании, так как он позволяет создавать слабосвязанные
компоненты, которые легко тестировать, модифицировать и обновлять.
Добиться реализации данного принципа можно с помощью инверсии
управления (Inversion of Control, IoC). Для ее реализации существует множество
подходов,
таких
как
шаблон
«фабрика»,
локатор
служб,
внедрение
зависимостей и другие. Существует даже специальный класс программного
обеспечения
–
IoC-контейнеры.
В
единой
информационной
системе
используется один из таких контейнеров – Windsor Installer. Его использование
скрыто за собственным статическим классом IoC, позволяющим получить
необходимые зависимости с помощью обобщенных методов ResolveAll и
Resolve (используется для получения единственного экземпляра). Он также
позволяет внедрять зависимости через конструктор. Таким образом, большая
часть программного комплекса представляет собой набор провайдеров –
классов, реализующих некоторый функционал, и доступных с помощью вызова
IoC.ResolveAll.
Например,
в рассмотренном
выше
примере,
менеджер
выполнения действий получает всех подписчиков с помощью простого вызова
IoC.ResolveAll< IActionExecuteSubscriber>().
На основе рефлексии в системе построено множество механизмов. Один
из них, наиболее примечательный, - это механизм событий. В языке C# есть
встроенное понятие события – это специальные методы и переменные
50
определенного типа, которые позволяют объекту уведомить всех подписчиков
это события о том, что что-то произошло (например, изменилось значение
поля). Но в единой информационной системе под событиями понимаются
классы, реализующие интерфейс IEntityEvent. Такие классы помечаются
специальным атрибутом FireOn, который указывает, в каких ситуациях
необходимо вызывать данное событие (создание, обновление или удаление
сущности), и имеют метод Execute, который получает контекст события,
содержащий всю сопутствующую информацию. События нужны в системе, в
основном, для двух целей:
Операции контроля. События проверяют некоторые инварианты,
которые должны сохранятся на протяжении всей жизни сущности. Например,
если попытаться создать пользователя с русскими логином, событие выбросит
исключение с сообщением о невозможности данной операции.
Операции изменения данных. Такие события могут изменять либо
саму сущность, для которой они были вызваны, либо сопутствующие ей
сущности. Например, при изменении режима выполнения запланированных
действий с «Выполнять каждую неделю» на «Выполнять вручную» необходимо
также удалить настройки времени выполнения.
События могут сильно влиять на поведение системы. Поэтому при записи
тестов необходимо учитывать их наличие, так как если просто изменить поля
сущности без вызова событий, поведение в тесте будет отличаться от реального
поведения. Есть несколько способов создания, изменения или удаления
сущностей с вызовом соответствующих событий. Самыми удобными из них
являются классы Creator (позволяет создавать и изменять сущности),
DocumentCreator (позволяет создавать и изменять документы с помощью
специального механизма – операций) и ReferenceDataObject (позволяет удалять
сущности). Работа с Creator будет рассмотрена в разделе «2.3. Состав и
структура программного средства».
51
Большинство
дополнительные
действий
в
параметры,
системе
требуют
запрашиваемые
для
у
своей
работы
пользователя
и
конкретизирующие детали работы действия. В ЕИС параметры реализованы с
помощью исключений ParameterRequiredException. Такой механизм позволяет
запрашивать параметр из любой части кода. При выбрасывании исключения
оно поднимается по стеку вызовов до уровня контроллера ASP.NET, где
обрабатывается, и пользователю отображается окошко с просьбой заполнить
параметр. Также существует специальный тип параметров – Interactive. Они
работают по тому же принципу, но требуют лишь дополнительного
подтверждения у пользователя.
Параметры также необходимо учитывать при генерации тестов. Если не
сохранить параметр во время записи теста или не заполнить его вручную в коде
самого теста, то тест будет всегда падать, так как в нем будут возникать
исключения.
Диспетчеризацией
параметров
в
системе
занимается
IParameterProvider. Получив экземпляр IParameterProvider с помощью IoC,
можно во время записи теста достать уже заполненные параметры, а во время
выполнения теста установить их же, чтобы выполняемое действие прошло без
ошибок и повторило записанное поведение.
Также особое внимание стоит уделить тонкостям работы с используемой
ORM (Object-Relational Mapping, объектно-реляционное отображение) —
технологией
программирования,
которая
связывает
базы
данных
с
концепциями объектно-ориентированных языков программирования, создавая
«виртуальную объектную базу данных». В единой информационной системе
группы компаний «Гарант» используется ORM DataObjects.Net [33]. Она
позволяет создавать структуру базы данных из имеющихся классов в коде. Все
классы, данные которых должны храниться в базе данных, наследуются от
класса Entity. Также DataObjects с помощью атрибутов позволяет настроить
способы представления иерархий наследования, индексы таблиц, различные
52
связи сущностей. К преимуществам данной ORM можно отнести ее
расширяемость: она предоставляет множество точек входа для дополнения
своего функционала при конфигурации базы данных, генерации SQL запросов
или просто работе с полученными из БД сущностями. Как и многие другие
ORM, DataObjects предоставляет возможность строить запросы к БД с
помощью LINQ (Language-Integrated Query, встроенные в язык запросы).
Делается это с помощью статического класса Query. Конечно, работа с базой
данных накладывает определенные ограничения на функционал объектов,
полученных с помощью DataObjects. В частности, все объекты, унаследованные
от класса Entity, привязываются к сессии базы данных. Это позволяет
отслеживать изменения в сущностях и вносить их в базу автоматически: при
изменении свойств объекта или создании объекта в коде также меняются и
соответствующие записи в БД. Но у этого есть и свои недостатки: любая работа
с объектом после закрытия сессии вызывает исключения. Это создает проблему
сохранения информации о сущности между сессиями: если во время записи
теста просто сохранить ссылку на сущность, то при завершении записи теста,
получить значения ее полей уже будет невозможно. Для решения этой
проблемы в ЕИС существует понятие контейнеров: это набор классов, который
хранит непривязанные к сессии данные, из которых можно однозначно
восстановить сущность. Изначально они предназначались для передачи
информации на сторону клиента (в браузер) и обратно, но они так же хорошо
подходят и для сохранения состояния сущности при записи тестов. Всего в
системе насчитывается около 10 видов контейнеров, хранящих разные типы
данных. Получить контейнеры можно с помощью сервиса IContConv,
преобразующего набор значений свойств объекта в набор контейнеров и
обратно.
И,
наконец,
необходимо
разобраться
с
тем,
разрабатываемый модуль в систему и как получать
как
информацию о
выполняемых в системе действиях. Для этих целей хорошо подходит
53
встроить
описанный выше интерфейс IActionExecuteSubscriber, который позволяет
подписываться на выполнение всех действий в системе. В ЕИС существует
менеджер
выполнения
действий
IActionsProvider,
который
находит
необходимое действие и запускает его. При этом перед запуском он вызывает
ActionExecuting у всех подписчиков, передавая информацию о выполняемом
действии и о контексте его выполнения. После же завершения действия он
вызывает ActionExecuted, также передавая информацию о действии и о
результате его выполнения (выброшенное исключение, если оно есть). Таким
образом, модуль генерации тестов сможет получать всю необходимую
информацию, реализуя указанный интерфейс. Если же в работе ему
понадобятся другие дополнительные сервисы системы, получить их можно
будет с помощью инверсии контроля в виде статического класса IoC.
Подводя итог проведенному анализу, можно отметить, что единая
информационная система группы компаний «Гарант» – это расширяемый
программный
комплекс,
который
позволяет
без
проблем
встроить
разрабатываемый модуль автоматического создания тестов в несколько точек
взаимодействия ядра системы с остальными компонентами, и тем самым
отследить и записать необходимые действия пользователя. Кроме того,
собственная библиотека вспомогательных классов позволяет генерировать
лаконичный, понятный код, который можно будет легко читать и поддерживать
в будущем.
2.5.
Состав и структура разрабатываемого программного средства
В постановке задачи на разработку методики указано, что генерируемый
код должен быть читаемым и понятным, в точности повторять поведение
системы во время записи теста, а также содержать только существенные
инструкции, производящие реальные манипуляции с данными. Чтобы добиться
этого, для каждого действия, работа которого влияет на тестируемое поведение,
необходимо писать свой обработчик. Только зная, что делает действие, можно
54
полно и точно воспроизвести его. Поэтому центральным понятием в
разрабатываемом модуле является интерфейс IGeneratedTestRecordProvider –
провайдер (поставщик) записей генерируемого теста. Реализации данного
интерфейса участвуют в обработке выполнения всех действий системы. Если
провайдер знает, как обработать действие, то он создает соответствующую
запись. Кроме того, такие поставщики должны иметь механизм взаимодействия
друг с другом. Это нужно по нескольким причинам:
В реальной работе системы постоянно происходят изменения
состояния объектов, а каждый вызов метода может влиять на результаты
предыдущих и последующих действий. Поэтому для создаваемых записей
также нужно предоставить возможность влиять на поведение других записей.
Многие действия можно разделить на группы, в которых все
элементы будут иметь схожий алгоритм работы, назначение или используемые
зависимости. Такое общее поведение должно выноситься из провайдеров,
чтобы избежать дублирования кода. Таким образом, необходимо выделить
некоторые служебные провайдеры, которые не создают никаких записей, но
участвуют в формировании результирующего теста, предоставляя свои услуги
для других, реальных провайдеров.
Сгенерированный тест – это не просто повторение записанного
поведения системы. Тест также должен проверять корректность выполненных
действий. Соответственно, для некоторых механизмов таких проверок также
необходимо наличие специальных провайдеров. Например, если в тесте нужно
убедиться, что действие должно выдать ошибку из-за невыполнения каких-то
условий, то вызов такого действия должен оборачиваться в Assert.Catch. Для
этого специальный провайдер должен поймать такую ошибку во время записи
теста и сгенерировать соответствующий ей блок проверки.
Вопрос
взаимодействия
слабосвязанных
или
даже
несвязанных
провайдеров – самая сложная задача в разработке данного модуля. Одним из
55
шагов, предпринятых для ее решения, является применения топологической
сортировки при разрешении приоритетности провайдеров [12]. Другой шаг для
достижения поставленной цели – вынесение результатов работы провайдеров в
отдельную сущность. Это позволяет собрать сгенерированные записи вместе и
обработать их как единой целое, с учетом их влияния друг на друга [22].
Таким образом, в модуле появляется еще один ключевой интерфейс –
IGeneratedTestRecord. Он представляет собой сгенерированную запись. Записи
могут представляться различными классами и создаваться различными
провайдерами, но всех их объединяет то, чтобы у них есть метод GenerateCode,
позволяющий сгенерировать исходный код теста в строковом представлении.
Здесь же стоит отметить, что, в соответствии с постановкой задачи,
генерируемый текст должен быть отформатирован и легко читаем. Поэтому для
генерации
кода
используется
встроенный
в
платформу
.NET
класс
определено
поле
IndentedTextWriter, позволяющий создавать текст с отступами.
Также
в
интерфейсе
IGeneratedTestRecord
AdditionalActions, содержащее коллекцию дополнительных, побочных действий
записи. Они должны реализовать интерфейс IAdditionalAction, позволяющий
указать, когда данное действие активируется (при генерации класса тестов, на
старте/в конце теста или непосредственно до/после записи-владельца). Такие
дополнительные действия позволяют создавать контекст, необходимый для
выполнения основной записи. Также они используются для явного выражения
побочных эффектов или зависимостей.
Рассмотренные выше интерфейсы и их реализации являются элементами,
выполняющими отдельные функции разрабатываемого модуля. Каждый из них
берет на себя небольшой кусок ответственности, специализируясь лишь на
каких-то конкретных записываемых действиях. Таких элементов может быть
несколько десятков или сотен, но также в модуле должно быть определенное
ядро, сердцевина, которая определяет схему работы компонент в целом и не
56
подлежит переопределению в других местах. Таким ядром является класс
GeneratedTestManager. Он выполняет несколько функций:
Является входной точкой в модуль. Данный класс реализует
интерфейс IActionExecuteSubscriber, а, значит, при выполнении любого
действия в системе, рассмотренный выше ActionsProvider вызовет его методы
ActionExecuting и ActionExecuted. Именно благодаря этой особенности модуль
организует свое
взаимодействие
с единой информационной системой,
отслеживая выполнение действий без оказания влияния на них и исполняя
возложенные на него обязанности.
Включает/выключает запись тестов. Поскольку данный класс
является входной точкой перед запуском всех провайдеров, то именно он и
определяет, нужно ли вообще запускать их работу. У него имеются публичные
статические методы StartNewRecording и StopRecording, позволяющие начать и
закончить запись теста, а с помощью свойства IsRecording можно определить
текущее состояние. Также стоит отметить, что при изменении состояния
вызываются соответствующие события, позволяющее провайдерам и другим
элементам системы подготовиться к новой записи теста/очистить данные после
окончания старой.
Управляет
хранилищем
записей
текущего
теста.
GeneratedTestHistory – небольшой класс, хранящий список созданных в
текущей сессии записей. Он также имеет поле, указывающее на пользователявладельца (несколько пользователей не могут записывать тесты одновременно)
и IndentedTextWriter.
Синхронизирует
потоки.
Благодаря
единой
точке
запуска
провайдеров, модуль генерации тестов гарантирует, что провайдеры не будут
работать параллельно даже при параллельном выполнении действий в системе.
Определяет
порядок
работы
топологической сортировки.
57
провайдеров
с
помощью
этапа:
Запускает работу провайдеров. Работа провайдеров строится в три
подготовка,
попытка
создания
записи,
освобождение
ресурсов.
GeneratedTestManager вызывает соответствующие методы провайдеров в
нужном порядке и записывает результаты в текущую историю теста.
Обеспечивает безопасную работу модуля с точки зрения единой
информационной системы. Вся работа с провайдерами происходит в try-catch
блоках. При возникновении ошибки запись теста прекращается. Если бы
GeneratedTestManager не обладал подобной функциональность, то наличие хотя
бы одного неправильно работающего провайдера сделало бы работу с системой
невозможной, так как в таком случае обработка действий завершалась бы с
ошибкой еще до запуска самого действия.
Описанная выше архитектура модуля представлена на рисунке 2.1:
ActionExecuted
ЕИС
Generated
Test
Manager
ActionExecuted
ActionExecuted
ActionExecuted
IGeneratedTestRecord
Provider №1
IGeneratedTestRecord
Provider №2
IGeneratedTestRecord
Provider №3
IGeneratedTestRecord
Provider №4
IGeneratedTestRecord
GeneratedTestHistory
Код теста
Рисунок 2.1. Архитектура разрабатываемого модуля
Источник: составлено автором с помощью Microsoft Visio
58
Такая схема обработки действий позволяет создать модуль генерации
тестов,
который
будет
достаточно
функциональным,
расширяемым
и
безопасным. Однако для удобной работы также необходимо создать элементы
пользовательского интерфейса, а именно служебные кнопки и пункты меню.
Итак, в разрабатываемом модуле тестирования присутствуют:
Базовый
класс
GeneratedTestActionBase,
который
позволяет
создавать действия, генерирующие записи теста. Такие действия скрываются,
когда запись теста не осуществляется.
Два
пункта
меню
(расположены
в
разных
местах):
GeneratedTestActionsGroupSystemContext и GeneratedTestActionsGroupSubMenu.
Они также скрываются, когда функционал записи тестов недоступен, и служат
для размещения сгруппированных действий в выпадающем списке.
текст,
StartStopTestAction – действия начала/окончания записи теста. Его
внешний
вид
и
поведение
зависят
от
текущего
состояния
GeneratedTestManager.IsRecording. Если запись теста еще не начата, то данное
действие позволяет начать ее. Иначе же оно обрабатывает все созданные
IGeneratedTestRecord’ы вместе с их IAdditionalAction’ами, генерируя текст
созданного теста. Данный текст по окончанию выводится пользователю и
может быть исправлен и отправлен в пул сгенерированных тестов.
Рассмотрев ключевые классы и интерфейсы модуля, познакомимся с
реализованным на их базе функционалом на примере нескольких провайдеров и
действий, участвующих в создании тестов.
SaveButtonRecordProvider является, наверно, самым ярким примером
того, как должен работать провайдер. Объекты данного класса умеют
обрабатывать нажатие на кнопку «Сохранить». При его написании необходимо
было учитывать несколько важных аспектов:
Сохраняемая сущность может иметь любой тип. Код провайдера не
должен меняться от сущности к сущности.
59
У
всех
сущностей
в
системе
первичный
ключ
(Id)
в
соответствующей таблице в SQL имеет тип uniqueidentifier, чему в платформе
.NET соответствует тип Guid. При записи теста с сохранением информации о
сущности также сохраняется и ее Id. При этом если сущность была создана во
время записи теста (с помощью кнопки «Сохранить»), во время выполнения
теста ей нужно присвоить новый, уникальный Id, а все использования этой
сущности производить с учетом измененного идентификатора. Для этих целей
к
генерируемой
записи
добавляется
дополнительное
действие
GenerateIdAdditionalAction, которое создает и инициализирует переменную с
новым Guid’ом. Все связи «старый Id – имя сгенерированной переменной»
хранятся в истории текущего теста и используются при форматировании
Guid’ов. Таким образом, в сгенерированном тесте вся работа будет происходить
уже не со старым, неактивным идентификатором, а с новой переменной,
ссылающейся на созданную сущность. Если в тесте изменяется состояние уже
существующей сущности, а не создается новая, то тогда перезаписи Id не
происходит.
Поведение во время выполнения теста должно повторять поведение
во время его записи. В данном случае, недостаточно просто создать экземпляр
сущности, необходимо также вызвать связанные с ней события. В единой
информационной системе для этих целей предназначен класс Creator. Он
позволяет заполнить значения изменяемых полей и создать/обновить сущность.
Для удаления сущности используется класс ReferenceDataObjects, который так
же вызывает все необходимые события при выполнении метода DeleteItem.
Тест должен быть выразительным и понятным. Поэтому при
изменении одного поля сущности, необходимо в Creator’е указать только одно
измененное поле. Чтобы определить, какие именно поля были изменены,
необходимо сохранить старые значения до выполнения действия и сравнить их
со значениями после. Такое поведение требуется не только в провайдере
кнопки «Сохранить», поэтому для сохранения и сравнения полей был создан
60
ActionExecuteHistoryContainersProvider, который будет рассмотрен ниже. В
работе SaveButtonRecordProvider’а необходимо лишь указать, что он зависит от
ActionExecuteHistoryContainersProvider, и воспользоваться его услугами, когда
это будет необходимо.
Пример результатов работы данного провайдера приведет в листинге 2.1:
var id1 = Guid.NewGuid();
new Creator<RegEntity>()
.SetId(id1)
.Set(e => e.SysName, "Test")
.Set(e => e.DateCreated, new DateTime(2020, 5, 15))
.Create();
Листинг 2.1. Пример результатов работы провайдера, отвечающего за
создание сущности
Рассмотренный провайдер игнорирует наличие параметров. Если в одном
из событий изменения сущности запрашивается параметр, то сгенерированный
тест будет падать из-за ParameterRequiredException. Поскольку параметры
могут использоваться во всех действиях, а не только в действии сохранения
сущности, был создан специальный ParametersRecordProvider. На этапе
освобождения ресурсов провайдеров (после создания записи), он проверяет,
была ли создана запись. Если новая запись найдена, то данный провайдер
добавляет в ее список дополнительных действий два действия: создать
параметры (выполняется до основной записи) и очистить параметры
(выполняется после основной записи). Таким образом, все сгенерированные
записи будут снабжены двумя дополнительными строчками, делающими
работу теста идентичной работе системы во время записи.
ActionExecuteHistoryContainersProvider
–
служебный
провайдер,
упомянутый выше. Он не создает записей, но предоставляет свои услуги по
сохранению состояния сущности до выполнения действия. Как было упомянуто
ранее, особенность работы ORM DataObjects.NET заключается в том, что
сущности привязываются к сессии базы данных. Это означает, что если
61
сохранить значения ссылочных полей во время выполнения действия, то во
время генерации кода, получить эти значения уже будет нельзя. Решение,
применяемое в единой информационной системе, заключается в том, что для
различных типов полей существуют различные классы-контейнеры, хранящие
значения полей в безопасном виде. Соответственно, работа данного провайдера
состоит в том, чтобы на стадии инициализации всех провайдеров сохранить
сущность в такие контейнеры и позднее предоставить доступ к ним.
Также
в
разрабатываемый
модуль
был
добавлен
класс
ContainerEqualityHelper, который умеет сравнивать значения контейнеров. С его
помощью можно сравнить старые и новые контейнеры и получить список
измененных полей, например, для передачи их Creator’у. Для форматирования
контейнеров и других типов данных при генерации исходного кода был создан
интерфейс IGeneratedTestDataFormatter. Получив необходимый обработчик
теста для конкретного типа поля с помощью IoC.Resolve, можно вызвать его
метод Format, и в генерируемый код будет записано корректное представления
сохраненного значения. Всего в модуле описано 15 таких обработчиков для
различных типов данных, но за счет использования инверсии контроля и
рефлексии этот список может быть расширен до неограниченного размера.
MustThrowRecordProvider – еще один служебный провайдер записей. Он
работает вместе с действием MustThrowAction. После активации последнего
модуль начинает ожидать возникновения ошибки. Когда же такая ошибка
произойдет, указанный провайдер попытается найти другой провайдер, для
действия без ошибки, получить его запись и обернуть ее в Assert.Throws. Таким
образом в системе можно контролировать ожидаемое возникновение ошибки.
Если действие внутри Assert.Throws выполнится без исключения, тест
сигнализирует об этом.
CheckExpressionFormAction
–
действие,
генерирующее
операции
контроля. Оно отображается на форме редактирования сущности и позволяет
62
проверить
корректность
состояния
этой
сущности.
Например,
после
совершения нескольких транзакций можно проверить, что итоговый баланс
некоторого юридического лица стал равен определенному значению (сумме
этих транзакций). Для этого необходимо выполнить это действие на форме
нужного юридического лица, указать условие «it.Balance == 123», и если во
время выполнения теста его баланс будет отличаться от 123, то тест выявит
ошибку.
SaveToVariableAction – еще одно действие, помогающее сделать процесс
записи тестов более гибким. Оно позволяет сохранить указанное значение поля
в переменную. У него есть два режима работы, которые влияют на то, каким
образом будет получено значение переменной: сохранено в контейнер во время
записи или получено динамически во время выполнения. При этом в
зависимости от выбранного режима используются разные классы записей.
Созданные переменные можно использовать далее в тесте, например, для
проведения операций контроля.
Общая структура взаимодействия классов изображена на рисунке 2.2.
Рисунок 2.2. Диаграмма ключевых классов и интерфейсов модуля
Источник: составлено автором с помощью Microsoft Visual Studio
63
На этой диаграмме можно наблюдать четкое разделение всех классов на
описанные выше четыре группы:
Независимые
побочные
эффекты
действий
в
системе
–
IAdditionalAction’ы.
Записи,
генерирующие
основной
код
действий
–
IGeneratedTestRecord’ы. Умеют создавать IAdditionalAction’ы, так как зачастую
для самой записи известно, какие побочные эффекты она в себе несет.
Поставщики записей – IGeneratedTestRecordProvider’ы. Главное их
предназначение – создавать сами записи теста. Однако многие реализации
данного интерфейса так же могут модифицировать созданные ранее записи с
помощью добавления новых побочных эффектов. В разработанном модуле
присутствует
большое
количество
провайдеров,
и
все
они
являются
практически независимыми. Их схема наследования представлена на рис. 2.3:
Рисунок 2.3. Диаграмма классов поставщиков записей теста
Источник: составлено автором с помощью Microsoft Visual Studio
64
Вспомогательные
действия
для записи теста
–
наследники
GeneratedTestActionBase. Позволяют модифицировать процесс обработки
провайдеров, либо же создать специальные записи напрямую, без провайдеров.
Отдельно стоящий класс GeneratedTestManager. Знает обо всех
существующих
провайдерах
и
взаимодействует
с
ними.
Он
также
предоставляет некоторые сервисы, связанные с изменением статуса записи
теста, для всех элементов модуля.
Благодаря такому разделению классов и жесткой организации их
зависимостей, достигается высокий уровень контроля над кодом. В частности,
локализация ошибок занимает гораздо меньше времени по сравнению с работой
в слабоструктурированном коде с неявными побочными эффектами. А при
создании новых провайдеров и записей нет необходимости изобретать
собственный способ внедрения их в существующую структуру классов. Вместо
этого можно воспользоваться преимуществами реализованной архитектуры,
унаследовав новый класс от необходимого типа, и сосредоточить свои усилия
на написании логики самой генерации исходного кода тестов.
2.6.
Документация на разработанное программное средство
Кроме самого кода каждое программное средство должно иметь и
документацию. В единой информационной системе, где количество доступных
действий исчисляется сотнями, вопрос о наличие и качестве документации
стоит особенно остро. Поэтому сопровождение системы комментариями и
инструкциями проводится на трех различных уровнях:
Документация на уровне кода. В соответствии с внутренними
правилами оформления кода все публичные классы и методы должны быть
снабжены xml комментариями. Соблюдение этих норм контролируется во
время компиляции с помощью дополнения StyleCop. Подобные xml
65
комментарии используются во многих компаниях, так как они позволяют
разработчикам быстрее ориентироваться в коде. Но в ЕИС их применение
особенно
важно,
поскольку
данные
комментарии
являются
базовой
документацией, выводимой пользователю в веб-интерфейсе.
Редактируемые настройки документации. Полученные из кода
комментарии также доступны для редактирования. Определенные группы
пользователей имеют доступ к настройкам элементов интерфейса. Это
подразумевает то, что они могут дополнить или изменить подписи и описание
кнопок. Внесенные изменения хранятся в базе данных, то есть сохраняют свое
состояние в долгой перспективе.
Отдельный модуль документации. В единой информационной
системе также присутствует специальный модуль, который предоставляет
пользователям удобный доступ к полнотекстовой документации. В ней указаны
все особенности работы действия и инструкции к использованию. Такая
документация хранится в отдельной базе данных.
Итак, для снабжения пользователей справкой в разрабатываемом модуле
были применены xml-комментарии ко всем публичным классам. Это позволило
дать краткое пояснение новым элементам интерфейса, но и не ограничило
пользователей в возможности расширения имеющейся документации.
Сама же работа с модулем (а не с отдельными его элементами) не требует
от пользователей каких-либо сложных манипуляций, а основные рекомендации
указаны в инструкции ниже:
1.
Весь функционал данного модуля не активен вне записи теста
2.
Чтобы начать запись теста, необходимо выполнить действие «Start
new test recording» в меню «Generated tests» на главном экране системы (Рис.
2.5):
66
Рисунок
2.4.
Начало
записи
теста
Источник: составлено автором при работе с ЕИС
3.
Во время записи теста работа с системой происходит в обычном
режиме.
4.
Для успешного создания теста необходимо воспроизвести действия,
повторяющие тестируемое поведение. При этом рекомендуется добавлять
контрольные точки с проверками условий везде, где это необходимо.
5.
Для создания контрольных точек необходимо выполнить действие
«Check expression» в меню «Actions» - «Generated tests» на форме проверяемого
элемента или над таблицей проверяемой сущности (Рис. 2.6). Данное действие
требует заполнить выражение условия проверки на модифицированном языке
C#, используемом во многих других частях ЕИС (Рис. 2.7). Данное условие
должно быть верно, когда сущность имеет ожидаемое состояние, и неверно в
обратном случае. Если выражение будет заполнено некорректным текстом,
пользователю будет выведена ошибка с указанием ошибки синтаксиса.
Рисунок 2.5. Вызов диалога для ввода условия проверки
Источник: составлено автором при работе с ЕИС
67
Рисунок 2.6. Ввод условия проверки
Источник: составлено автором при работе с ЕИС
6.
Для указания того, что следующее действие должно
выдать
ошибку, необходимо воспользоваться кнопкой «Generated tests» - «Must throw
an error» на главном экране системы (Рис. 2.8).
Рисунок 2.7. Указание, что следующее действие завершится ошибкой
Источник: составлено автором при работе с ЕИС
7.
Промежуточное состояние необходимых данных можно сохранять в
переменные с помощью действия «Save to variable» в контекстном меню поля
(Рис. 2.9). При этом данное действие запрашивает (Рис. 2.10) имя переменной и
тип сохранения значения: времени записи или времени исполнения (описание
этих режимов содержатся в разделе «2.3. Состав и структура программного
средства»). Далее в тесте сохраненное значение можно использовать с
помощью знака ‘@’ и имени переменной. Например, «@oldBalance».
68
Рисунок 2.8. Вызов диалога для сохранения значения в переменную
Источник: составлено автором при работе с ЕИС
Рисунок 2.9. Ввод информации о переменной
Источник: составлено автором при работе с ЕИС
8.
Для завершения записи теста необходимо выполнить действие «End
test recording» в меню «Generated tests» на главном экране системы (Рис. 2.8). В
результате пользователю будет выведен исходный код записанного теста (Рис.
2.11), который можно отправить в базу сгенерированных тестов.
69
Рисунок 2.10. Вывод записанного теста
Источник: составлено автором при работе с ЕИС
9.
При возникновении непредвиденных ошибок, пользователю будет
выведено сообщение с информацией об ошибке, а запись теста будет
остановлена.
Таким образом, взаимодействие пользователя с модулем кодогенерации
автотестов реализовано с помощью широко распространенных в системе
интерфейсов, и требует лишь незначительных дополнительных действий. Тем
не менее такой интуитивно понятный интерфейс не ограничивает сферу
применимости модуля: пользователь имеет возможность записывать различные
сценарии, сохранять необходимые в тесте значения во временные переменные,
проверять корректность обработки ошибок и использовать произвольные
выражения при описании ожидаемого поведения системы.
70
Выводы по второй главе
Во
второй
главе
данной
выпускной
квалификационной
работы
описывается процесс разработки и реализации методики проектирования ИТинфраструктуры контроля качества программного обеспечения. В качестве
ключевой идеи данной методики выступает идея кодогенерации автотестов на
основе действий пользователя. Также в данной главе проанализированы и
другие аспекты проектирования ИТ-инфраструктуры всего предприятия, а
именно: грамотная архитектура самой тестируемой информационной системы,
наличие процессов непрерывного тестирования, повышенные требования к
квалификации
сотрудников,
наличие
инфраструктуры
доставки
сгенерированных автотестов в тестовые контуры.
Для разработанной методики приводится пример реализации ключевой ее
компоненты – модуль кодогенерации автотестов. В работе проводится анализ
используемых в компании программных и аппаратных средств, после чего
более детально рассматривается архитектура ЕИС, взаимодействие ядра и
внешних модулей, а также наиболее часто применяемые практики и технологии
программирования. На основе этого шага определяется способ интеграции
разрабатываемого модуля и доступные ему предоставляемые системой сервисы
и вспомогательные классы. Следующий раздел отводится под обзор выбранной
архитектуры
самого
модуля,
его
ключевых
классов
и
интерфейсов,
обосновывается эффективность принятых решений. Здесь же приводятся
примеры некоторых отдельных компонент, демонстрирующие возможности
модуля и дающие рекомендации к программированию. В конце главы
рассматриваются вопросы составления документации и описывается процесс
взаимодействия пользователя с разработанным модулем. Как итог, во второй
главе данной выпускной квалификационной работы разобраны все аспекты
применения и реализации разработанной методики создания автотестов на
основе действий пользователя.
71
ГЛАВА 3. ОЦЕНКА ТЕХНИКО-ЭКОНОМИЧЕСКИХ ПОКАЗАТЕЛЕЙ
РАЗРАБОТАННОГО МОДУЛЯ ТЕСТИРОВАНИЯ
3.1.
Описание результатов испытаний
Для подведения результатов разработки и внедрения программного
средства необходимо провести технико-экономический анализ созданного
продукта. Он позволяет оценить успешность и целесообразность проведенной
работы, а также служит основой для принятия решения о дальнейшей судьбе
проекта. Например, при недостижении необходимого уровня надежности
программное средство необходимо отправить на доработку, а при прохождении
всех проведенных испытаний, наоборот, способствовать его дальнейшему
развитию и внедрению [21].
Оценка качества программного обеспечения – вопрос комплексный,
отраженный во множестве подходов и методик. Для большинства из них
необходимо предоставить набор качественных и количественных показателей,
характеризующих объект исследования [6]. Источником многих таких
показателей являются проведенные в ходе тестирования и отладки испытания и
их результаты. Поэтому обзор и анализ этих испытаний – первый шаг в оценке
технико-экономических показателей продукта.
В ходе тестирования разработанного модуля были проверены следующие
аспекты его работы:
1.
Интеграция модуля с единой информационной системой: внедрение
в пред- и постобработку действий, добавление новых действий и пунктов меню,
доступность предоставляемых ядром сервисов.
2.
Возможность взаимодействия провайдеров.
3.
Надежность работы модуля при наличии циклических зависимостей
и провайдеров, выбрасывающих исключения.
72
4.
Работа в многопоточном и многопользовательском окружении.
5.
Корректность синтаксиса сгенерированного кода.
6.
Форматирование сгенерированного кода.
7.
Идентичность записанного и воспроизведенного в тесте поведения.
8.
Наличие в коде теста только существенных действий пользователя.
9.
Работа с различными типами данных.
10.
Создание, изменение, удаление сущностей с воспроизведением всех
побочных эффектов этих действий.
11.
Возможность
изменения
поведения
одних
записей
другими
записями.
12.
Корректность документации, автоматическое скрытие/отображение
действий, доступных только во время записи теста.
Для тестирования использовалось тестовое окружение, применяемое для
проверки корректности работы системы в процессе регулярного приемочного
тестирования
нового
функционала:
изолированная
копия
единой
информационной системы разворачивалась на общем тестовом сервере с
конфигурацией, максимально повторяющей конфигурацию основной копии
ЕИС. В процессе тестирование было проведено 110 испытаний – попыток
создать
автотест
посредством
разработанного
модуля
с
различными
тестируемыми сценариями. Полученный в результате успешных запусков код
тестов запускался в стандартном окружении автотестов, а также проверялся на
соответствие записанному сценарию.
Все выявленные проблемы были исправлены. Как результат, десять
последних прогонов продемонстрировали корректную работу программного
комплекса. По их результатам можно судить о качестве продукта:
Элементы модуля успешно подключаются к ядру системы, весь
реализованный функционал доступен без дополнительного конфигурирования.
Возникновение ошибок в работе модуля не оказывает влияния на
стабильность системы в целом.
73
Выбранная архитектура позволяет создавать различные провайдеры
и записи, а также организовывать их взаимодействие в распределенной среде.
Сгенерированный
исходный
код
теста
является
читаемым,
понятным корректным C# кодом и соответствует записанному поведению.
Представленные в модуле провайдеры корректно работают с
любыми (даже не известными во время компиляции) сущностями и другими
провайдерами.
Предоставляемые
модулем
элементы
пользовательского
интерфейса полно и точно отражают реализуемый функционал.
Таким образом, разработанное программное обеспечение подтвердило
свою способность создавать корректные, читаемые, поддерживаемые тесты без
участия
разработчика,
а
также
свою
безопасность
для
окружающей
информационной системы. Рассмотренные результаты испытаний послужили
основой для более подробной оценки качественных показателей.
3.2.
Оценка качественных показателей разработанного
программного средства
Под качеством программного обеспечения понимается весь объём
признаков и характеристик программ, который относится к их способности
удовлетворять установленным или предполагаемым потребностям [4]. С одной
стороны, это один из наиболее интересных для владельца продукта параметров.
Но, с другой стороны, его невозможно формализовать в общем виде,
применительно к любой программе. Поскольку перед разными программными
средствами ставятся разные цели, то и требования качества для них
различаются. Например, в банковском приложении наиболее важными
являются безопасность и конфиденциальность данных, а в видеоигре этот
показатель сильно уступает в приоритете дизайну графической части. Поэтому
для оценки качества программного обеспечения разработано несколько разных
74
моделей и стандартов. Наиболее распространенным в Российской Федерации
является международный стандарт ISO 9126 (ГОСТ Р ИСО / МЭК 9126-93) –
«Информационная
технология.
Оценка
программного
продукта.
Характеристики качества и руководство по их применению» [1]. Данный
стандарт выделяет 6 качественных характеристик:
1.
Функциональность характеризует соответствие функциональных
возможностей
программного
обеспечения
требуемой
пользовательской
функциональности.
2.
Надежность – свойство программного средства обеспечивать
работоспособность за определенный период времени.
3.
Практичность
–
характеристика,
определяющая
сложность
понимания, изучения и использования программного средства.
4.
Эффективность
–
соотношение
между
уровнем
качества
функциональности программного средства и используемыми ресурсами в
установленных условиях.
5.
Сопровождаемость – расположенность программного средства к
изменениям (модификациям).
6.
Мобильность – способность программного средства адаптироваться
при изменении аппаратно-операционной среды.
Данная модель при расчете итоговой оценки качества ПО предполагает
оценивание каждого из факторов в отдельности и выставление для них весов,
коэффициентов важности.
Для большинства программных средств, и для разработанного модуля
генерации тестов в частности, наиболее важной характеристикой является
надежность, так как недостаточный уровень надежности может со временем
сделать невозможной какую-либо работу с присутствующим функционалом [7].
Расширение модуля может лишь ухудшить показатели надежности, поэтому на
стадию сопровождения принято допускать только надежное ПО, поддержка
которого не будет требовать от компании дополнительных финансовых затрат
75
на частичное или полное исправление ошибок, допущенных на стадии
разработки.
Надежность
–
свойство
программного
средства
сохранять
работоспособность в течение определенного периода времени, в определенных
условиях эксплуатации с учетом последствий для пользователя каждого отказа
[3]. Работоспособным называется такое состояние программного средства, при
котором оно способно выполнять заданные функции с параметрами,
установленными
требованиями
технического
задания.
С
переходом
в
неработоспособное состояние связано событие отказа.
Для оценивания надежности разработанного модуля была выбрана
модель Коркорэна. Ее характеризуют следующие утверждения:
модель
содержит
изменяющуюся
вероятность
отказов
для
различных источников ошибок и соответственно разную вероятность их
исправления.
в модели используются такие параметры, как результат N
испытаний, в которых наблюдается 𝑁! ошибок i-го типа.
выявление в ходе N испытаний ошибки i-го типа появляется с
вероятностью 𝑎!.
Показатель уровня надежности R вычисляют по следующей формуле:
𝑅 = "! + ∑)
"
!*'
(3.1)
#" ∗("" &')
"
𝑁+ – число безотказных (или безуспешных) испытаний, выполненных в серии
из N испытаний,
k – известное число типов ошибок,
𝑎! — вероятность выявления при тестировании ошибки i-го типа,
𝑌! – вероятность появления ошибок i-го типа: 𝑌! = (
76
𝑎!, при 𝑁! > 0
0, при 𝑁! = 0
Таким образом, для расчета оценки надежности необходимо разделить
испытания на k групп в зависимости от типа тестируемой логики и определить
вероятности
появления
соответствующих
ошибок.
Всего
в
процессе
тестирования было проведено 90 испытаний. 79 из них завершились
безуспешно, то есть не выявили существующих проблем. Статистика успешных
приведена в таблице 3.1:
Таблица 3.1
Результаты испытаний программного комплекса
Количество
выявленных ошибок
(𝐍𝐢)
Вероятность появления
(𝐚𝐢)
Тип ошибки
Ошибки вычисления
Логические ошибки
Ошибки ввода/вывода
Ошибки манипулирования
данными
Ошибки сопряжения
Ошибки
определения
данных
Ошибки работы с базой
данных
5%
20%
10%
30%
0
3
0
4
10%
10%
1
1
15%
2
Используя данные из представленной таблицы, можно посчитать
итоговую оценку надежности программного средства:
𝑅=
+
,+∗(+&')
+
-+
-+
+.'2∗(/&')
-+
Таким
=
+
3+.12
-+
образом,
+./∗(0&')
+∗(+&')
+
-+
-+
+
+.0∗(1&')
+.'∗('&')
+
-+
-+
+
+.'∗('&')
-+
+
= 0.89
с
уверенностью
89%
можно
утверждать,
что
разработанный модуль будет работать стабильно, без сбоев. Учитывая то, что
работа данного программного средства не оказывает влияния на стабильность
окружающей системы в целом и не имеет доступа к реальным данным
клиентов, подобные показатели являются удовлетворительным результатом.
77
Также во время проведенных испытаний было проведено исследование и
других показателей качества. Для этого каждому из вышеуказанных факторов
были сопоставлены две оценки:
Вес 𝑤! – коэффициент важности соответствующего фактора в
рамках рассматриваемого программного средства. Сумма всех таких весов
равняется 1: ∑4!*+ 𝑤! = 1.
Экспериментально установленная оценка 𝑟! – характеристика
соответствия реального поведения системы и представленных в постановке
задачи требований и целей.
Результаты оценки показателей качества представлены в таблице 3.2:
Таблица 3.2
Качественные показатели
Качественные
показатели
Функциональность
Надежность
Практичность
Эффективность
Сопровождаемость
Мобильность
Вес показателя (𝐰𝐢)
0.25
0.3
0.15
0.05
0.2
0.05
Экспериментально
установленная оценка (𝐫𝐢)
0.9
0.89
1
0.7
0.85
0.7
Итоговая оценка качества программного складывается из произведений
оценок 𝑤! и 𝑟!:
𝐾 = ∑4!*' 𝑤! ∗ 𝑟!
(3.2)
𝐾 = 0.25 ∗ 0.9 + 0.3 ∗ 0.89 + 0.15 ∗ 1 + 0.05 ∗ 0.7 + 0.2 ∗ 0.85 +
+0.05 ∗ 0.7 = 0.882
На следующий диаграмме (Рис. 3.1) представлены рассмотренные
характеристики:
78
1,2
1
1
0,9
0,89
0,85
0,8
0,7
0,7
0,6
0,4
0,2
0
Функциональность
Надежность
Эффективность
Сопровождаемость Мобильность
Рисунок
3.1.
Оценка
Практичность
качественных
показателей
Источник: составлено автором с помощью Microsoft Excel
По итогам проведенного анализа можно сказать, что разработанный
программный модуль соответствует представленным в постановке задачи
требованиям на 88%. Это являются хорошим показателем и говорит о том, что
разработка завершена успешно, а полученный продукт может быть применен в
реальном бизнес-процессе.
3.3.
Оценка экономической эффективности
При оценке результатов разработки программного средства важнейшим
показателем также является его экономическая эффективность. Экономическая
эффективность — показатель, определяемый соотношением экономического
эффекта и затрат, породивших этот эффект. Экономическим эффектом
называют выраженную в денежных единицах разницу между доходом,
полученным от определенной деятельности в течении некоторого промежутка
времени и расходами на ее осуществление за тот же период. Таким образом,
расчет экономической эффективности позволяет определить целесообразность
79
разработки и внедрения программного продукта, а также оценить полученную
выгоду или убытки. Поскольку в случае разработки модуля генерации тестов
его внедрение не увеличивает доходы компании, экономический эффект
обуславливается исключительно изменением затрат на поддержку и развитие
единой информационной системы.
Расчет
экономической
эффективности
производится
с
помощью
следующих формул:
Абсолютное снижение трудовых затрат ∆𝑇:
∆𝑇 = 𝑇5 − 𝑇6
(3.3)
где 𝑇5 – трудовые затраты по базовому варианту; 𝑇6 – трудовые затраты
по проектному варианту.
Коэффициент относительного снижения трудовых затрат 𝐾7:
𝐾7 = ∆7 × 100%,
(3.4)
7#
Индекс
снижения
трудовых
затрат
при
повышении
производительности труда 𝑌7:
𝑌7= 7#
(3.5)
7$
Абсолютное снижение стоимостных затрат ∆𝐶:
∆𝐶 = 𝐶5 − 𝐶6,
(3.6)
где 𝐶5 – стоимостные затраты по базовому варианту; 𝐶6 – стоимостные
затраты по проектному варианту;
Коэффициент относительного снижения стоимости затрат 𝐾С:
𝐾С = ∆: × 100%
(3.7)
:#
Индекс снижения стоимости затрат:
80
𝑌С =
:#
(3.8)
:$
Годовой экономический эффект:
Э = ∆𝐶 − 𝐸;: × ∆𝐾,
(3.9)
где 𝐸;< – нормативный коэффициент эффективности капитальных
вложений; константа, которая зависит от области применения; ∆𝐾 –
капитальные вложения при переходе от базового варианта к проектному.
Капитальные вложения при переходе от базового варианта к
проектному ∆𝐾:
∆𝐾 = 𝐾6 − 𝐾5,
(3.10)
где 𝐾5 – капитальные затраты по базовому варианту; 𝐾6 – капитальные
затраты по проектному варианту;
Капитальные затраты по проектному варианту 𝐾6:
𝐾6 = 𝑍р × 𝑁р × 𝑡р,
(3.11)
где 𝑍р – часовая оплата программиста; 𝑁р – число программистов; 𝑡р –
время на разработку программного средства в часах.
Коэффициент эффективности 𝐸; :
𝐸; =
∆:
∆>
(3.12)
Срок окупаемости затрат на внедрение программного средства:
𝑇?> =
Затраты
до
'
(3.13)
@%
внедрения
модуля
генерации
тестов.
Написанием
автоматических тестов в группе компаний «Гарант» до внедрения данного
модуля занимались исключительно разработчики, так как другие сотрудники не
имели достаточной квалификации и знания языка C#, чтобы создавать даже
самые простые тесты бизнес логики. Время, затрачиваемое разработчиками на
81
создание тестов, зависело от тестируемой задачи. При этом практиковались три
модели реализации данного процесса:
1.
Написание падающего теста до решения задачи и проверка его
результатов после. Чаще всего такая модель применялась тогда, когда создание
тестов занимало незначительное время по сравнению с временем решения
самой задачи, так как скорейший выпуск правок имеет более высокий
приоритет, чем фиксация корректности этих правок в виде теста.
2.
В ином же случае правки выпускались без тестов и создавалась
отдельная задача для их написания. При таком подходе время на создание
тестов дополнительно
увеличивалось
за
счет того,
что разработчику
необходимо было заново разбираться в сути проблемы и внесенных
изменениях.
3.
При наличии большого количества смежных и срочных задач,
задачи так же решались без написания тестов. По окончанию работы над всем
набором таких задач несколькими разработчиками в течение длительного
времени писалось большое количество тестов, покрывающих все внесенные
изменения.
Доли времени, потраченного на написание тестов, от общего времени
решения задачи для разных моделей создания тестов и проценты применения
этих моделей приведены в таблице 3.3:
Таблица 3.3
Временные затраты базового варианта
Тип модели написания
тестов
1
2
3
Доля времени написания
тестов от общего
времени решения задачи
10%
20%
18%
82
Доля тестов,
написанных в
соответствии с
выбранной моделью
15%
60%
25%
Таким
образом,
средневзвешенная
доля
времени
разработчика,
потраченная на написание тестов, составляла 𝑡тест:
𝑡тест = 0.1 ∗ 0.15 + 0.2 ∗ 0.6 + 0.18 ∗ 0.25 = 0.18
Согласно производственному календарю, 2019 год при 40-часовой
рабочей неделе состоит из 1970 рабочих часов. В IT-отделе работает 11
разработчиков, которые участвуют в написании бизнес тестов. Итак, трудовые
затраты в год составляли:
𝑇5 = 1 970 ∗ 0.18 ∗ 11 ≈ 3 900 (часов)
Затраты после внедрения модуля генерации тестов. Внедрение нового
модуля
позволило
оптимизировать
затраты
компании
сразу
по
двум
направлениям:
Частичный перенос ответственности за тесты с разработчиков на
аналитиков. Это возможно благодаря тому, что для создания тестов теперь нет
необходимости знать язык программирования C#: это можно сделать с
помощью элементов веб-интерфейса.
Оптимизация времени создания теста разработчиком за счет того,
что выполнять действия в веб-интерфейсе – намного легче и быстрее, чем
искать, конфигурировать и использовать соответствующие классы в коде.
Учитывая
скорость
и
легкость
создания
тестов
с
помощью
разработанного функционала, для аналитика проверка корректности решения
поставленной задачи (включает в себя вникание в задачу и создание одного или
нескольких тестов) занимает 15-20 минут, в зависимости от детальности данной
проверки. Исходя из того, что, разработчики в среднем решают 2 бизнес задачи
в день, трудовые затраты отдела аналитики, в 2019 году (247 рабочих дней)
составят:
𝑇 ан = ',.2 ∗ 2 ∗ 11 ∗ 247 ≈ 1 600 (часов)
6
4+
83
Поскольку тесты, проверяющие бизнес логику, стали составляться
аналитиками, разработчики были освобождены от этой обязанности. Но вместе
с тем, на них, как на более квалифицированных специалистов в области
тестирования, легла задача поддержки и перепроверки созданных аналитиками
тестов. Это подразумевает под собой исключение некорректных тестов,
исправление падающих существующих и расширение неполных тестовых
наборов (например, с помощью того же модуля тестирования). Но даже
учитывая появление новых задач, время, затрачиваемое разработчиками на
тесты, заметно сократилось, так как создание тестов с нуля – более трудоемкая
задача, чем внесение правок в существующие. Исходя из того же числа бизнес
тестов в день (2), поддержка инфраструктуры тестирования стала занимать у
одного разработчика около 30 минут в день.
𝑇раз = 0+ ∗ 11 ∗ 247 ≈ 1 350 (часов)
6
4+
Итого, общие трудовые затраты после внедрения модуля тестирования,
составляют:
𝑇6 = 𝑇ан + 𝑇раз = 1 600 + 1 350 = 2 950 (часов)
6
6
Тогда можно посчитать абсолютное снижение трудовых затрат:
∆𝑇 = 3 900 − 2 950 = 950 (часов)
Коэффициент относительного снижения трудовых затрат:
𝐾7 =
-2+
0 -++
× 100% ≈ 24%
Индекс снижения трудовых затрат при повышении производительности
труда 𝑌7:
𝑌7 = 0 -++ ≈ 1.32
/ -2+
Представленные выше показатели характеризуют изменение трудовых
затрат, то есть времени, необходимого для достижения одинаковых результатов
84
разными
способами.
разработанного
Проведенный
модуля
анализ
тестирования
показал,
положительно
что
внедрение
сказалось
на
эффективности работы персонала, то есть помогло снизить время выполнения
поставленных задач. Но наиболее интересной для компании является оценка
стоимостных затрат, так как ода позволяют подсчитать финансовую выгоду от
разработки данного модуля.
Средняя заработная плата разработчика в группе компаний «Гарант»
составляет 120 тыс. рублей, что в пересчете на почасовую оплату равняется 730
рублей/час. Следовательно, стоимостные затраты до внедрения модуля
тестирования оцениваются как С5:
С5 = 3 900 ∗ 730 ≈ 2 850 000 (рублей)
Для расчета стоимостных затрат после внедрения необходимо также
учитывать оплату работы аналитиков, так как большая часть трудовых затрат
перешла на них. Средняя зарплата аналитика равняется 110000 рублей, то есть
670 рублей/час. Тогда общие стоимостные затраты равняются С6:
𝐶6ан = 1 600 ∗ 670 ≈ 1 070 000 (рублей)
𝐶6раз = 1 350 ∗ 730 ≈ 980 000 (рублей)
С6 = 1 070 000 + 980 000 = 2 150 000 (рублей)
Абсолютное снижение стоимостных затрат:
∆𝐶 = 2 850 000 − 2 150 000 = 700 000 (рублей)
Коэффициента относительного снижения стоимостных затрат:
𝐾: =
,++ +++
/ 32+ +++
× 100% ≈ 25%
Индекс снижения стоимости затрат:
𝑌: =
/ 32+ +++
/ '2+ +++
≈ 1,33
85
Для удобства понимания полученные результаты сведены в таблице 3.4:
Таблица 3.4
Результаты оценки экономической эффективности
Затраты по
базовому
варианту
Трудоемкость 3 900
Стоимость
2 850 000
Затраты по
проектному
варианту
2 950
2 150 000
Абсолютное
изменение
затрат
950
700 000
Коэффициент
Индекс
изменения
изменения
затрат
затрат
24%
1.32
25%
1.33
Для расчета годового экономического эффекта и срока окупаемости
разработанного программного средства, необходимо найти капитальные
вложения при переходе от базового варианта к проектному ∆𝐾. Написание
тестов в базовом варианте не требовало никаких дополнительных капиталов от
компании, поэтому 𝐾5 = 0. Трудоемкость разработки складывалась из
нескольких компонент:
1.
Изучение методов тестирования: 8 часов
2.
Изучение единой информационной системы: 32 часа
3.
Проектирование архитектуры модуля: 32 часов
4.
Кодирование: 112 часов
5.
Тестирование и отладка: 48 часов
6.
Составление документации: 8 часов
7.
Внедрение модуля в ЕИС: 16 часов
,
𝑇 = ∑!*'
𝑡! = 8 + 32 + 32 + 112 + 48 + 8 + 16 = 256 (часов)
Учитывая то, что разработкой занимался 1 человек с заработной платой
450р/час, капитальные затраты по проектному варианту составили:
𝐾6 = 450 ∗ 1 ∗ 256 ≈ 115 000 (рублей)
Капитальные вложения при переходе от базового варианта к проектному
составили ∆𝐾:
∆𝐾 = 115 000 − 0 = 115 000 (рублей)
86
Для
расчета
годового
экономического
эффекта
используется
нормативный коэффициент эффективности капитальных вложений, который
для сферы информационных технологий равняется 0.15.
Э = 700 000 − 0.15 ∗ 115 000 ≈ 680 000(рублей)
Коэффициент эффективности 𝐸; :
𝐸; =
,++ +++
≈ 6.1
''2 +++
Срок окупаемости затрат на внедрение программного средства:
' ≈ 0.164 (года)
𝑇?> = 4.'
Срок окупаемости затрат при пересчете на дни:
дни = 0.115 ∗ 247 ≈ 41 (день)
𝑇?>
Подводя итоги, необходимо отметить, что внедрение разработанного
модуля позволяет группе компаний «Гарант» сократить трудовые затраты на
создание автотестов на 25% на счет сокращения удельного времени создания
теста, а также перераспределить структуру затрат между отделами аналитики и
разработки. Проведенный анализ показывает, что с помощью нового
инструмента предприятие может экономить около 700 тысяч рублей в год, что
составляет 25% от общих затрат на создание автотестов. Также на показатели
экономической эффективности заметное влияние оказывают капитальная
стоимость разработки, тестирования, отладки и внедрения программного
средства. Эти расходы составляет незначительную долю от общих затрат
компании и окупаются всего за 41 рабочих день, что делает применение
разработанного модуля тестирования прибыльным даже в краткосрочной
перспективе.
87
Выводы по третьей главе
В третьей главе данной выпускной квалификационной работы подведены
итоги разработки модуля генерации тестов для единой информационной
системы группы компаний «Гарант». В первом разделе произведен анализ
проведенных в процессе тестирования и отладки испытаний, результаты
которого подтвердили успешное завершение стадии разработки программного
средства. Эти же испытания использовались во второй части данной главы для
оценки показателей качества. По результатам этой оценки был сделан вывод о
том, что разработанный модуль удовлетворяет требования поставленной задачи
и может быть внедрен в производство. Последний раздел третьей главы был
отведен
расчету
экономической
эффективности
от
внедрения
нового
инструмента. В результате проведенного анализа можно утверждать, что
применение разработанного модуля тестирования позволяет заметно сократить
трудовые и стоимостные затраты компании, а благодаря низким капитальным
вложениям на разработку срок окупаемости продукта составляет около двух
месяцев.
88
ЗАКЛЮЧЕНИЕ
Данная выпускная квалификационная работа посвящена разработке
методики
проектирования
ИТ-инфраструктуры
контроля
качества
программного обеспечения.
В итоге
проведенного исследования
были
получены следующие
результаты:
1.
Приведено обоснование целесообразности автоматизации процесса
создания тестов.
Для
компаний
наподобие
«Гаранта»
качество
разрабатываемого
программного обеспечения является крайне важным фактором, определяющим
жизнеспособность компании в целом. С одной стороны, информационная
система компании должна активно и динамично развиваться, чтобы успевать за
быстро
меняющимися
бизнес-требованиями
и
оставаться
конкурентоспособной, а с другой стороны частые изменения не должны
сказываться на стабильности и корректности работы системы. Добиться
выполнения
обоих
этих
требований
возможно
только
при
грамотно
организованном контроле качества. Наиболее распространенная практика
контроля качества ПО – это всестороннее непрерывное автоматизированное
тестирование. Поэтому тестирование занимает важную роль в бизнес-процессах
компаний, и, как следствие, требует значительных расходов. Особенно это
заметно в компаниях, покрывающих большим количеством тестов кодовую
базу приложений: в «Гаранте» до 20% времени разработчиков уходит именно
на написание и поддержку тестов. Автоматизация процесса создания тестов
позволяет компании перестроить существующие процессы тестирования и
сократить свои трудовые и стоимостные затраты в этой области, что и
объясняет актуальность проведенного исследования.
Существующие
инструменты
позволяют
легко
организовать
автоматический запуск тестов при внесении изменений в кодовую базу
89
приложения, но на рынке не представлено качественных массово применимых
продуктов для автоматического создания тестов. Поэтому для решений этой
проблемы
необходимо
было
разработать
собственную
методику
проектирования ИТ-инфраструктуры контроля качества.
Разработана
2.
методика
проектирования
ИТ-инфраструктуры
контроля качества программного обеспечения.
Во
второй
главе
данной
выпускной
квалификационной
работы
рассматриваются вопросы разработки собственной методики контроля качества
ПО. В качестве ключевого шага к автоматизации создания
разработанная
методика
предполагает
создание
тестов
кодогенератора,
основывающегося на записи действий пользователя в привычном для него
интерфейсе
системы.
максимально
Такой
интегрированный
подход
во
позволяет
всю
получить
инфраструктуру
код
тестов,
тестируемой
информационной системы и имеющихся тестовых контуров, и при этом
является интуитивно понятным для пользователя, а значит, он не требует
дополнительного обучения взаимодействию с кодогенератором. Помимо этого
для достижения максимальной эффективности разработанного инструмента и
для снижения затрат на его создание методика предусматривает еще несколько
мер по организации ИТ-инфраструктуры компании, а именно: использование
тестируемой
и
расширяемой
архитектуры
проверяемого
программного
средства, организацию непрерывного автоматизированного тестирования всех
вносимых
в
кодовую
базу
изменений,
обучение
персонала
основам
тестирования, организацию процесса доставки сгенерированных тестов
в
общие тестовые контуры. Все эти меры не требуют больших усилий при
внедрении у компаний, попадающих в целевой сегмент разработанной
методики, так как для подобных компаний необходимость в частичном или
полном удовлетворении указанных требований возникает независимо от
потребности внедрить рассмотренный ранее кодогенератор.
90
3.
Реализован
модуль
кодогенерации
тестов
для
единой
информационной системы группы компаний «Гарант».
В качестве доказательства реализуемости описанной ранее методики и
для проведения основанной на практическом опыте оценке экономической
эффективности для единой информационной системы группы компаний
«Гарант» была реализована ключевая компонента рассмотренной методики –
модуль кодогенерации автотестов на основе пользовательских действий.
Приведенное во второй главе описание процесса разработки, состава и
структуры программного средства показывает, что при грамотно выстроенной
архитектуре тестируемой информационной системы расширение этой системы
новым модулем является достаточно легкой задачей. При этом сам
разработанный
модуль
так
же
является
расширяемым,
предоставляет
привычные и интуитивно понятные пользователю интерфейсы и способен
генерировать
корректный,
читаемый,
поддерживаемый
код
тестов,
повторяющих записанный тестовый сценарий.
4.
Доказана экономическая эффективность разработанного модуля
кодогенерации автотестов.
В третьей главе данной выпускной квалификационной работы проводится
анализ экономической эффективности разработанного программного средства.
Основными предпосылками для признания нового подхода экономически
эффективным является то, что создание теста через веб-интерфейс системы
происходит намного быстрее, чем ручное написание аналогичного кода, и то,
что для создания теста не требуется рабочее время высокооплачиваемых
разработчиков. С другой стороны, наличие нового модуля тестирования
неизбежно ведет к появлению дополнительных затрат на его поддержку. Но
даже несмотря на этот факт приведенные в третьей части работы расчеты
показывают, что внедрение нового модуля позволяет сократить трудовые и
стоимостные затраты на 25%, а срок окупаемости его разработки составляет 41
рабочий день, что говорит о том, что применение разработанной методики
91
контроля качества программного обеспечения экономически эффективно даже
в краткосрочной перспективе.
Подводя итоги, необходимо отметить, что разработанная методика
контроля качества может быть применена не только для информационной
системы группы компаний «Гарант», но и на любом другом предприятии,
обладающем схожей спецификой работы. Ее применение целесообразно для
компаний, занимающихся разработкой крупных информационных систем с
высокими требованиями к качеству. Внедрение разработанной методики на
таких
проектах
позволяет
оптимизировать
процессы
тестирования
программного обеспечения и значительно сократить трудовые и стоимостные
затраты компании в этой области.
Все поставленные в начале работы задачи были успешно выполнены, а
предоставленная реализация удовлетворяет всем требованиям качества.
92
СПИСОК ЛИТЕРАТУРЫ
1.
ГОСТ Р ИСО / МЭК 9126-93 "Информационная технология. Оценка
программного продукта. Характеристики качества и руководство по их
применению".
2.
ГОСТ
Р
ИСО/МЭК
12207-99
Информационная
технология.
Процессы жизненного цикла программных средств.
3.
ГОСТ 28195-89. Оценка качества программных средств. Общие
положения.
4.
ГОСТ 28806-90. Качество программных средств. Термины и
определения.
5.
Албахари Д., Албахари Б. C# 8.0. Карманный справочник.: - М.:
ООО «И. Д. Вильямс», 2020 – 341 с.
6.
Ананьева Т.Н., Исаев Г.Н., Стандартизация, сертификация и
управление качеством программного обеспечения. Учебное пособие, Изд.
«Инфра-М», 2019 – 120-140 с.
7.
Битти
Джой,
Виггерс
Карл
И.,
Разработка
требований
к
программному обеспечению, Изд. «БХВ-Петербург», 2019 – 430-435 с.
8.
Блэк
Р.
Ключевые
процессы
тестирования.
Планирование,
подготовка, проведение, совершенствование, Изд. «Лори», 2019 – 220 с.
9.
Бэнкер К. MongoDB в действии – Изд. «ДМК Пресс», 2017 – 25 с.
10.
Ковалевская
Е.
В.,
Методы
программирования:
учебно-
методический комплекс / Ковалевская Е. В., Комлева Н. В. – М.: МЭСИ,
Евразийский открытый институт, 2011. – 65 c.
11.
Ковалевская
Е.
В.
Технология
разработки
программного
обеспечения: учебное пособие / Ковалевская Е. В. -М.: МЭСИ, 2004 – 42 с.
12.
Комлева Н. В. Структуры и алгоритмы компьютерной обработки
данных / Комлева Н. В. -М.: МЭСИ, 2004. – 22 с.
13.
Лафоре Р. Объектно-ориентированное программирование в С++.
Изд. Питер, 2018 – 340 с.
93
14.
Лукин В.В., Лукин В.Н., Лукин Т.В., Технология разработки
программного обеспечения, Изд. «Вузовская книга», 2018 – 210 с.
15.
Мартин
Роберт,
Чистая
архитектура.
Искусство
разработки
программного обеспечения, Изд. Питер, 2018 – 100-150 с.
16.
Майерс Г., Баджетт Т., Сандлер К., Искусство тестирования
программ, Изд. «Вильямс», 2019 – 127 с.
17.
Ошероув Рой, Искусство автономного тестирования с примерами на
С#, 2-е изд. – Изд. «ДМК Пресс», 2016 – 29 с.
18.
Рихтер Джеффри, CLR via C#. Программирование на платформе
Microsoft .NET Framework 4.5 на языке C# / Рихтер Джеффри -4-е изд. - СПб.:
Питер, 2013. – 464 с.
19.
Фримен А. ASP.NET MVC 5 с примерами на C# 5.0 для
профессионалов, -е изд.: - М.: ООО «И. Д. Вильямс», 2018 – 25 с.
20.
Хамбл
Д.,
Фарли
Д.,
Непрерывное
развертывание
ПО.
Автоматизация процессов сборки, тестирования и внедрения новых версий
программ, Изд. «Вильямс», 2016 – 245 с.
21.
Брянский М.А., Нефёдов Ю.В. Управление жизненным циклом ИТ-
сервисов. Управление в России: проблемы и перспективы, 2019.
22.
Демаков A.B., Зеленова С.А., Зеленов C.B. Тестирование парсеров
текстов на формальных языках. Программные системы и инструмент / Демаков
A.B., Зеленова С.А., Зеленов C.B // Тематический сборник факультета ВМиК
МГУ. Вып. 2. М: ВМиК МГУ, 2001. 150-156 с.
23.
Калын М.М. Автоматизация тестирования: инструменты и подходы
по разработке автоматиечских тестов. Аллея науки, 2018.
24.
Павлековская И.В., Староверова О.В., Уринцов А.И. Влияние
научно- технического прогресса на развитие информационного общества.
Вестник экономической безопасности. 2017. № 3. С. 212-217.
25.
Платонов А.А., Староверова О.В., Обзор средств для кодогенерации
тестов / Платонов А.А., Староверова О.В // Современные инновационные
94
технологии
в
экономике,
науке,
образовании
//
Материалы
Третьей
Международной научно-практической конференции, 2020 – 228-237 с.
26.
Кодогенерация
автотестов
программного
обеспечения
[Электронный ресурс] / Научно-практический журнал «Энигма» / – Электрон.
дан.
–
Режим
доступа:
https://enigma-
sci.ru/domains_data/files/ROOT_DIRECTORY/KODOGENERACIYa%20AVTOT
(дата
ESTOV%20PROGRAMMNOGO%20OBESPEChENIYa.pdf
обращения
11.05.2020).
27.
Тестирование [Электронный ресурс] / НОУ ИНТУИТ / – Электрон.
дан. – Режим доступа: https://www.intuit.ru/studies/courses/497/353/lecture/8413
(дата обращения 21.05.2020).
28.
Что такое специализированный депозитарий. Основные понятия
[Электронный ресурс] / Пенсионный консультант / – Электрон. дан. – Режим
доступа:
http://pension-npf.ru/index.php@src=207.html/
(дата
обращения:
14.05.2020).
29.
CI/CD: принципы, внедрение, инструменты [Электронный ресурс] /
Medium / – Электрон. дан. – Режим доступа: https://medium.com/southbridge/cicd-принципы-внедрение-инструменты-f0626b9994c8
(дата
обращения:
16.05.2020).
30.
Glendenning D., Schaefer K., Cochran J., Forsyth S., Perkins B.
Professional Microsoft IIS 8 – Изд. «John Wiley & Sons Limited», 2012 – 117 с.
31.
Turley P., Muti R., Finlan C. Professional Microsoft SQL Server
2016 Reporting Services and Mobile Reports – Изд. «John Wiley & Sons Limited»,
2017 – 37 с.
32.
Automated Code Coverage Implementation and Run MSTest or NUnit
UnitTests With Parasoft Dot Test [Электронный ресурс] / C# Corner / – Электрон.
дан.
–
Режим
доступа:
https://www.c-
sharpcorner.com/UploadFile/jagan.ganta/automated-code-coverage-implementationand-run-mstest-or-nun/ (дата обращения: 16.05.2020).
95
33.
DataObjects.Net Documentation [Электронный ресурс] / Xtensive LLC
–
/
Электрон.
дан.
–
Режим
доступа:
http://help.dataobjects.net/##DataObjects.Net%20v5.0/index.html (дата обращения:
23.05.2020).
34.
Getting started with automated white box testing (and Pex)
[Электронный ресурс] / CodeProject – 1999-2018 / – Электрон. дан. – Режим
доступа:
https://www.codeproject.com/Articles/31141/Getting-started-with-
automated-white-box-testing-a (дата обращения: 15.05. 2020).
35.
NStub [Электронный ресурс] / GitHub / – Электрон. дан. – Режим
доступа: https://github.com/Jedzia/NStub (дата обращения: 18.05. 2020).
36.
Pex – dynamic analysis and test generation tool for .NET from Microsoft
[Электронный ресурс] / DevIntelligence / – Электрон. дан. – Режим доступа:
http://devintelligence.com/2008/02/pex-dynamic-analysis-and-test-generation-fornet-from-microsoft/ (дата обращения: 15.05.2020).
37.
Rational Tau Documentation [Электронный ресурс] / IBM / –
Электрон. дан. – Режим доступа: https://www.ibm.com/support/pages/rational-taudocumentation-library (дата обращения: 13.05.2020).
38.
SpecFlow+ Getting Started [Электронный ресурс] / SpecFlow / –
Электрон. дан. – Режим доступа: http://specflow.org/getting-started/ (дата
обращения: 19.05.2020).
39.
Using MSpec – a few weeks in. [Электронный ресурс] / Joel
Abrahamsson/
–
Электрон.
дан.
–
http://joelabrahamsson.com/using-mspec-a-few-weeks-in/
Режим
(дата
доступа:
обращения:
19.05.2020).
40.
What Is NUnit? [Электронный ресурс] / NUnit / – Электрон. дан. –
Режим доступа: http://nunit.org/ (дата обращения: 21.05.2020).
96
Отзывы:
Авторизуйтесь, чтобы оставить отзыв