Seminar:Тестирование

Материал из Wiki Test Lab
Перейти к: навигация, поиск

Назад    Главная
 

Источник

Дальше »


Содержание

7. Тестирование

Стандартизация качества. Методы обеспечения качества ПО. Понятие тестирования. Тестирование черного ящика. Тестирование белого ящика. Инструменты тестирования. Критерии тестирования. Виды тестирования. Работа с ошибками. Средства контроля ошибок (bug tracking systems).


Управление качеством

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


  1. 1865 год – образован комитет, который ныне называется ITU (International Telecommunication Union). Сейчас штаб-квартира в Женеве (Швейцария), а ITU является часть ООН. Его основная задача – стандартизация телекоммункационных протоколов и интерфейсов с целью поддержания и развития глобальной мировой телекоммуникационной сети. Самыми известными стандартами ITU являются:
    1. ISDN (цифровая телефонная связь, объединяющая телефонные сервисы и передачу данных),
    2. ADSL (широко известная модемная технология, позволяющая использовать телефонную линию для выхода в Интернет, не блокируя при этом обычного телефонного сервиса),
    3. OSI (модель открытого 7-уровневого сетевого протокола, на которой базируются все современные стандартные сетевые интерфейсы и протоколы; также является стандартом ISO),
    4. языки визуального проектирования телекоммуникационных систем, SDL и MSC, влившиеся позднее в UML. Многие стандарты ITU переводятся на русский язык и превращаются в российские стандарты в виде ГОСТов.
  2. 1946 год – создана организация ISO (International Organization for Standardization). Цель – содействие развитию стандартизации, а также смежных видов деятельности в мире с целью обеспечения международного обмена товарами и услугами, способствование и развитие сотрудничества в интеллектуальной, научно-технической и экономической областях. К настоящему времени создано около 17 000 стандартов в самых разных областях промышленности – продовольственные и иные товары, различное оборудование, банковские сервисы и т.д. Вот некоторые стандарты.
    1. Серия стандартов ISO 9000. Направлены на стандартизацию качества товаров и услуг. Определение качества, определение системы поддержки качества на всех жизненных фазах изделия, товара, услуги (проектирование, разработка, коммерциализация, установка и обслуживание), описание процедур по улучшению деятельности компании, промышленного производства.
    2. ISO/IEC 90003:2004 – адаптация стандартов ISO 9000 к производству ПО в русле обеспечения качества в жизненном цикле ПО.
    3. ISO 9126:2001 – определение качественного ПО и различных атрибутов, описывающих это качество. Многие стандарты ISO переводятся на русский язык и превращаются в российские стандарты в виде ГОСТов. Имеется много стандартов в области информационных технологий, а также несколько – в области программной инженерии. На соответствие стандартам ISO существует сертификация. В частности, компании сертифицируются на соответствие стандартам ISO 9000, то есть на качественный процесс разработки ПО.
  3. 1988 год, образование организации ETSI (European Telecommunications Standards Institute), штаб-квартира в г. София Антиполис (Франция). Является независимой, некоммерческой, организацией по стандартизации в телекоммуникационной промышленности (изготовители оборудования и операторы сети) в Европе. Самые известные стандарты – GSM, система профессиональной мобильной радиосвязи TETRA.

