Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Тестирование программного обеспечения

Содержание:

Введение

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

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

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

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

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

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

Сформулируем основополагающий вывод:

 Если ваша цель - показать отсутствие ошибок, то вы их найдете не слишком много.

 Если же ваша цель - показать наличие ошибок, вы найдете значительную их часть.

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

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

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

Тестирование программного обеспечения

1.1 Классификация видов тестирования

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

Состав и содержание документации, сопутствующей процессу тестирования, определяется зарубежным стандартом IEEE 829-2008 Standard for Software Test Documentation.

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

По объекту тестирования

 Функциональное тестирование (functional testing)

 Нагрузочное тестирование (performance/load/stress testing)

 Тестирование удобства использования (usability testing)

 Тестирование интерфейса пользователя (UI testing)

 Тестирование безопасности (security testing)

 Тестирование локализации (localization testing)

 Тестирование совместимости (compatibility testing)

. По знаниям о тестируемой системе

 Тестирование методом «черного ящика» (black box)

 Тестирование методом «белого ящика» (white box)

 Тестирование методом «серого ящика» (grey box)

По уровню автоматизации

 Ручное тестирование (manual testing)

 Автоматизированное тестирование (automated testing)

По степени изолированности

 Модульное тестирование (unit testing)

 Интеграционное тестирование (integration testing)

 Системное тестирование (system testing)

По уровню готовности

 Альфа-тестирование (alpha testing)

 Бета-тестирование (beta testing)

 Приемосдаточные испытания (acceptance testing)

Функциональное тестирование и тестирование качества

Функциональное тестирование проводится для проверки выполнения системой функциональных требований.

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

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

• Время отклика (время выполнения операции)

• Число операций, выполняемых в единицу времени (например, transactions per second, TPS).

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

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

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

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

Тестирование интерфейса пользователя (UI testing) предполагает проверку соответствия ПО требованиям к графическому интерфейсу пользователя. Различают следующие виды тестирования графического интерфейса пользователя:

• Тестирование на соответствие стандартам графических интерфейсов;

• Тестирование с различными разрешениями экрана;

• Тестирование локализованных версий: проверка длины названий элементов интерфейса и т.п.;

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

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

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

• Тестирование авторизации пользователей - выявляет дефекты, связанные с авторизацией отдельных пользователей и г8рупп пользователей и с проверкой их подлинности;

• Тестирование процедур проверки корректности ввода - имеет целью выявление ошибок в процедурах проверки данных, поступающих в систему извне;

• Тестирование криптографических механизмов защиты - используется для выявления дефектов, связанных с шифрованием и расшифрованием данных, использованием цифровых подписей и проверкой целостности данных;

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

• Тестирование на переполнение буфера - выявляет выход за границы буферов при обработке данных;

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

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

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

Тестирование совместимости (compatibility testing) - проверка совместимости системы с различными вариантами программно-аппаратного окружения (операционными системами, различными браузерами, сетевым ПО, СУБД, сторонним ПО, аппаратной платформой).

2. Основы функционального тестирования (Black-Box)

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

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

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

2.1. Black-box, white-box, grey-box тестирование.

По степени доступа к коду различают два типа тестирования: тестирование "черного ящика" (black box), или функциональное тестирование - без доступа к коду, и "белого ящика" (white box), или структурное тестирование - тестирование кода.

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

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

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

2.2. Методы отбора тестов для Black-box тестирования

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

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

2.3. Тестирование сценариев использования - юз-кейсов (use-cases)

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

Чтобы уменьшить число тестов, можно проверить только те переходы, которые имеют смысл для пользователя. Use-case - это логически завершенная последовательность действий. Например, открытие файла в Notepad - это use-case, а выбор пункта меню "Открыть файл" в Notepad - это не use-case, а лишь первый шаг юз-кейса "открытие файла".

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

Здесь проверяется правильность перехода программы между внутренними состояниями при выполнении определенных операций (т.е. при определенных входных данных).

2.4. Тестирование классов эквивалентности.

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

