Этапы тестирования тестирование в различных моделях разработки. Почему тестирование необходимо? Подготовка к тестированию

  • Тестирование веб-сервисов
  • Самый лучший способ оценить, хорошо ли мы протестировали продукт – проанализировать пропущенные дефекты. Те, с которыми столкнулись наши пользователи, внедренцы, бизнес. По ним можно многое оценить: что мы проверили недостаточно тщательно, каким областям продукта стоит уделить больше внимания, какой вообще процент пропусков и какова динамика его изменений. С этой метрикой (пожалуй, самой распространённой в тестировании) всё хорошо, но… Когда мы выпустили продукт, и узнали о пропущенных ошибках, может быть уже слишком поздно: на “хабре” появилась про нас гневная статья, конкуренты стремительно распространяют критику, клиенты потеряли к нам доверие, руководство недовольно.

    Чтобы такого не происходило, мы обычно заранее, до релиза, стараемся оценивать качество тестирования: насколько хорошо и тщательно мы проверяем продукт? Каким областям не хватает внимания, где основные риски, какой прогресс? И чтобы ответить на все эти вопросы, мы оцениваем тестовое покрытие.

    Зачем оценивать?

    Любые метрики оценки – трата времени. В это время можно тестировать, заводить баги, готовить автотесты. Какую такую магическую пользу мы получаем благодаря метрикам тестового покрытия, чтобы пожертвовать временем на тестирование?
    1. Поиск своих слабых зон. Естественно, это нам нужно? не чтобы просто погоревать, а чтобы знать, где требуются улучшения. Какие функциональные области не покрыты тестами? Что мы не проверили? Где наибольшие риски пропуска ошибок?
    2. Редко по результатам оценки покрытия мы получаем 100%. Что улучшать? Куда идти? Какой сейчас процент? Как мы его повысим какой-либо задачей? Как быстро мы дойдём до 100? Все эти вопросы приносят прозрачности и понятности нашему процессу , а ответы на них даёт оценка покрытия.
    3. Фокус внимания. Допустим, в нашем продукте около 50 различных функциональных зон. Выходит новая версия, и мы начинаем тестировать 1-ю из них, и находим там опечатки, и съехавшие на пару пикселей кнопки, и прочую мелочь… И вот время на тестирование завершено, и эта функциональность проверена детально… А остальные 50? Оценка покрытия позволяет нам приоритезировать задачи исходя из текущих реалий и сроков.

    Как оценивать?

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

    Оцениваем покрытие требований тестами

    Допустим, у вас в команде есть аналитики, и они не зря тратят своё рабочее время. По результатам их работы созданы требования в RMS (Requirements Management System) – HP QC, MS TFS, IBM Doors, Jira (с доп. плагинами) и т.д. В эту систему они вносят требования, соответствующие требованиям к требованиям (простите за тавтологию). Эти требования атомарны, трассируемы, конкретны… В общем, идеальные условия для тестирования. Что мы можем сделать в таком случае? При использовании скриптового подхода – связывать требования и тесты. Ведём в той же системе тесты, делаем связку требование-тест, и в любой момент можем посмотреть отчёт, по каким требованиям тесты есть, по каким – нет, когда эти тесты были пройдены, и с каким результатом.
    Получаем карту покрытия, все непокрытые требования покрываем, все счастливы и довольны, ошибок не пропускаем…

    Ладно, давайте вернёмся с небес на землю. Скорее всего, детальных требований у вас нет, они не атомарны, часть требований вообще утеряны, а времени документировать каждый тест, ну или хотя бы каждый второй, тоже нет. Можно отчаяться и поплакать, а можно признать, что тестирование – процесс компенсаторный, и чем хуже у нас с аналитикой и разработкой на проекте, тем больше стараться должны мы сами, и компенсировать проблемы других участников процесса. Разберём проблемы по отдельности.

    Проблема: требования не атомарны.

    Аналитики тоже иногда грешат винегретом в голове, и обычно это чревато проблемами со всем проектом. Например, вы разрабатываете текстовый редактор, и у вас могут быть в системе (в числе прочих) заведены два требования: «должно поддерживаться html-форматирование» и «при открытии файла неподдерживаемого формата, должно появляться всплывающее окно с вопросом». Сколько тестов требуется для базовой проверки 1-го требования? А для 2-го? Разница в ответах, скорее всего, примерно в сто раз!!! Мы не можем сказать, что при наличии хотя бы 1-го теста по 1-му требованию, этого достаточно – а вот про 2-е, скорее всего, вполне.

    Таким образом, наличие теста на требование нам вообще ничего не гарантирует! Что значит в таком случае наша статистика покрытия? Примерно ничего! Придётся решать!

    1. Автоматический расчёт покрытия требований тестами в таком случае можно убрать – он смысловой нагрузки всё равно не несёт.
    2. По каждому требованию, начиная с наиболее приоритетных, готовим тесты. При подготовке анализируем, какие тесты потребуются этому требованию, сколько будет достаточно? Проводим полноценный тест-анализ, а не отмахиваемся «один тест есть, ну и ладно».
    3. В зависимости от используемой системы, делаем экспорт/выгрузку тестов по требованию и… проводим тестирование этих тестов! Достаточно ли их? В идеале, конечно, такое тестирование нужно проводить с аналитиком и разработчиком этой функциональности. Распечатайте тесты, заприте коллег в переговорке, и не отпускайте, пока они не скажут «да, этих тестов достаточно» (такое бывает только при письменном согласовании, когда эти слова говорятся для отписки, даже без анализа тестов. При устном обсуждении ваши коллеги выльют ушат критики, пропущенных тестов, неправильно понятых требований и т.д. – это не всегда приятно, но для тестирования очень полезно!)
    4. После доработки тестов по требованию и согласования их полноты, в системе этому требованию можно проставить статус «покрыто тестами». Эта информация будет значить значительно больше, чем «тут есть хотя бы 1 тест».

    Конечно, такой процесс согласования требует немало ресурсов и времени, особенно поначалу, до наработки практики. Поэтому проводите по нему только высокоприоритетные требования, и новые доработки. Со временем и остальные требования подтянете, и все будут счастливы! Но… а если требований нет вообще?

    Проблема: требований нет вообще.

    Они на проекте отсутствуют, обсуждаются устно, каждый делает, что хочет/может и как он понимает. Тестируем так же. Как результат, получаем огромное количество проблем не только в тестировании и разработке, но и изначально некорректной реализации фич – хотели совсем другого! Здесь я могу посоветовать вариант «определите и задокументируйте требования сами», и даже пару раз в своей практике использовала эту стратегию, но в 99% случаев таких ресурсов в команде тестирования нет – так что пойдём значительно менее ресурсоёмким путём:
    1. Создаём фичелист (feature list). Сами! В виде google-таблички, в формате PBI в TFS – выбирайте любой, лишь бы не текстовый формат. Нам ещё статусы собирать надо будет! В этот список вносим все функциональные области продукта, и постарайтесь выбрать один общий уровень декомпозиции (вы можете выписать объекты ПО, или пользовательские сценарии, или модули, или веб-страницы, или методы API, или экранные формы…) – только не всё это сразу! ОДИН формат декомпозиции, который вам проще и нагляднее всего позволит не пропустить важное.
    2. Согласовываем ПОЛНОТУ этого списка с аналитиками, разработчиками, бизнесом, внутри своей команды… Постарайтесь сделать всё, чтобы не потерять важные части продукта! Насколько глубоко проводить анализ – решать вам. В моей практике всего несколько раз были продукты, на которые мы создали более 100 страниц в таблице, и это были продукты-гиганты. Чаще всего, 30-50 строк – достижимый результат для последующей тщательной обработки. В небольшой команде без выделенных тест-аналитиков большее число элементов фичелиста будет слишком сложным в поддержке.
    3. После этого, идём по приоритетам, и обрабатываем каждую строку фичелиста как в описанном выше разделе с требованиями. Пишем тесты, обсуждаем, согласовываем достаточность. Помечаем статусы, по какой фиче тестов хватает. Получаем и статус, и прогресс, и расширение тестов за счёт общения с командой. Все счастливы!

    Но… Что делать, если требования ведутся, но не в трассируемом формате?

    Проблема: требования не трассируемы.

    На проекте есть огромное количество документации, аналитики печатают со скоростью 400 знаков в минуту, у вас есть спецификации, ТЗ, инструкции, справки (чаще всего это происходит по просьбе заказчика), и всё это выступает в роли требований, и на проекте уже все давно запутались, где какую информацию искать?
    Повторяем предыдущий раздел, помогая всей команде навести порядок!
    1. Создаём фичелист (см. выше), но без детального описания требований.
    2. По каждой фиче собираем воедино ссылки на ТЗ, спецификации, инструкции, и прочие документы.
    3. Идём по приоритетам, готовим тесты, согласовываем их полноту. Всё то же самое, только благодаря объединению всех документов в одну табличку повышаем простоту доступа к ним, прозрачные статусы и согласованность тестов. В итоге, у нас всё супер, и все счастливы!

    Но… Ненадолго… Кажется, за прошлую неделю аналитики по обращениям заказчиков обновили 4 разные спецификации!!!

    Проблема: требования всё время меняются.

    Конечно, хорошо бы тестировать некую фиксированную систему, но наши продукты обычно живые. Что-то попросил заказчик, что-то изменилось во внешнем к нашему продукту законодательстве, а где-то аналитики нашли ошибку анализа позапрошлого года… Требования живут своей жизнью! Что же делать?
    1. Допустим, у вас уже собраны ссылки на ТЗ и спецификации в виде фичелиста-таблицы, PBI, требований, заметок в Wiki и т.д. Допустим, у вас уже есть тесты на эти требования. И вот, требование меняется! Это может означать изменение в RMS, или задачу в TMS (Task Management System), или письмо в почте. В любом случае, это ведёт к одному и тому же следствию: ваши тесты неактуальны! Или могут быть неактуальны. А значит, требуют обновления (покрытие тестами старой версии продукта как-то не очень считается, да?)
    2. В фичелисте, в RMS, в TMS (Test Management System – testrails, sitechco, etc) тесты должны быть обязательно и незамедлительно помечены как неактуальные! В HP QC или MS TFS это можно делать автоматически при обновлении требований, а в google-табличке или wiki придётся проставлять ручками. Но вы должны видеть сразу: тесты неактуальны! А значит, нас ждёт полный повторный путь: обновить, провести заново тест-анализ, переписать тесты, согласовать изменения, и только после этого пометить фичу/требование снова как «покрыто тестами».

    В этом случае мы получаем все бенефиты оценки тестового покрытия, да ещё и в динамике! Все счастливы!!! Но…
    Но вы так много внимания уделяли работе с требованиями, что теперь вам не хватает времени либо на тестирование, либо на документирование тестов. На мой взгляд (и тут есть место религиозному спору!) требования важнее тестов, и уж лучше так! Хотя бы они в порядке, и вся команда в курсе, и разработчики делают именно то, что нужно. НО НА ДОКУМЕНТИРОВАНИЕ ТЕСТОВ ВРЕМЕНИ НЕ ОСТАЁТСЯ!

    Проблема: не хватает времени документировать тесты.

    На самом деле, источником этой проблемы может быть не только нехватка времени, но и ваш вполне осознанный выбор их не документировать (не любим, избегаем эффекта пестицида, слишком часто меняется продукт и т.д.). Но как оценивать покрытие тестами в таком случае?
    1. Вам всё равно нужны требования, как полноценные требования или как фиче-лист, поэтому какой-то из вышеописанных разделов, в зависимости от работы аналитиков на проекте, будет всё равно необходим. Получили требования / фичелист?
    2. Описываем и устно согласовываем вкратце стратегию тестирования, без документирования конкретных тестов! Эта стратегия может быть указана в столбце таблицы, на странице вики или в требовании в RMS, и она должна быть опять же согласована. В рамках этой стратегии проверки будут проводиться по-разному, но вы будете знать: когда это последний раз тестировалось и по какой стратегии? А это уже, согласитесь, тоже неплохо! И все будут счастливы.

    Но… Какое ещё «но»? Какое???

    Говорите, все обойдём, и да пребудут с нами качественные продукты!

    План курса:

    1.
    Тестовая модель и Как работать со структурой
    2.
    Как придумывать проверки
    1.
    2.
    Техники тест-дизайна (Black-box)
    Обзор техник White Box
    3.
    Работа с непротиворечивостью
    4.
    Формулирование проверок
    5.
    Приоритезация
    6.
    Соблюдение процесса работы с тестовой документацией

    Аудит - Что проверяли

    1.
    Полнота покрытия (по требованиям)
    2.
    Непротиворечивость (дубликаты, противоречия требованиями)
    3.
    Структура (как делили на части и на тестовые наборы, как били на проверки)
    4.
    Содержимое проверок (формулировка, понятность всем участникам проекта)
    5.
    Оформление (описки, аккуратный внешний вид)
    6.
    Покрытие (Smoke/MAT/AT)
    7.
    Соблюдение процесса (процесс работы с тестовой документаций)

    Ошибки для всех видов документации
    Грамотность
    60
    10,4
    Покрытие всех функций
    проверками
    42
    9,4
    Разбиение на функции
    6,4
    Внешний вид
    6,2
    Единый стиль
    2,1
    Методанные документа
    2,1
    Методанные результата
    2
    55
    38
    14
    20
    17
    % от всех проектов
    % от всех ошибок

    Ошибки для Test Survey, Test Cases
    Пропуск проверок
    12,6
    Ожидаемый
    результат
    Дубликаты
    Единый стиль
    Противоречия
    Приоритет
    70
    47
    6
    38
    3,5
    25
    2,4
    25
    1,6
    1,4
    19
    % от всех проектов
    % от всех ошибок

    Тестовая модель

    - это логическая структура, описывающая функциональность
    системы и/или поведения пользователя, по которой
    генерируются тест-кейсы. Построение тестовой модели
    начинается с построения структуры, а затем утвержденная
    структура наполняется тест-кейсами/проверками.
    (с) Дмитрий Тищенко. Блог A1QA, 2014

    Покрытие проверками

    1) Актуальные хотелки клиента в спецификации\требованиях\макетах
    2) Договоренности на проекте
    3) Наличие необходимых проверок для каждой функции:
    Техники тест-дизайна:




    Equivalent Partitioning Testing
    Boundary Values Testing
    Pairwise testing
    State transition Testing

    Equivalence Partitioning

    ТЕХНИКА ЭКВИВАЛЕНТНЫХ КЛАССОВ

    *для простоты примера возьмем неизменную цену

    1) Разбить на классы входные параметры

    Параметр
    Класс 1
    Класс 2
    Версия продукта
    Standard
    Premium
    <0
    0 <= количество < 100
    Количество
    Класс 3
    >= 100
    *Голос разума – для «Версии продукта» необходимо протестировать ВСЕ значения из класса валидных значений.
    Н-р, для поля Оплаты (значения: картой, наличными, переводом) логично протестировать ВСЕ варианты отдельно

    2) 1 класс == 1 проверка

    Версия продукта
    Case 1
    Standard
    Case 2
    Premium
    Кол-во

    2) 1 класс == 1 проверка

    Версия продукта
    Case 1
    Standard
    Case 2
    Premium
    Кол-во
    Case 3
    -1
    Case 4
    16
    Case 5
    125

    3) Негативная проверка только для 1го класса в кейсе

    Версия продукта
    Кол-во
    Результат
    Case 1
    Standard
    50
    Positive
    Case 2
    Premium
    50
    Positive
    Case 3
    Standard
    -1
    Negative
    Case 4
    Standard
    16
    Positive
    Case 5
    Standard
    125
    Negative

    4) Пересмотреть позитивные проверки

    Версия продукта
    Кол-во
    Результат
    Case 1
    Standard
    50
    Positive
    Case 2
    Premium
    50
    Positive
    Case 3
    Standard
    -1
    Negative
    Case 4
    Standard
    16
    Positive
    Case 5
    Standard
    125
    Negative

    5) Итого

    Версия продукта
    Кол-во
    Результат
    Case 1
    Premium
    50
    Positive
    Case 2
    Standard
    -1
    Negative
    Case 3
    Standard
    16
    Positive
    Case 4
    Premium
    125
    Negative

    Еще классы …

    Параметр
    Класс 1
    Класс 2
    Версия продукта
    Standard
    Premium
    <0
    0 <= Кол-во < 100
    Дробные
    Целые
    Числа
    Не числа
    Кол-во
    Класс 3
    > 100
    Пустое

    Версия продукта
    Кол-во
    Результат
    Case 1
    Standard
    50
    Positive
    Case 2
    Premium
    10
    Positive
    Case 3
    Premium
    -1
    Negative
    Case 4
    Standard
    16
    Positive
    Case 5
    Premium
    150
    Negative
    Case 6
    Premium
    19,45
    Negative
    Case 7
    Premium
    %Number!
    Negative
    Case 8
    Standard
    -
    Negative

    Версия продукта
    Кол-во
    Результат
    Case 1
    Standard
    50
    Positive
    Case 2
    Premium
    10
    Positive
    Case 3
    Premium
    -1
    Negative
    Case 4
    Standard
    16
    Positive
    Case 5
    Premium
    150
    Negative
    Case 6
    Premium
    19.45
    Negative
    Case 7
    Premium
    %Number!
    Negative
    Case 8
    Standard
    -
    Negative

    ~30% позитивных кейсов

    Версия продукта
    Кол-во
    Результат
    Case 1
    Standard
    50
    Positive
    Case 2
    Premium
    10
    Positive
    Case 3
    Premium
    -1
    Negative
    Case 4
    Premium
    150
    Negative
    Case 5
    Premium
    19.45
    Negative
    Case 6
    Premium
    %Number!
    Negative
    Case 7
    Standard
    -
    Negative

    Функция
    Входной параметр
    Получатель
    Send
    Тема
    Тело
    Файлы
    Attach
    Файлы
    Форматирование Текст
    Delete
    Void
    Класс 1
    Класс 2
    Существующий адрес Несуществующий адрес
    Размер 0
    0 < Размер <= Limit
    Содержит символы @
    ._-+
    Символы кроме @ . _ - +
    Формат
    Не формат
    Размер 0
    0 < Размер <= Limit
    Содержит символы
    кроме “∞₽₾₾©¥£µ®” Символы ∞₽₾₾©¥£µ®
    Размер 0
    0 < Размер <= Limit
    Форматирование
    Без форматирования
    Нет
    Один
    Размер 0
    0 < Размер <= Limit
    Supported
    Unsupported
    Текст не выбран\не
    выбирать
    Текст
    форматирование
    Нажать
    Класс 3
    Размер > Limit
    Размер > Limit
    Размер > Limit
    Много
    Размер > Limit
    Форматированн
    ый текст


    1
    2
    Получатель
    Существует
    0 < Размер <= Limit
    Тема
    0 < Размер <= Limit
    Содержит символы
    кроме “∞₽₾₾©¥£µ®”
    3 Содержит символы @ . _ 0 < Размер <= Limit
    -+
    4 Формат
    0 < Размер <= Limit
    5 Несуществующий адрес 0 < Размер <= Limit
    6 Размер 0
    Содержит символы
    кроме “∞₽₾₾©¥£µ®”
    7 Размер > Limit
    Содержит символы
    кроме “∞₽₾₾©¥£µ®”
    8 Не формат
    0 < Размер <= Limit
    9 0 < Размер <= Limit
    Размер 0
    10 0 < Размер <= Limit
    Размер > Limit
    11 0 < Размер <= Limit
    Содержит символы
    “∞₽₾₾©¥£µ®”
    12 Существует
    0 < Размер <= Limit
    0 < Размер <= Limit
    Formatting
    Нет
    Один
    Ожидаемый
    результат
    Отправлено
    Отправлено
    0 < Размер <= Limit
    Три
    Отправлено
    0 < Размер <= Limit
    0 < Размер <= Limit
    Formatting
    Три
    Нет
    Один
    Отправлено
    Не доставлено
    Не отправлено
    Formatting
    Один
    Не отправлено
    0 < Размер <= Limit
    Formatting
    0 < Размер <= Limit
    0 < Размер <= Limit
    Нет
    Один
    Три
    Три
    Не отправлено
    Не отправлено
    Не отправлено
    Не отправлено
    Размер > Limit
    Нет
    Не отправлено
    Тело
    Файлы

    #
    Входные
    Результат
    Void
    Отмена удаления
    Текст не выбран\не выбирать
    форматирование
    Письмо удалено
    Письмо не удалено
    Текст
    Применено форматирование
    4
    Форматированный текст
    Применено новое форматирование
    5
    Размер и формат из допустимых
    значений
    Файл прикреплен
    Не указывать файл
    Файл не прикреплен
    Указать файл недопустимого размера
    (min < или > max)
    Файл не прикреплен
    Указать неподдерживаемый файл
    Файл не прикреплен
    1
    Функция
    Удаление
    2
    3
    6
    7
    8
    Форматирование
    Прикрепление
    файла
    Система не применяет форматирование

    Boundary values

    ТЕХНИКА ГРАНИЧНЫХ ЗНАЧЕНИЙ

    Задача: Создать тест-кейсы для Evacuation Plan

    Задача: Создать тест-кейсы для Evacuation Plan

    0
    Базовый Тест
    Для успокоения нервов
    Негативный Тест
    99

    99
    0
    0
    99



    Находим все пары (см. график)
    В математике это Декартово произведение:
    Evacuation_Plan х Risk_Assesment = {(a,b) | a ∈ Evacuation_Plan, b ∈ Risk_Assesment}
    Evacuation_Plan х Risk_Assesment =
    { (-1,-1),
    (-1,0), (-1,1),
    (-1,50),
    (-1,98), (-1,99), (-1,100),
    (0,-1),
    (0,0),
    (0,1),
    (0,50),
    (0,98),
    (0,99),
    (0,100),
    (1,-1),
    (1,0),
    (1,1),
    (1,50),
    (1,98),
    (1,99),
    (1,100),
    (50,-1), (50,0), (50,1), (50,50),
    (50,98), (50,99), (50,100),
    (98,-1), (98,0), (98,1), (98,50),
    (98,98), (98,99), (98,100),
    (99,-1), (99,0), (99,1),
    (99,50), (99,98), (99,99),
    (99,100),
    (100,-1), (100,0), (100,1), (100,50), (100,98), (100,99), (100,100),
    }
    7x7 = 49 проверок

    Evacuation_Plan = {-1, 0, 1, 50, 98, 99, 100}
    Risk_Assesment = {-1, 0, 1, 50, 98, 99, 100}
    EP_Type = {Standard, Premium}
    RA_Type = {Standard, Premium}
    Количество кейсов = 7 * 7 * 2 * 2 = 196

    Pairwise Testing

    ТЕХНИКА ТЕСТИРОВАНИЯ ВСЕХ ПАР

    Задача

    Хранение данных (5): PostgreSQL, Oracle, MySQL, JSON, XML
    Операционная система (4): Windows 7, 8, 10, OS X 10
    RAM (3): 1 024 MB, 4 096 MB, 8 192 MB
    HDD (2): SCSI, IDE
    Полный перебор = 5 * 4 * 3 * 2 = 120 вариантов

    Идеи

    1. Протестировать пары значений, а не полные переборы
    2. Эмпирическое доказательство эффективности
    3. All Pairs/Orthogonal massive варианты техники

    Работа с ортогональными
    массивами

    1
    2
    3
    4
    5
    Data
    PostgreSQL
    Oracle
    MySQL
    JSON
    XML
    OS
    Windows 7
    Windows 8
    Windows 10
    OS X 10
    RAM
    1 024 MB
    4 096 MB
    8 192 MB
    HDD
    SCSI
    IDE

    Работа с ортогональными
    массивами
    1. Понять какие и сколько входных параметров:
    1
    2
    3
    4
    5
    Data
    PostgreSQL
    Oracle
    MySQL
    JSON
    XML
    OS
    Windows 7
    Windows 8
    Windows 10
    OS X 10
    RAM
    1 024 MB
    4 096 MB
    8 192 MB
    HDD
    SCSI
    IDE

    Работа с ортогональными
    массивами
    1. Понять какие и сколько входных параметров:
    Хранение данных
    OS
    RAM
    HDD
    Column 5
    Column 6
    1
    1
    1
    1
    1
    1
    1
    2
    2
    2
    2
    2
    1
    3
    3
    3
    3
    3
    1
    4
    4
    4
    4
    4
    1
    5
    5
    5
    5
    5
    2
    1
    2
    3
    4
    5
    2
    2
    3
    4
    5
    1
    1
    2
    3
    4
    5
    2
    3
    4
    5
    1
    2
    Data
    PostgreSQL
    Oracle
    MySQL
    JSON
    XML
    2
    4
    5
    1
    2
    3
    OS
    Windows 7
    Windows 8
    Windows 10
    OS X 10
    2
    5
    1
    2
    3
    4
    3
    1
    3
    5
    2
    4
    RAM
    1 024 MB
    4 096 MB
    8 192 MB
    3
    2
    4
    1
    3
    5
    HDD
    SCSI
    IDE
    3
    3
    5
    2
    4
    1
    3
    4
    1
    3
    5
    2
    3
    5
    2
    4
    1
    3
    4
    1
    4
    2
    5
    3
    4
    2
    5
    3
    1
    4
    4
    3
    1
    4
    2
    5
    4
    4
    2
    5
    3
    1
    4
    5
    3
    1
    4
    2
    5
    1
    5
    4
    3
    2
    5
    2
    1
    5
    4
    3
    5
    3
    2
    1
    5
    4
    5
    4
    3
    2
    1
    5
    5
    5
    4
    3
    2
    1
    2. Выбираем подходящий ортогональный массив – L25(56 ^6)

    Работа с ортогональными
    массивами
    1. Понять какие и сколько входных параметров:
    1
    2
    3
    4
    5
    Data
    PostgreSQL
    Oracle
    MySQL
    JSON
    XML
    OS
    Windows 7
    Windows 8
    Windows 10
    OS X 10
    RAM
    1 024 MB
    4 096 MB
    8 192 MB
    HDD
    SCSI
    IDE
    2. Выбираем подходящий ортогональный массив –
    3. Строим ортогональный массив
    4. Удаляем ненужные КОЛОНКИ
    L25(56 ^6)
    Хранение данных
    OS
    RAM
    HDD
    1
    1
    1
    1
    1
    2
    2
    2
    1
    3
    3
    3
    1
    4
    4
    4
    1
    5
    5
    5
    2
    1
    2
    3
    2
    2
    3
    4
    2
    3
    4
    5
    2
    4
    5
    1
    2
    5
    1
    2
    3
    1
    3
    5
    3
    2
    4
    1
    3
    3
    5
    2
    3
    4
    1
    3
    3
    5
    2
    4
    4
    1
    4
    2
    4
    2
    5
    3
    4
    3
    1
    4
    4
    4
    2
    5
    4
    5
    3
    1
    5
    1
    5
    4
    5
    2
    1
    5
    5
    3
    2
    1
    5
    4
    3
    2
    5
    5
    4
    3

    Работа с ортогональными
    массивами
    1. Понять какие и сколько входных параметров:
    Хранение данных
    OS
    RAM
    HDD
    1
    PostgreSQL
    Windows 7
    1 024 MB
    SCSI
    2
    PostgreSQL
    Windows 8
    4 096 MB
    IDE
    3
    PostgreSQL
    Windows 10
    8 192 MB
    SCSI
    4
    PostgreSQL
    OS X 10
    1 024 MB
    SCSI
    5
    PostgreSQL
    Windows 10
    1 024 MB
    SCSI
    6
    Oracle
    Windows 7
    4 096 MB
    SCSI
    7
    Oracle
    Windows 8
    8 192 MB
    SCSI
    1
    2
    3
    4
    5
    8
    Oracle
    Windows 10
    1 024 MB
    SCSI
    Data
    PostgreSQL
    Oracle
    MySQL
    JSON
    XML
    9
    Oracle
    OS X 10
    1 024 MB
    SCSI
    OS
    Windows 7
    Windows 8
    Windows 10
    OS X 10
    10
    Oracle
    Windows 10
    1 024 MB
    IDE
    11
    MySQL
    Windows 7
    8 192 MB
    SCSI
    RAM
    1 024 MB
    4 096 MB
    8 192 MB
    12
    MySQL
    Windows 8
    1 024 MB
    SCSI
    HDD
    SCSI
    IDE
    13
    MySQL
    Windows 10
    4 096 MB
    IDE
    14
    MySQL
    OS X 10
    1 024 MB
    SCSI
    15
    MySQL
    OS X 10
    4 096 MB
    SCSI
    16
    JSON
    Windows 7
    4 096 MB
    IDE
    17
    JSON
    Windows 8
    4 096 MB
    SCSI
    18
    JSON
    Windows 10
    1 024 MB
    SCSI
    19
    JSON
    OS X 10
    4 096 MB
    SCSI
    20
    JSON
    OS X 10
    8 192 MB
    SCSI
    21
    XML
    Windows 7
    4 096 MB
    SCSI
    22
    XML
    Windows 8
    1 024 MB
    SCSI
    23
    XML
    Windows 10
    4 096 MB
    SCSI
    24
    XML
    OS X 10
    8 192 MB
    IDE
    25
    XML
    Windows 10
    4 096 MB
    SCSI
    2. Выбираем подходящий ортогональный массив – L25(56 ^6)
    3. Строим ортогональный массив
    4. Удаляем ненужные КОЛОНКИ
    5. Проставляем значения входных параметров
    6. Заполняем пустые места + проверяем пары на релевантность

    PICT
    Хранение данных
    OS
    RAM
    HDD
    1
    JSON
    OSX_10
    4096MB
    SCSI
    2
    Oracle
    Windows7
    1024MB
    IDE
    3
    MySQL
    Windows10
    8192MB
    IDE
    4
    Oracle
    Windows8
    8192MB
    SCSI
    5
    JSON
    Windows8
    1024MB
    IDE
    6
    JSON
    Windows7
    8192MB
    SCSI
    7
    Oracle
    Windows10
    1024MB
    SCSI
    8
    XML
    Windows7
    4096MB
    IDE
    9
    MySQL
    OSX_10
    1024MB
    SCSI
    10
    JSON
    Windows10
    4096MB
    SCSI
    11
    XML
    Windows10
    8192MB
    SCSI
    12
    PostgreSQL
    Windows8
    4096MB
    SCSI
    13
    MySQL
    Windows7
    4096MB
    SCSI
    14
    XML
    Windows8
    1024MB
    IDE
    15
    PostgreSQL
    Windows7
    1024MB
    IDE
    16
    XML
    OSX_10
    8192MB
    IDE
    17
    PostgreSQL
    Windows10
    8192MB
    SCSI
    18
    MySQL
    Windows8
    4096MB
    IDE
    19
    PostgreSQL
    OSX_10
    8192MB
    IDE
    20
    Oracle
    OSX_10
    4096MB
    SCSI

    105*16*2*4*5*2 = 134 400

    1
    2
    3
    4
    5

    105
    Subject
    Arabic
    Art History
    Biology
    Business
    Studies
    Chemistry

    EAL
    School level (16)
    Elementary
    Middle
    High
    School Wide
    High/Middle

    Likelihood
    Definite
    Tentative
    Employment
    Type
    Full
    Part
    Substitute
    Temporary
    Contract length
    1
    2
    3
    4
    Cover letter

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

    Цель

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

    Проверку взаимодействий компонентов

    Проверку правильности интеграции компонентов

    Проверку точности реализации всех требований

    Выявление дефектов и принятие мер, необходимых для их устранения до
    развертывания программного обеспечения

    Качество

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

    Глава 12. Г67

    ответствует определенным требованиям или превышает их (оценка производится согласно мерам и критериям приемлемости).

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

    Кто отвечает за качество продукта

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

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

    Тестирование в итеративном жизненном цикле

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

    Классификация тестов

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

    Тестируемый параметр качества - какой параметр качества проходит испытания

    Этап тестирования- момент жизненного цикла, в котором выполняется
    тестирование

    Тип теста - конкретная задача отдельного теста, как правило, связанная с одним
    параметром качества

    Параметры качества

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

    Надежность

    Программное обеспечение "сопротивляется" появлению ошибок в процессе выполнения: отсутствуют аварийные отказы, зависания, утечка памяти и т. п.

    Функциональные возможности

    Программное обеспечение реализует требуемые прецеденты или имеет ожидаемое поведение.

    Я Производительность

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

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

    Этапы тестирования

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

    Блочное тестирование

    Тестируются минимальные элементы системы. Время тестирования, как правило, совпадает со временем реализации элементов.

    Интегральное тестирование

    Тестируются интегральные блоки (или компоненты, или подсистемы).

    Системное тестирование

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

    Приемочное тестирование

    Конечными пользователями (или представителями конечных пользователей) тестируется завершенное приложение (или система). Цель тестирования: определить готовность к развертыванию продукта.

    Следует помнить, что в разное время жизненного цикла этапы тестирования проходят с различными акцентами. Ранний концептуальный прототип, используемый в фазе исследования для оценки жизнеспособности видения продукта, будет подвергаться различным приемочным испытаниям. Архитектурный прототип, разрабатываемый в фазе уточнения плана, будет подвержен интегральным и системным испытаниям, направленным на проверку архитектурной целостности и производительности ключевых архитектурных элементов, несмотря на то что в это время большая часть кода системы имеет форму программ-суррогатов. Этапы тестирования - это не предопределенные "фазы", последовательно выполняемые ближе к концу проекта; наоборот, при итеративном жизненном цикле тестирование начинается рано и выполняется часто.

    Типы тестов

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

    Аттестационный тест

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

    Конфигурационный тест

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

    Функциональные испытания

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

    Установочные испытания

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

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

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

    Испытание под нагрузкой

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

    Эксплуатационные испытания

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

    Испытания в жестком режиме

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

    Регрессивное тестирование

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

    Максимально раннего выявления дефектов;

    Проверки того, что изменения кода не приводят к новым дефектам или не
    восстанавливают старые.

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

    Модель тестирования

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

    Рассмотрим подробнее составляющие модели тестирования.

    Контрольные задачи

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

    Методики испытания

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

    Сценарии испытаний

    Инструкции, автоматизирующие реализацию части или всей методики испытания (или методик испытания).

    Классы и компоненты испытаний

    Классы и компоненты, реализующие проекты тестов, в том числе драйверы и программы-суррогаты.

    Взаимодействия тестов

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

    Примечания

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

    Основные элементы модели тестирования и их взаимоотношения показаны на рис. 12.1.

    Рис. 12.1. Контрольные задачи, методики испытаний и сценарии испытаний для банкомата

    Исполнители и артефакты

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

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

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

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

    Исполнители и артефакты технологического процесса тестирования представлены на рис. 12.2. Давайте рассмотрим ключевые артефакты этого процесса.

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

    Модель тестирования описывалась ранее.

    Результаты тестирования и данные, собранные в процессе выполнения тестов.

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

    Дефекты, полученные в результате "проваленных тестов" являются одним из
    типов запросов на внесение изменений (см. главу 13).

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

    Пакеты и классы тестов

    Подсистемы и компоненты тестов

    Заключительная оценка тестов используется как часть оценки итерации проекта и периодической оценки состояния (см. главу 7, "Технологический процесс управления проектом").

    Технологический процесс

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

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

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

    Разработка теста

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

    Реализация теста

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

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

    Выполнение тестов на этапе интегрального тестирования

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

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

    Выполнение тестов на этапе системного тестирования

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

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

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

    Оценка тестирования

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

    Инструментальная поддержка

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

    Корпорация Rational Software предлагает следующие инструментальные средства, поддерживающие автоматизацию тестов и процесс тестирования в целом.

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

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

    LogViewer фиксирует результаты тестирования и представляет отчет для оценки выполнения теста.

    TestManager поддерживает планирование, проектирование и оценку тестов, позволяет определить тестовое покрытие и генерирует отчеты о состоянии тестов.

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

    PerformanceStudio выполняет сценарии тестирования виртуального пользова
    теля, используя для этого эксплуатационные испытания и некоторые функци
    ональные испытания.

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

    Rational Purify для локализации труднообнаруживаемых ошибок времени выполнения.

    Rational PureCoverage* для определения участков кода, не прошедших тестирование, и выполнения анализа покрытия кода.

    Rational Quantify* для выявления фрагментов кода, ограничивающих производительность.

    Кроме того, для большинства из названных средств Rational Unified Process предлагает инструментальные наставники.

    Резюме

    Тестирование позволяет оценить качество производимого продукта.

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

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

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

    Аннотация: Основные понятия тестирования. Фазы и этапы тестирования. Типы тестов. Разработка, управляемая тестами (Test Driven Development)

    Введение

    Тестирование является одним из наиболее устоявшихся способов обеспечения качества разработки программного обеспечения.

    С технической точки зрения тестирование заключается в выполнении приложения на некотором множестве исходных данных и сверке получаемых результатов с заранее известными (эталонными) с целью установить соответствие различных свойств и характеристик приложения заказанным свойствам. Как одна из основных фаз процесса разработки программного продукта ( Дизайн приложения - Разработка кода - Тестирование), тестирование характеризуется достаточно большим вкладом в суммарную трудоемкость разработки продукта. Широко известна оценка распределения трудоемкости между фазами создания программного продукта: 40%-20%-40%.

    С точки зрения математики тестирование можно рассматривать как интерпретацию некоторой формулы и проверки ее истинности на некоторых множествах. Действительно, программу можно представить в виде формулы f = f1* f2* f3*... * fn , где f1 , f 2 , ... fn - операторы языка программирования, а их суперпозиция - программа .

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

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

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

    Динамическое тестирование (собственно тестирование) осуществляет выявление ошибок только на выполняющейся программе с помощью специальных инструментов автоматизации тестирования - Testbed или Testbench.

    Основы тестирования

    Классы критериев тестирования

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

    • Условие критерия тестирования команд (критерий С0) - набор тестов в совокупности должен обеспечить прохождение каждой команды не менее одного раза.
    • Условие критерия тестирования ветвей (критерий С1) - набор тестов в совокупности должен обеспечить прохождение каждой ветви не менее одного раза.
    • Условие критерия тестирования путей (критерий С2) - набор тестов в совокупности должен обеспечить прохождение каждого пути не менее 1 раз.

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

    Выделяют следующие частные виды функциональных критериев :

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

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

    Мутационные критерии ориентированы на проверку свойств программного изделия на основе подхода Монте-Карло.

    Метод мутационного тестирования состоит в том, что в разрабатываемую программу P вносят мутации (мелкие ошибки), т.е. искусственно создают программы- мутанты P1, P2... . Затем программа P и ее мутанты тестируются на одном и том же наборе тестов (X, Y).

    Если на наборе (X, Y) подтверждается правильность программы P и, кроме того, выявляются все внесенные в программы- мутанты ошибки, то набор тестов (X, Y) соответствует мутационному критерию, а тестируемая программа объявляется правильной. Если некоторые мутанты не выявили всех мутаций, то надо расширять набор тестов (X, Y) и продолжать тестирование.

    Фазы тестирования

    При тестировании как правило выделяют три фазы: модульное, интеграционное и системное тестирование.

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

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

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

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

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

    Этапы тестирования

    Каждая фаза тестирования включает в себя следующие этапы:

    1. Определение целей (требований к тестированию), включающее следующую конкретизацию: какие части системы будут тестироваться, какие аспекты их работы будут выбраны для проверки, каково желаемое качество и т. п.
    2. Планирование : создание графика (расписания) разработки тестов для каждой тестируемой подсистемы; оценка необходимых человеческих, программных и аппаратных ресурсов; разработка расписания тестовых циклов . Важно отметить, что расписание тестирования обязательно должно быть согласовано с расписанием разработки создаваемой системы.
    3. Разработка тестов (тестового кода для тестируемой системы).
    4. Выполнение тестов : реализация тестовых циклов .
    5. Анализ результатов .

    Тестовый цикл - это цикл исполнения тестов, включающий фазы 4 и 5 тестового процесса. Тестовый цикл заключается в прогоне разработанных тестов на некотором однозначно определяемом срезе системы (состоянии кода разрабатываемой системы). Обычно такой срез системы называют build .

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

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

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

    Вся информация об обнаруженных в процессе тестирования дефектах (тип, условия обнаружения , причина, условия исправления, время, затраченное на исправление) заносятся в базу дефектов.

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

    Типы тестов

    В тестовом плане определяются и документируются различные типы тестов .

    Типы тестирования по виду подсистемы или продукта таковы:

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

    Типы тестирования по способу выбора входных значений:

    1. Функциональное тестирование, при котором проверяется:
      • покрытие функциональных требований;
      • покрытие сценариев использования.
    2. Стрессовое тестирование, при котором проверяются экстремальные режимы использования продукта.
    3. Тестирование граничных значений.
    4. Тестирование производительности.
    5. Тестирование на соответствие стандартам.
    6. Тестирование совместимости с другими программно-аппаратными комплексами.
    7. Тестирование работы с окружением.
    8. Тестирование работы на конкретной платформе.

    Test Driven Development

    Рассмотрим подход к тестированию, несколько отличающийся от приведенного выше. Разработка через тестирование ( Test Driven Development - TDD) - процесс разработки программного обеспечения, который предусматривает написание и автоматизацию модульных тестов еще до момента написания соответствующих классов или модулей. Это гарантирует, что все обязанности любого элемента программного обеспечения определяются еще до того, как они будут закодированы.

    TDD задает следующий порядок этапов программирования:

    • Красный - напишите небольшой тест, который не работает, а возможно, даже не компилируется.
    • Зеленый - заставьте тест работать как можно быстрее, при этом не думайте о правильности дизайна и чистоте кода. Напишите ровно столько кода, чтобы тест сработал.
    • Рефакторинг - удалите из написанного вами кода любое дублирование.
    • Освоив TDD, разработчики обнаруживают, что они пишут значительно больше тестов, чем раньше, и двигаются вперед маленькими шагами, которые раньше могли показаться бессмысленными.

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

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

    Итоги

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

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

    Кроме того, продолжаются исследования в области тестов, ориентированных на конкретную модель разработки (водопадную, спиральную) или на конкретную парадигму программирования. Например, для тестирования компонентно-ориентированных систем предлагается тестирование при помощи агентов. Для тестирования активных Java-апплетов предлагают использовать нейросети. Для тестирования агентов, существующих в web (роботы, пауки), предлагают использовать системы, основанные на знаниях.

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

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

    • "Парадокс пестицида", описанный Борисом Бейзером в 1990-м году. Заключается он в том, что тесты все менее и менее эффективны в отлове багов, так как баги, для обнаружения которых эти тесты написаны, уже найдены и починены. Если же этого не происходит, то возникают серьезные вопросы к написанному коду и к рабочим процессам
    • Тесты статичны и их сложно менять, в то время как тестируемая система имеет свойство постоянно эволюционировать, обрастать новым функционалом и менять поведение старого. И тесты нужно менять каждый раз, когда функционал изменяет внешний вид программы или ее поведение. И с ростом сложности обновления тестов оправдывать чудовищные издержки на поддержку тестов становиться все сложнее.

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

    Что такое модель?

    Модель - это описание тестируемой системы. Формальная спецификация вполне сойдет. Модель должна быть сильно проще описываемой системы и как-то помогать нам понимать и предсказывать поведение тестируемого продукта.

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

    Если вкратце, то можно описать так: тестируемое ПО начинает работу в каком-то состоянии ("главная страничка открыта"), принимает какой-то пользовательский ввод ("посмотреть фоточки котяток") и, в зависимости от этого ввода, переходит в новое состояние ("альбом с фоточками котяток появился"). Мы используем модели все время чтобы понять поведение того куска софта с которым работаем ("Хм... если я нахожусь тут и делаю вот это , то я окажусь вон там "). Да в общем-то все тестирование можно рассматривать как перемещение тестировщика через различные состояния системы и проверку того, что эти перемещения происходят корректно (что значит "корректно" это отдельная тема, так что пока мы ее пропустим).

    Что такое Model-Based Testing?

    Это довольно немолодая идея использовать формально описанные модели для того, чтобы сделать тестирование ПО более дешевым и простым занятием. Само Model-Based Testing это такая "продвинутая" техника тестирования через "черный ящик". У нее есть ряд бонусов перед традиционными методами:

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

    И самое важное - формально описанные модели в комбинации с зачатками теории графов помогает легко и непринужденно генерировать сотни тестов.

    Зоркий поклонник Agile может воскликнуть "эй! у нас есть BDD и оно покрывает первые три пункта и еще это спецификация!". Я же отвечу "нихрена подобного - ваши примеры станут нормальной спецификацией только тогда, когда короля Шака Зулу можно будет считать спецификацией на все человечество".

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

    Короткий ликбез по теории графов

    Теория графов зародилась в 1736-м году в стареньком Прусском городе Кёнингсберге. Город стоял на двух берегах реки и попутно занимал еще и пару островов посреди этой самой реки. Жители этого города от безделья пытались придумать как посетить все семь мостов не проходя ни по одному дважды. Решали на практике, во время прогулок, и в теории, во время кухонных посиделок. Долгое время никто не мог доказать или опровергнуть возможность существования данного маршрута, пока не пришел зануда Эйлер и не испортил горожанам праздник.

    Эйлер придумал изобразить каждый кусок суши как вершину графа, а мосты - ребрами графа.

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

    С тех пор граф, в котором все вершины имеют четное количество ребер называется "Эйлеровым Графом". А полный обход этого графа носит гордое имя "Эйлерова пути".

    И после этого жителям Кёнингсберга пришлось найти себе другое развлечение. Только один китайский математик Мэй-Ку Куан все морочил себе голову этими мостами. А беспокоил его следующий вопрос:

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

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

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

    И в честь Куана эту задачку назвали "задачей китайского почтальона".

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

    Тут мы введем еще один термин - орграф. Или ориентированный граф. Это такой граф, ребра которого можно пересекать только в указанном направлении. Направленные же ребра так же называются "дугами".

    И если в случае Эйлерова Пути или Проблемы Китайского Почтальона мы оперировали дугами касающимися вершин, то тут приходится принимать во внимание еще и направление движения. И доля "Эйлеризации" такого графа нам требуется чтобы количество входящих в вершину дуг равнялось количеству исходящих. И считая каждую входящую дугу как "+1", а исходящую как "-1" мы можем вычислять "полярность" каждой вершины орграфа. Например вершина в двумя входящими и одной исходящей дугой имеет полярность "2 - 1 = 1".

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

    Причем тут тестирование?

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

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

    С другой стороны, исполнение всех возможных действий это хорошо, но даже самый недалекий тест-менеджер понимает, что это банальное "покрытие состояний" в терминах тестирования сырого кода. Но у множителей есть одно неприятное свойство - у них, как правило, очень много "следующих" состояний у каждой вершины. Что же нам делать, если мы хотим проверить все возможные комбинации действий? Решения задач вроде задачи Китайского Почтальона не подходят, поскольку они гарантируют только посещение каждой дуги, но никак не посещение всех возможных комбинаций дуг.

    Такой подход как раз активно использовался для тестирования конечных автоматов. К тому же это требование естественно вытекает из комбинаторной техники дизайна тестов под названием "все пары".

    Решение предложил некий де Брюийн. Алгоритм выглядит примерно так:

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

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

    Про то, зачем сюда добавляют Цепи Маркова, и как обычно решается распараллеливание таких тестов я напишу позже. А пока подведем краткие итоги.

    Итого

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

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

    И, поскольку Теория Графов позволяет нам работать непосредственно с моделью:

    • Новые обходы можно автоматически генерировать при изменении модели
    • Наши тесты могут легко и непринужденно меняться в рамках одной и той же модели
    • Различные алгоритмы обхода могут удовлетворять различным потребностям тестирования
    • Полученные алгоритмы обхода легко можно переиспользовать в совершенно новой среде


    
    Top