Остановимся теперь на ряде комитетов, непосредственно связанных с разработкой ПО.

  1. 1984 год – создание SEI (Software Engineering Institute) на базе университета Карнеги-Меллон в г.Питсбурге (США). Инициатор и главный спонсор – министерство обороны США. Основная задача – стандартизация в области программной инженерии, выработка критериев для сертификации надежных и зрелых компаний (что в первую очередь интересует Минобороны США для выполнения его заказов). Самые известные продукты – стандарт CMM, CMMI, разработки в области семейства программных продуктов (product lines). Эти продукты шагнули далеко за пределы военных разработок США, их использование и развитие стало международной деятельностью. Некоторые продукты SEI стандартизованы также ISO. На соответствие CMM/CMMI проводится сертификация.
  2. 1963 год – создание IEEE (Institute of Electrical and Electronics Engineers). Ведет историю с конца XIX века, в контексте промышленной стандартизацией в США. Сейчас IEEE международная некоммерческая ассоциация специалистов в области техники, мировой лидер в области разработки стандартов по радиоэлектронике и электротехнике. Штаб-квартира в США, существуют многочисленные подразделения в разных странах, включая Россию. IEEE издаёт третью часть мировой технической литературы, касающейся применения радиоэлектроники, компьютеров, систем управления, электротехники, в том числе (январь 2008) 102 реферируемых научных журнала и 36 отраслевых журналов для специалистов, проводит в год более 300 крупных конференций, принимала участие в разработке около 900 действующих стандартов.
  3. 1989 год – группа американских IT-компаний (в том числе Hewlett Packard, Sun Microsystems, Canon) организовали OMG (Object Management Group). Сейчас включает около 800-т компаний членов. Основное направление - разработка и продвижение объектно-ориентированных технологий и стандартов, в том числе для создания платформо-независимых программных приложений уровня предприятий. Известные стандарты CORBA, UML, MDA.

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


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

Качество продукта или сервиса, предназначенного потребителю, определяется в стандарте ISO 9000:2005 как степень соответствия его характеристик требованиям - обязательным или подразумеваемым.

Методы обеспечения качества ПО. Не претендуя на абсолютную полноту, перечислим различные способы контроля качества, используемые на практике при разработке ПО.


  • Наладка качественного процесса, другими словами совершенствование процесса. Для комплексного улучшения процессов в компании (подход technology push) компаниями-разработчиками ПО используются стандарты CMM/CMMI, а также по стандартам серии ISO 9000 (с последующей официальной сертификацией). Применяются и локальные стратегии, менее дорогостоящие и более направленные на решение отдельных проблем (подход organization pull).
  • Формальные методы1) – использование математических формализмов для доказательства корректности, спецификации, проверки формального соответствия, автоматической генерации и т.д.:
    • доказательство правильности работы программ,
    • проверка на моделях определенных свойств (model cheking),
    • статический анализ кода по дереву разбора программы (например, проверка корректности кода по определенным критериям – аккуратная работа с памятью, поиск мертвого кода и пр.),
    • модельно-ориентированное тестирование (model-based testing): автоматическая генерация тестов и тестового окружения по формальным спецификациям требований к системе) и т.д.
  • На практике применяются ограниченно из-за необходимости серьезной математической подготовки пользователей, сложности в освоении, большой работы по развертыванию. Эффективны для систем, имеющих повышенные требования к надежности. Также имеются случаи эффективного использования средств, основанных на этих методах, в руках высококвалифицированных специалистов.
  • Исследование и анализ динамических свойств ПО. Например, широко используется профилирование – исследование использования системой памяти, ее быстродействие и др. характеристик путем запуска и непосредственных наблюдений в виде графиков, отчетов и пр. В частности, этот подход используется при распараллеливании программ, при поиске "узких" мест. Еще пример – область, называемая "моделирование и анализ производительности" (performance modeling and analysis). Здесь моделируется нагрузочное окружение системы (число одновременных пользователей системы, сетевой трафик и пр.) и наблюдается поведение системы.
  • Обеспечение качества кода. Сюда относится целый комплекс различных мероприятий и методов. Вот некоторые, самые известные из них.
    • Разработка стандартов оформления кода в проекте и контроль за соблюдением этих стандартов. Сюда входят правила на создание идентификаторов переменных, методов и имен классов, на оформление комментариев, правила использования стандартных для проекта библиотек и т.д.
    • Регулярный рефакторинг для предотвращения образования из кода "вермишели". Существует тенденция ухудшения структуры кода при внесении в него новой функциональности, исправления ошибок и пр. Появляется избыточность, образуются неиспользуемые или слабо фрагменты, структура становится запутанной и трудной для понимания. Рефакторинг – это регулярная деятельность по переписыванию кода, но не с целью добавления новой функциональности, а для улучшения его структуры. Рефакторинг появился в контексте "гибких" методов, в данный момент активно поддерживается различными средами разработки ПО.
    • Различные варианты инспекции кода, например, техника peer code review. Последняя заключается в том, что код каждого участника проекта, выборочно, читается и обсуждается на специальных встречах (code review meetings), и делается это регулярно. Практика показывает, что в целом код улучшается.
    • Еcть еще такой подход, как "вычитка" кода, используемый, например, при разработке критических систем реального времени. Ею занимаются также разработчики, но их роль в данном проекте – вычитка, а не разработка.
  • Тестирование. Самый распространенный способ контроля качества ПО, представленный, фактически, в каждом программном проекте.