Например, пусть мы тестируем программу для отдела кадров, в ней есть поле "Возраст соискателя".

Требования по возрасту у нас будут такие:

0-13 лет - не нанимать

14-17 лет - можно нанимать на неполный день

18-54 года - можно нанимать на полный день

55-99 лет - не нанимать

Чтобы проверить все возможные разрешенные данные (только разрешенные!) нам нужно протестировать ввод чисел от 0 до 99. (Возможен ведь еще ввод отрицательных чисел и нечисловых данных.) Так ли необходимо тестировать все числа от 0 до 99? В случае, если программа анализирует каждое чиcло по отдельности, вот таким образом, то видимо, да:

...

if (age == 13) hireStatus="NO";

if (age == 14) hireStatus="PART";

if (age == 15) hireStatus="PART";

if (age == 16) hireStatus="PART";

if (age == 17) hireStatus="PART";

if (age == 18) hireStatus="FULL";

...

Но к счастью, программы обычно пишут по-другому:

if (age >= 0 && age <=13)

hireStatus="NO";

if (age >= 14 && age <=17)

hireStatus="PART";

if (age >= 18 && age <=54)

hireStatus="FULL";

if (age >= 55 && age <=99)

hireStatus="NO";

Становится очевидным, что можно протестировать одно из чисел каждого диапазона. Например: 5, 15, 20, 60. А также граничные значения (первое и последнее значения из каждого диапазона): 0, 13, 14, 17, 18, 54, 55, 99.Чтобы уменьшить количество тестируемых значений, производится

а) разбиение множества всех значений входной переменной на подмножества (классы эквивалентности), а затем

б) тестирование одного любого значения из каждого класса.

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

В данном случае имеем 12 классов эквивалентности (каждое из 8 граничных значений по сути является отдельным классом).

Чтобы проверить правильность работы программы на всех разрешенных данных, нужно провести 12 тестов.

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

Таким образом, метод классов эквивалентности можно разделить на три этапа:

1. Тестирование разрешенных значений

2. Тестирование граничных значений

3. Тестирование запрещенных значений

Часто в литературе второй и третий этапы называют отдельными методами, но сути это не меняет.

2.5. Попарное тестирование.

Метод классов эквивалентности применяется для тестирования каждого входного параметра по отдельности.

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

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

Таким образом, можно упростить себе задачу и протестировать все возможные значения для каждой из пар параметров. Такой подход называется попарным тестированием (pairwise testing).

Вот пример. Пусть имеется 3 двоичных входных параметра (3 чекбокса). Количество всех возможных комбинаций - 2 в степени 3 = 8 , значит, нужно произвести 8 тестов. Давайте попробуем сэкономить, тестируя чекбоксы попарно.

Выпишем все комбинации для первого и второго чекбоксов:

1-й 2-й

0 0

0 1

1 0

1 1

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

1-й 2-й 3-й

0 0 0

0 1 0

1 0 1

1 1 1

Итак, с помощью четырех наборов входных данных (четырех тестов) мы протестируем две пары параметров: первый со вторым и второй с третьим. Осталось протестировать пару "первый с третьим".

Выпишем отдельно 1 и 3 столбцы:

1-й 3-й

0 0

0 0

1 1

1 1

Как видно, мы имеем здесь две из четырех возможных комбинаций. Комбинации "01" и "10" здесь отсутствуют, а комбинации "00" и "11" присутствуют два раза. Ну что же, добавим еще 2 строки (еще два теста)

1-й 3-й

0 0

0 0

1 1

1 1

0 1

1 0

Вернем второй столбец на его законное место:

1-й 2-й 3-й

0 0 0

0 1 0

1 0 1

1 1 1

0 1

1 0

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

1-й 2-й 3-й

0 0 0

0 1 0

1 0 1

1 1 1

0 0 1

1 0 0

Получаем 6 тестов вместо 8 при полном переборе.

Можно ли сэкономить еще? Оказывается, можно.

Вернемся к 1 шагу:

1-й 2-й

0 0

0 1

1 0

1 1

Давайте допишем третий столбец другим способом, поменяв порядок комбинаций:

1-й 2-й 3-й

0 0 1

0 1 0

1 0 0

1 1 1

Все комбинации для 1 и 2, а также для 2 и 3 параметра здесь есть. Посмотрим теперь на комбинации 1 и 3 параметра

1-й 3-й

0 1

0 0

1 0

1 1

Изменив порядок значений в третьем столбце, мы одним махом убили двух зайцев: скомбинировали и 2-й с 3-м, и 1-й с 3-м параметры.

Итого имеем всего 4 строки, то есть 4 теста, эквивалентные первоначальным шести:

1-й 2-й 3-й

0 0 1

0 1 0

1 0 0

1 1 1

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

Вот строгое определение ортогонального массива:

Ортогональный массив OA(N,k,s,t) - это двумерный массив из N рядов (итераций) и k колонок (факторов) из набора S (т.е. факторы могут принимать любое из s значений), обладающий свойством:

выбрав любые t колонок (0<=t<=k) мы получим в рядах все комбинации сочетаний из s по t (Количество повторений одинаковых комбинаций обозначают через λ. Чаще всего рассматривают массивы, где λ = 1, т.е. каждая комбинация встречается только один раз). Параметр t называют мощностью ортогонального массива.

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

2.5. Использование информации о программе при Gray-Box тестировании

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

2.5.1. Информация о базе данных

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

Например, если вводимая фамилия пользователя записывается в поле типа "строка" длиной 128 символов, мы должны:

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

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

2.5.2. Информация о других внешних системах

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

2.5.3. Информация о коде программы

Если мы имеем доступ к коду программы, мы можем

а) увидеть специальные случаи, которые не попали в документ с требованиями и которые необходимо протестировать или, напротив

б) увидеть, что какие-то вещи тестировать не имеет смысла.

2.6. Методы отбора тестов для White-Box тестирования

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

Различают два метода отбора тестов:

5.1. Тестирование путей исполнения (control-flow testing)

5.2. Тестирование работы с данными (data-flow testing)

Подробно эти методы описаны в книге A Practitioner's guide to Sofware Test Design (Lee Copeland). Описание их выходит за рамки данной лекции, поскольку они не являются методами функционального тестирования.

3. наращиваемый подход к первичному функциональному тестированию ПО.

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

Большинство программных продуктов состоит из трех компонентов:

1. Инсталлятор

2. Пользовательская документация.

3. Собственно программа

Тестирование инсталлятора обычно включает в себя:

1. Тестирование свежей (первичной) инсталляции

2. Тестирование апгрейда (повторной инсталляции поверх уже существующей копии)

3. Тестирование деинсталляции

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

1. Тестирование формальных требований (полнота, понятность, непротиворечивость, актуальность)

2. Тестирование правильности синтаксиса и грамматики

3. Тестирование работоспособности примеров

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

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

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

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

1. Приемочное тестирование требований к ПО

2. Исследовательское тестирование.

3. Тестирование базовых сценариев

4. Анализ тенденций

5. Поэлементное тестирование входных данных (тестирование каждого элемента данных в отдельности на всех разрешенных классах эквивалентности)

6. Комбинирование входных данных (тестирование комбинаций разрешенных значений для нескольких элементов данных)

7. Тестирование граничных значений

8. Тестирование ошибочных данных

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

Затем, по утвержденному черновику, можно проводить тестирование.

3.1. Приемочное тестирование требований

Приемочное тестирование - это минимально необходимое. QA должно обращать внимание в первую очередь на

1. наличие

2. непротиворечивость

3. проверяемость (testability)

4. полноту системы операций (CRUD).

CRUD - это 4 базовых функции персистентного хранилища: create, read, update, delete. Большинство пользовательских интерфейсов содержит эти операции. В требованиях должны присутствовать эти операции над объектами каждого типа из доступных в пользовательском интерфейсе.