Тестирование

Тестирование – это проверка соответствия между реальным поведением программы и ее ожидаемым поведением в специально заданных, искусственных условиях. Разберем это определение по частям.

Ожидаемое поведение программы. Исходной информацией для тестирования является знание о том, как система должна себя вести, то есть требования к ней или к ее отдельной части. Самым распространенным способом тестирования является тестирование методом черного ящика, то есть когда реализация системы недоступна тестеровщикам, а тестируется только ее интерфейс. Часто это закрепляется и организацией коллектива – тестеровщики оказываются отдельными сотрудниками и в некоторых компаниях они даже принципиально не общаются с разработчиками, чтобы минимально знать реализационных деталей и максимально полно выступить в роли проверяющей инстанции. Существует тестирование методом белого ящика, когда код программ доступен тестеровщикам и используется в качестве источника информации о системе2). Его схема представлена на рис. 7.1.


07-01.jpg

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

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

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


Тесты могут быть "ручными" и автоматизированными. "Ручной" тест – это последовательность действий тестеровщика, которую он (или разработчик) может воспроизвести и ошибка произойдет. Как правило, в средствах контроля ошибками такие последовательности действий содержатся в описании ошибки. Автоматический тест – это некоторая программа, которая воздействует на систему и проверяет то или иное ее свойство. Автоматический тест, по сравнению с "ручным", можно легко воспроизводить без участия человека. Можно создавать наборы тестов и прогонять их часто, например, в режиме регрессионного тестирования. Кроме того, автоматические тесты можно генерировать по более высокоуровневым спецификациям, например, по формально описанным требованиям к системе. А, например, тесты для компиляторов можно генерировать по формальному описанию языка программирования.

Таким образом, преимущества автоматических тестов перед "ручными" очевидны. Поговорим теперь о трудностях автоматического тестирования.

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

Кроме того, немаловажной задачей инструментов тестирования является обеспечение доступа теста к системе через некоторый ее интерфейс. Доступ к системе может оказаться затруднительным, например, в силу политических обстоятельств, когда сторонними разработчиками делается подсистема некоторой стратегической системы, и доступ к этой объемлющей системе у разработчиков сильно ограничен. Или в силу аппаратных ограничений – трудно "залезть" на "железку", где работает целевой код системы.

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

Во-вторых, часто возникает проблема ресурсов для автоматического тестирования. Особенно при автоматической генерации тестов: часто есть возможность автоматически сгенерировать очень большое количество тестов, так что если их еще выполнять регулярно, в режиме непрерывной интеграции, то не хватит имеющихся системных ресурсов. При этом качество тестирования может оказаться неудовлетворительным – ошибки находятся редко или вообще не находятся. Дело в том, что количество всех возможных состояний программной системы очень велико, и тестирование не может покрыть их все. На практике, в реальных проектах, определяют критерии тестирования, которые определяют ту "планку" качества, которую необходимо достичь в этом проекте. Ведь хорошее качество стоит дорого и очевидно, что разное ПО имеет разное качество, например, система управления ядерным реактором и текстовый редактор. На практике, часто, качество ПО определяется бюджетом проекта по его разработке. Далее, в силу ограниченности ресурсов на тестирование часто целесообразно бывает определить те аспекты ПО, которые наиболее важны -как для общей работоспособности системы, так и для заказчика. Например, при тестировании Web-приложения, предоставляющего услугу по созданию объявлений о продаже недвижимости, такими критериями были:


  • правильность переходов сложного мастера – в частности, в связи с возможностью переходов назад;
  • целостность введенных пользователем данных о создаваемых объявлениях.


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