Другие требования должны проверяться другими людьми.

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

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

3.2. Исследовательское тестирование ПО.

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

Действия, которые можно предпринять на этом этапе:

1. Чтение внешней документации (учебники, википедия)

2. Чтение внутренней документации (требования к ПО, гайды, прочее)

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

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

4. Проверка всех возможностей ПО. Пользователю ПО доступны, как правило, три вида интерфейса:

GUI - следует открыть важные экраны и диалоги графического интерфейса

CLI - попробовать основные ключи интерфейса командной строки

API - вызвать основные методы API

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

5. Ad-hoc тестирование. Ad hoc означает "Для этого", для специальной цели. Если нам пришло в голову провести какую-то специальную проверку и такая проверка может вскрыть критичный баг, следует ее провести сейчас.

3.3. Тестирование базовых сценариев

На этом этапе нужно проверить все базовые сценарии, описанные в требованиях, при типичных или дефолтных настройках. Если пользоваться моделью конечного автомата в виде графа, таким образом мы проверим наиболее важные пути в графе. См. Boris Beizer, Black-Box Testing.

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

3.4. Анализ тенденций

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

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

3.5. Поэлементное тестирование входных данных

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

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

3.6. Комбинирование входных данных.

Определить и протестировать комбинации разрешенных значений для нескольких элементов данных.

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

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

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

3.7. Тестирование граничных значений.

Для каждой границы каждого элемента данных нужно протестировать 2 значения (последнее из одного класса эквивалентности и первое - из другого)

Можно выделить 2 границы:

1. Границы диапазона данных

2. Границы размера поля (длина строки)

3.8. Тестирование невалидных данных (не имеющих смысла)

1. Пустая строка

2. Неверные числовые данные (напр., отрицательные или дробные, там где это не имеет смысла)

3. Недопустимый формат (например, для даты или телефона)

4. Недопустимые печатные символы (служебные или национальные символы там, где это не имеет смысла)

5. Недопустимые непечатные символы (перевод строки или табуляция там, где это не имеет смысла)

Пример. Пусть нам дали на тестирование некое веб-приложение по некому адресу в интернете.

1. На первом этапе выяснилось, что никаких документальных требований нет.

2. При исследовательском тестировании выяснилось, что программа предназначена для создания почтовых ящиков, интерфейс имеет три текстовых поля ввода: e-mail, пароль, размер ящика в МБ и кнопку Submit.

3. Базовые сценарии (операции CRUD)

Имеется только операция Create. Операции Read, Update and Delete отсутствуют (получения информации о почтовом ящике, редактирования и удаления почтового ящика). Имеет смысл написать баг или спросить авторитетное лицо проекта насчет их отсутствия.

Нужно создать ящик и проверить, что он действительно работает.

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

5. Поэлементное тестирование входных данных

5.1. Имеется три поля ввода

5.2. Классы эквивалентности для валидных значений:

E-mail может быть:

1. свободный/занятый

2. на домене, который обслуживается/не обслуживается данным сервером

Всего получается 4 класса эквивалентности. Ввод занятого E-mail следует проверять именно на этом этапе, т.к. значение является валидным E-mail согласно RFC. Нельзя считать это значение ошибочным и откладывать тестирование на последний этап.

Пароль может быть

1. Удовлетворяющий требованиям сложности или нет - 2 класса

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

Размер может быть:

1. Меньше предельного/больше предельного

2. Целый/дробный

4 класса эквивалентности.

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

Итого получается 10 тестов.

6. Комбинирование входных данных.

Email: free, busy, our domain, external domain

Password: safe, not safe

Size: less than limit, more than limit, integer, fractional

Всего комбинаций 4*2*4 = 32

Воспользуемся утилитой PICT, она нам даст 17 попарных комбинаций.

7. Тестирование граничных значений

Email: диапазон данных - неприменимо

длина данных - перед собакой как минимум 1 символ должен быть, как максимум - 64 (википедия)

Надо проверить: 0, 1, 64, 65

общая длина - 254 максимум (надо проверить 254 и 255)

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

Размер ящика:

диапазон: 0, 0.0000001 (количество нулей подбирается экспериментально), макс. предел (напр 100), макс. предел + 0.000001

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

8. Тестирование невалидных данных

Email - пустая строка, невалидный по RFC (несколько вариантов, например, перебрать все запрещенные символы)

Пароль - пустая строка, юникод-символы

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

4. Тестовая документация

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

Написание тестовой документации имеет много общего с написанием ПО: следует разбивать код на отдельные модули и избегать дублирования кода.

4.1. Что должна содержать тестовая документация и почему.

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

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

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

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

Краткое описание тест-кейса имеет смысл вынести в заголовок.

Пример.

Заголовок: "Проверка того, что программа умеет показывать файлы формата BMP"

Шаг 1. Нажать кнопку "Выбрать файл"

Шаг 2. Выбрать файл с расширением BMP

Шаг 3. Нажать кнопку "Открыть"

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

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

Заголовок: "Проверка изменения домашнего телефона пользователя в ActiveDirectory"

Шаг 1. Нажать кнопку "Создать пользователя"

Шаг 2. Ввести имя пользователя, логин и пароль.

Шаг 3. Нажать кнопку OK

Шаг 4. Выбрать только что созданного пользователя в списке, кликнув на его логин.

Шаг 5. Нажать кнопку "Редактировать"

шаг 6. Ввести номер телефона в поле "Домашний телефон"

шаг 7. Нажать кнопку ОК

Ожидаемый результат: домашний телефон сохранился в ActiveDirectory.

Здесь ожидаемый результат было бы неплохо также расписать в виде последовательности шагов: как посмотреть в ActiveDirectory, что домашний телефон сохранился. Это и будет описанием критерия соответствия. Можно записать эти шаги здесь же, начиная с номера 8, и уточнить ожидаемый результат:

Шаг 8. Залогиниться на сервер AciveDirectory

Шаг 9. Открыть оснастку dsa.msc

Шаг 10. Найти пользователя по логину

Шаг 11. Посмотреть значение поля Home phone

Ожидаемый результат: это значение соответствует номеру телефона в поле "Домашний телефон"

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

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

Таким образом, возвращаемся к предыдущему варианту и вставляем ссылку в поле "Ожидаемый результат":

Ожидаемый результат: домашний телефон сохранился в ActiveDirectory.

4.2. Тестовые объекты и тестовые данные

Вышеприведенный тесткейс должен проверять редактирование телефона пользователя. Однако же первые три шага не относятся к редактированию телефона. Это вспомогательные шаги по созданию пользователя - мы создаем тестовый объект, объект, который мы будем использовать в тестах. Целесообразно вынести эти шаги в отдельную секцию "Setup", и описать более кратко:

Setup:

Создать пользователя.

Шаг 1. Открыть список пользователей.

Шаг 2. Выбрать пользователя в списке, кликнув на его логин.

Шаг 3. Нажать кнопку "Редактировать"

шаг 4. Ввести номер телефона в поле "Домашний телефон"

шаг 5. Нажать кнопку ОК

Ожидаемый результат: домашний телефон сохранился в ActiveDirectory.

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

Часто один и тот же тесткейс следует выполнять с разными тестовыми данными. Например, если программа должна уметь показывать файлы в формате BMP, JPG и GIF, логично написать один тесткейс и указать в специальной секции, что выполняться он должен с использованием трех файлов разного формата. По аналогии с программированием - мы выносим название формата в параметр процедуры. Такой тесткейс называется data-driven - управляемый данными.

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

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

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

4.3. Идентификатор тесткейса, приоритет, время прохождения

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

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

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

4.4. История изменений и история прохождений

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

Однако этот способ не так удобен, как применение специализированных систем поддержки тестовой документации, например TestRail или Testlink. Такие системы имеют ряд дополнительных функций, связанных с прохождением тесткейсов:

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

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

5. Тестирование мобильных приложений.

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