Виды тестирования. Не претендуя на полноту, выделим следующие виды тестирования.

  • Модульное тестирование - тестируется отдельный модуль, в отрыве от остальной системы. Самый распространенный случай применения – тестирования модуля самим разработчиком, проверка того, что отдельные модули, классы, методы делают действительно то, что от них ожидается. Различные среды разработки широко поддерживают средства модульного тестирования – например, популярная свободно распространяемая библиотека для Visual Studio NUnit, JUnit для Java и т.д. Созданные разработчиком модульные тесты часто включаются в пакет регрессионных тестов и таким образом, могут запускаться многократно.
  • Интеграционное тестирование – две и более компонент тестируются на совместимость. Это очень важный вид тестирования, поскольку разные компоненты могут создаваться разными людьми, в разное время, на разных технологиях. Этот вид тестирования, безусловно, должен применяться самими программистами, чтобы, как минимум, удостовериться, что все живет вместе в первом приближении. Далее тонкости интеграции могут исследовать тестеровщики. Необходимо отметить, что такого рода ошибки – "ошибки на стыках" - непросто обнаруживать и устранять. Во время разработки все компоненты все вместе не готовы, интеграция откладывается, а в конце обнаруживаются трудные ошибки (в том смысле, что их устранение требует существенной работы). Здесь выходом является ранняя интеграция системы и в дальнейшем использование практики постоянной интеграции.
  • Системное тестирование – это тестирование всей системы в целом, как правило, через ее пользовательский интерфейс. При этом тестеровщики, менеджеры и разработчики акцентируются на том, как ПО выглядит и работает в целом, удобно ли оно, удовлетворяет ли она ожиданиям заказчика. При этом могут открываться различные дефекты, такие как неудобство в использовании тех или иных функций, забытые или "скудно" понятые требования.
  • Регрессионное тестирование – тестирование системы в процессе ее разработки и сопровождение на не регресс. То есть проверяется, что изменения системы не ухудшили уже существующей функциональности. Для этого создаются пакеты регрессионных тестов, которые запускаются с определенной периодичностью – например, в пакетном режиме, связанные с процедурой постоянной интеграции.
  • Нагрузочное тестирование – тестирование системы на корректную работу с большими объемами данных. Например, проверка баз данных на корректную обработку большого (предельного) объема записей, исследование поведение серверного ПО при большом количестве клиентских соединений, эксперименты с предельным трафиком для сетевых и телекоммуникационных систем, одновременное открытие большого числа файлов, проектов и т.д.
  • Стрессовое тестирование – тестирование системы на устойчивость к непредвиденным ситуациям. Этот вид тестирования нужен далеко не для каждой системы, так как подразумевает высокую планку качества.
  • Приемочное тестирование – тестирование, выполняемое при приемке системы заказчиков. Более того, различные стандарты часто включают в себя наборы приемочных тестов. Например, существует большой пакет тестов, поддерживаемых компанией Sun Microsystems, которые обязательны для прогона для всех новых реализаций Java-машины. Считается, что только после того, как все эти тесты успешно проходят, новая реализация вправе называться Java.


Работа с ошибками

Между программистами и тестеровщиками необходим специальный интерфейс общения. Ведь ошибок находится много, их исправление требует времени, и их исправления разработчиками тестеровщики должны удостовериться, что они действительно исправлены. Кроме того, менеджерам нужна статистика по найденным и исправленным ошибкам – это хороший инструмент контроля проекта. Все это изображено на рис. 7.2. Чтобы справиться с этим потоком информации и обеспечить необходимые в работе, удобные сервисы, существует специальный класс программных средств – средства контроля ошибок (bug tracking systems).


07-02.jpg

Рис. 7.2.
Как правило, описание ошибки в системе контроля ошибок имеет следующие основные атрибуты:


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


Этот список существенно дополняется в различных программных средствах контроля ошибок, но это основные атрибуты.

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


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


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



Дальше »

Личные инструменты