Стоимость ошибки в релизе мобильного приложения высока. Приложения попадают в Google Play в течении нескольких часов, в Appstore несколько недель. Неизвестно сколько времени будут обновляться пользователи. Ошибки вызывают бурную негативную реакцию, пользователи оставляют низкие оценки и истерические отзывы. Новые пользователи, видя это, не устанавливают приложение.

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

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

5.1. Тестирование требований

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

навигационная схема за три моря

Рисунок 1 - Начальные этапы тестирования

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

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

Когда требования стали полны и непротиворечивы, тестировщик составляет smoke-тесты и функциональные тесты, покрывающие исходные данные. Тесты деляется на общие и специфические для разных платформ. Для хранения и прогона тестов мы используем Sitechсo.

https://habrastorage.org/getpro/habr/post_images/656/97b/500/65697b5004acd5282c29f7749f9ebfb5.png

Рисунок 2 - Рабочая среда тестировщика (наполнение тестов)

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

5.2. Билд-сервер

Как правило, проекты собираются на TeamCity билд-сервере.

https://habrastorage.org/getpro/habr/post_images/95a/0f2/e98/95a0f2e98d9d969e49b24670160e7474.png

Рисунок 3 - Интерфейс билд-сервера

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

https://habrastorage.org/getpro/habr/post_images/d33/78c/2d9/d3378c2d97ab6f8cae736ed86df3616a.jpg

Рисунок 4 - Интерфейс отображения процесса тестирования

5.3. Быстрое тестирование

Быстрое тестирование проводится после завершения итерации разработки, если сборка не пойдет в релиз.Для начала проводятся smoke-тесты, чтобы понять имеет ли смысл тестировать сборку.

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

Некорректно выполненные задачи переоткрываются. Баги заносятся в Jira. К не UI багам обязательно прикладываются логи со смартфона. К UI багам скриншоты с пометками что не так.

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

Для андроид-приложений запускаются monkey тесты. По окончании тестирования ставится галочка «тестирование багов пройдено» в билд-сервере.

Если в процессе тестирования не было найдено blocker, critical и major багов, ставится галочка «можно показывать заказчику». Ни один билд не отсылается заказчику без одобрения отдела тестирования. (По согласованию с заказчиком иногда высылаются билды с major багами).Критичность бага определяется по таблице:

таблица определение критичности ошибки

Рисунок 5 - Таблица определения критичности бага

После завершения тестирования PM получает подробное письмо-отчет:

отчет о завершении тестирования

Рисунок 6 - Письмо–отчет

5.4. Полное тестирование

Полное тестирование проводится перед релизом. Включает себя в себя быстрое тестирование, регресионное тестирование, monkey-тестирование на 100 устройствах и тестирование обновлений.

Регрессионное тестирование подразумевает прогон ВСЕХ тест-кейсов по проекту. Тест-кейсов не только за последнюю итерацию, но и за все предыдущие и общие тест кейсы по требованиям. Это занимает день-три на одно устройство в зависимости от проекта.

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

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

Релизный monkey-тест осуществляется на 10 iOS и 80 Android устройствах при помощи сервиса Appthwack. В конце полного тестирования, кроме письма, вручную составляется подробный отчет.

Сборка уходит в релиз только при 100% прохождении всех тест-кейсов.

https://habrastorage.org/getpro/habr/post_images/ab3/a38/4de/ab3a384dedecc509dbb0cad9d288c416.png

Рисунок 7 - Результаты тестирования

5.5.Тестирование внешних сервисов

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

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

Учет времени тестировщиков производится в отдельном Jira проекте. На составление тест-кейсов, прогон тестов, написание отчетов по проекту заводится отдельная задача и стандартными средствами в ней отмечается затраченное время.

https://habrastorage.org/getpro/habr/post_images/dda/ed7/850/ddaed7850deef27e9e9745f5566bae63.png

Рисунок 8 - Отслеживание времени

Заключение

Многие организации, занимающиеся созданием программного обеспечения, до 30% средств, выделенных на разработку программ, тратят на испытания, что составляет миллиарды долларов ПО всему миру в целом. И все же, несмотря на громадные капиталовложения, знаний o сути испытаний явно не хватает и большинство программных продуктов ненадёжно.

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

Невозможно гарантировать отсутствие ошибок в нетривиальной программе; в лучшем случае можно попытаться показать наличие ошибок. Если программа правильно ведет себя для солидного набора тестов, нет оснований утверждать, что в ней нет ошибок; со всей определённостью можно лишь утверждать, что не известно, когда эта программа не работает. Конечно, если есть причины считать данный набор тестов способным с большой вероятностью обнаружить все возможные ошибки, то можно говорить o некотором уровне уверенности в правильности программы, устанавливаемом этими тестами. Надёжность невозможно внести в программу в результате тестирования, она определяется правильностью этапов проектирования. Наилучшее решение проблемы надёжности - с самого начала не допускать ошибок в программе. Однако вероятность того, что удастся безупречно спроектировать большую программу, бесконечно мала.

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

Список литературы

  1. Анашкина Н.В., Петухова Н.Н., Смольянинов В.Ю. Технологии и методы программирования.
  2. Кнут Д. Искусство программирования для ЭВМ
  3. Соммервил И., Инженерия программного обеспечения. 6-е изд.
  4. Орлов С.А., Технологии разработки программного обеспечения.
  5. Брауде Эрик Дж., Технология разработки программного обеспечения.
  6. Жоголев Е.А., Технология программирования.
  7. Мейер Б., Бодуэн К. Методы программирования.
  8. <http://www.refu.ru/refs/67/14960/1.html>
  9. <http://social.msdn.microsoft.com/Forums/ru-RU/e750a78b-0c1f-4766-81a2-7cea9b4b3ea2/->
  10. <http://sergiek.narod.ru/index/0-2>
  11. http://bugscatcher.net/archives/1103
  12. Блэк Р. Ключeвыe прoцeссы тeстирoвaния. Плaнирoвaниe, пoдгoтoвкa, прoвeдeниe, сoвeршeнствoвaниe. - СПб.: Лoри, 2006. с. 576.
  13. Винничeнкo И. Aвтoмaтизaция прoцeссoв тeстирoвaния. - СПб.: Питeр, 2005. с. 203.
  14. Дaстин Э., Рэшкa Р, Джoн Пoл Джoн. Aвтoмaтизирoвaннoe тeстирoвaниe прoгрaммнoгo oбeспeчeния. - СПб.: Лoри, 2003. с. 384.
  15. Липaeв В.В. Нaдёжнoсть прoгрaммных срeдств. - М.: СИНТEГ, 1998. с. 240.
  16. Липaeв В.В. Oтлaдкa слoжных прoгрaмм. - М.: Энeргoaтoмиздaт, 1993. с. 235.
  17. Мaкгрeгoр Д, Сaйкс Д. Тeстирoвaниe oбъeктнo-oриeнтирoвaннoгo прoгрaммнoгo oбeспeчeния. Прaктичeскoe пoсoбиe. - К.: ТИД "ДС", 2002. с. 432.
  18. Смaгин В.A., Сoлдaтeнкo В.С., Кузнeцoв В.В. Мoдeлирoвaниe и oбeспeчeниe нaдёжнoсти прoгрaммных срeдств AСУ. - СПб.: ВИКУ им. A.Ф. Мoжaйскoгo, 1999. с. 49.
  19. Сoммeрвилл И. Инжeнeрия прoгрaммнoгo oбeспeчeния. - СПб.: Вильямс, 2002. с. 624.
  20. Тaмрe Л.Ввeдeниe в тeстирoвaниe прoгрaммнoгo oбeспeчeния. - СПб.: Вильямс, 2003. с. 386.
  21. Шнeйдeрмaн Б. Психoлoгия прoгрaммирoвaния. - М.: Рaдиo и связь, 1984. с. 512.