Тестирование программы показывает полное отсутствие ошибок
Тестирование — один из важнейших элементов цикла разработки. Благодаря раннему и непрерывному тестированию можно сэкономить время и деньги, которые позже пойдут на исправление ошибок. Лучшие современные практики QA способствуют оптимизации и улучшению процессов тестирования, повышают качество и производительность. Но тестировщики по-прежнему сталкиваются с общими проблемами, которые мы разберём ниже.
Мы публикуем сокращённую версию. Полный текст об основных проблемах тестирования программного обеспечения, плюсах и минусах аутсорса можно прочитать здесь.
Неясные требования и цели
Хотя в Agile менять требования в середине спринта не рекомендуется, такое иногда происходит. Это стресс для всей команды, в том числе тестировщиков. Ведь объём тестирования тоже меняется.
Сценарий тестирования должен соответствовать конечной цели проекта. Поэтому важно чётко их сформулировать и донести заранее. Иначе может получиться вовсе не тот продукт, который ожидался.
Дороговизна и непонятная оценка качества
Часто у agile-команд нет количественного способа измерения общего качества продукта. Есть отдельные показатели, такие, как покрытие тестами и сложность кода, но эти элементы не дают полного представления о качестве. Поэтому тестировщики не могут проактивно выявлять конкретные области, где результат оставляет желать лучшего.
Нехватка коммуникации и простои
Отсутствие взаимодействия разработчиков и тестировщиков приводит к постоянным простоям, поскольку каждая команда пытается подстроиться под то, что сделала другая. Например, при регрессионном тестировании обнаруживается ряд проблем из-за изменений в коде. Поэтому инженерам QA приходится переписывать тестовые случаи, чтобы согласовать их с новым кодом.
Всё это время разработчикам приходится ждать, ведь если продолжить работу до результатов теста, можно наломать ещё больше дров. В итоге одна команда простаивает, пока работает другая, а потом все работают сверхурочно. В итоге уходит время, деньги, и радость от работы.
Культура QA
Если команда сразу будет ориентироваться на качество продукта, не придётся использовать QA как антикризисный инструмент. Культура качества строится на понимании и принятии всеми участниками процесса цели сделать хороший продукт. Это способствует пониманию внутри команды и помогает быстро внедрять новые методы QA, а также стабильно поставлять качественный продукт.
Ранее тестирование
Выше мы уже упоминали, насколько важно раннее тестирование для обеспечения качества программного обеспечения. Это легче сказать, чем сделать, но преимущества раннего тестирования значительно перевешивают трудности.
Частое регрессионное тестирование также может смягчить некоторые проблемы, связанные с ранним и частым тестированием. Команда QA определит конкретные области, в которых может возникнуть регрессия, что поможет свести к минимуму время тестирования без ущерба для покрытия. Автоматизация также является отличным способом частого тестирования, и её можно внедрять постепенно.
Кроме надлежащей проверки и оценки новых сотрудников, руководители команд QA также должны убедиться в наличии эффективных программ обучения, регулярно проводить анализ производительности. По мере того, как члены команды проходят обучение, тим-лиды могут давать им различные задания для оценки прогресса и компетентности.
Agile и непрерывное тестирование
С развитием Agile и DevOps стал популярным миф о том, что «тестировщики не нужны». Конечно, это не так. Тестирование, как и разработка, меняется, и новые методики помогают повысить качество конечного продукта.
Мы в Evrone исповедуем Agile и QAOps — сочетание QA и DevOps. Члены нашей команды умеют работать удаленно, сотрудничать с командами заказчика и избегать основных проблем QA-аутсорсинга.
Многие считают, что тестирование ПО — это поиск ошибок. Иногда я говорю тестировщикам: «не старайся найти как можно больше ошибок, старайся пропустить как можно меньше!», и меня не понимают: а в чём разница?
А разница огромная! В этой статье я хочу рассказать, в чём она заключается, и какие инструменты необходимо использовать для настоящего полезного тестирования.
Что такое поиск ошибок?
Я тестирую продукт. Моя задача — завести как можно больше багов. Оно и логично! Заводить баги тестировщику всегда приятно, это видимый измеримый результат работы, И чем их больше, тем больше меня ценят как тестировщика.
Какие области я буду тестировать в таком случае? В первую очередь, самые нестабильные. Зачастую они нестабильны потому, что менее приоритетны, но это неважно, значительно важнее количество багов.
Что будет, если я столкнусь со сложновоспроизводимым багом? ROI на его исследование считается в голове очень быстро. Зачем мне с ним возиться, если я за это же время смогу завести 3 менее критичных, зато простых в заведении?
Какие тесты я буду проводить в первую очередь? Конено, самые нестандартные. Ввести в поле логина «Войну и мир», поделить на ноль, вставить в профиль фотографию в формате .exe.
Скажу по секрету — иногда на собеседованиях тестировщики в ответ на просьбу «протеструйте калькулятор» перечисляют интересные и дельные тесты, но в числе первых тридцати нет теста «проверить сложение» и другие базовые операции.
Именно так выглядит поиск ошибок — не имеющий ничего общего с тестированием.
Что такое тестирование?
Я тестирую продукт. Моя задача — пропустить как можно меньше приоритетных для пользователя багов. Чем меньше багов пропущено, чем меньше недовольства клиентом выражено — тем выше я оцениваю эффективность своей работы.
Какие области я буду тестировать в этом случае? Естественно, я начну с самых приоритетных для пользователя. Даже если они стабильно и успешно работают, я всё равно буду проверять основные пользовательские сценарии, чтобы ни в коем случае не пропустить серьёзных проблем.
Что будет, если я столкнусь с трудностями? К примеру, со сложновоспроизводимым дефектом, или непониманием бизнес-процесса пользователя, или нехваткой требований? Если это важный функционал, то я буду выяснять «что не так», «как правильно». На заведение дефекта в итоге может уйти немало времени, и с точки зрения баг/время результат эффективности тестирования будет не очень высок, зато у меня появятся более глубокие знания о продукте, архитектуре, пользователях.
Какие тесты я буду проводить в первую очередь? Конечно, самые-самые стандартные. Выполнение самого основного сценария в самых основных условиях, чтобы убедиться, что самый важный функционал работает. И только после этого я перейду к менее стандартным сценариям.
Результаты тестирования и поиска ошибок
В случае с поиском ошибок, в краткосрочной перспективе результаты выше: багов заводится больше и сразу.
- из-за отсутствия глубоких знаний о продукте, постепенно начинает расти % пропущенных дефектов
- команда разработки занята исправлением страшных-ужасных-немыслимых багов, полученных путём клика на одну и ту же кнопку 144 раза под IE в полнолуние
- в релиз попадают некоторые ужасно неприятные и очевидные для пользователя баги
- количество находимых ошибок в ДОЛГОСРОЧНОЙ перспективе падает
Как перейти от поиска ошибок к тестированию?
Чтобы тестирование было эффективным и полезным в долгосрочной перспективе, необходимо следовать простым правилам и использовать ключевые инструменты тестирования:
1. Анализ продукта и документирование тестов
Кликая на кнопки, можно завести много багов — но нельзя сказать, что было проверено. Единственное решение — документирование тестов. Подробные тест-кейсы, удручающие тестировщиков и отнимающие уйму времени, бывают нужны очень редко. А вот чек-листы с перечнем «что нужно проверить» — необходимы.
- Вы анализируете продукт, выписываете основные фичи, действия, их параметры. Таким образом существенно снижается риск что-либо забыть.
- Чек-листы — отличная напоминалка «здесь надо вникнуть глубже». Есть какая-то невнятная фича с недостаточным описанием. Как её тестировать? В тестировании без тестов проще всего сказать «я вернусь к этому позже», и уже никогда не вернуться. А с тестами — у вас будет висеть тест, в котором непонятно как и что проверять, вы будете такие тесты видеть и не забудете необходимость выяснения.
- Чек-листы можно и НУЖНО согласовывать. С разработчиками, аналитиками. Вся команда включается в процесс тестирования, тестировщики узнают много нового о продукте, коллективный разум улучшает качество тестирования. И помимо однократного повышения качества отдельно взятого чек-листа, повышается качество тестирования в целом: тестировщики начинают больше учитывать в тестировании, развиваться, эти знания со временем окупаются в виде более результативного тестирования.
Залог успеха в ведении тестов — создание карты, по которой вы будете идти. Цель — покрыть весь продукт. Только пожалуйста, не надо отмазок об ужасной ресурсоёмкости — я покрывала проекты с миллионами строк кода меньше чем за месяц-полтора. И в процессе написания таких тестов поднимались неожиданные вопросы и всплывали критичные ошибки, которые несмотря на наличие горе-тестеров болтались в продукте годами.
2. Оценка тестирования
Чтобы не быть слепыми котятами, необходимо оценивать эффективность тестирования. Анализировать пропущенные ошибки и причины их пропуска. Покрытие функционала и кода тестами. Уровень удовлетворения пользователей, через анкеты и сбор обратной связи. Качество заведения ошибок, опрашивая разработчиков.
ВСЕГДА есть что улучшать, и отсутствие непрерывного процесса совершенствования — неизбежное болото.
Многие считают, что у тестирования есть какие-то мифические цели. И что они всегда одинаковы.
В каждом проекте, компании, команде цели свои собственные. Все ли их понимают одинаково? Проговаривали ли вы их вслух?
Чтобы приносить максимум пользы, надо хорошо понимать, в чём эта самая польза заключается. И не удивляйтесь, если мнение РМов и разработчиков не будет соответствовать вашему. Надо не переубеждать их, а подстраиваться под текущие проектные цели!
4. Понимание пользователей и их бизнес-процессов
- Как этот продукт используется?
- Зачем он вообще нужен, какие проблемы решает?
- Какая средняя квалификация у пользователей?
- В каких условиях работают пользователи? На каких окружениях, оборудовании?
5. Техническая квалификация и понимание архитектуры
Такие баги не просто бесполезны, они позорят тестировщиков и дискредетируют отрасль в целом! Чтобы заводить дефекты правильно, необходимо понимать платформу, на которой написан тестируемый продукт. Если мы говорим про веб-тестирование, то можно хотя бы указать в баг-репорте возвращаемый сервером код ошибки, посмотреть подробности файрбагом, предоставить подробную информацию и сэкономить разработке массу времени!
Выводы
Очень многие разработчики не любят тестировщиков. И правильно делают!
Зато хороших тестировщиков любят и ценят все. Но тестировщиков, а не кликеров и багозаводильцев!
Учитесь узнавать, что не так, что не нравится другим участникам команды разработки. Обязательно исследуйте пропущенные ошибки и делайте всё для того, чтобы больше их не пропускать. Не гонитесь за заведением багов — вашей мантрой должны быть «счастье пользователя», «качественный продукт» и «успешный проект», а не «завести как можно больше багов» — ОЧЕНЬ часто эти 2 цели оказываются слишком далеки друг от друга.
Привет, Хабр! Да-да, про тестирование ПО тут уже куча статей. Здесь я просто буду стараться структурировать как можно более полный охват данных из разных источников (чтобы по теории все основное было сразу в одном месте, и новичкам, например, было легче ориентироваться). При этом, чтобы статья не казалась слишком громоздкой, информация будет представлена без излишней детализации, как необходимая и достаточная для прохождения собеседования (согласно моему опыту), рассчитанное на стажеров/джунов (как вариант, эта информация может быть для общего понимания полезна ИТ-рекрутерам, которые проводят первичное собеседование и попутно задают некоторые около-технические вопросы).
ОСНОВНЫЕ ТЕРМИНЫ
Тестирование ПО (Software Testing) — проверка соответствия между реальным и ожидаемым поведением программы, проводится на наборе тестов, который выбирается некоторым образом. Чем занимаются в тестировании:
планированием работ (Test Management)
проектированием тестов (Test Design) — этап, на котором создаются тестовые сценарии (тест кейсы), в соответствии с определёнными ранее критериями. Т.е., определяется, КАК будет тестироваться продукт.
анализом результатов (Test Analysis)
Основные цели тестирования
техническая: предоставление актуальной информации о состоянии продукта на данный момент.
коммерческая: повышение лояльности к компании и продукту, т.к. любой обнаруженный дефект негативно влияет на доверие пользователей.
Верификация (verification)
Валидация (validation)
Соответствие продукта требованиям (спецификации)
Соответствие продукта потребностям пользователей
Дефект (баг) — это несоответствие фактического результата выполнения программы ожидаемому результату.
Следует уметь различать, что:
Bug (defect) — это ошибка программиста (или дизайнера или ещё кого, кто принимает участие в разработке), то есть когда в программе, что-то идёт не так, как планировалось. Например, внутри программа построена так, что изначально не соответствует тому, что от неё ожидается.
Failure — это сбой в работе компонента, всей программы или системы (может быть как аппаратным, так и вызванным дефектом).
Жизненный цикл бага
Серьезность (Severity) — характеризует влияние дефекта на работоспособность приложения. Выставляется тестировщиком.
Blocker - ошибка, приводящая приложение в нерабочее состояние, из-за которой дальнейшая работа с системой или ее ключевыми функциями становится невозможна, т.е. тестирование значительной части функциональности становится недоступно
Крит (Critical) - неправильно работающая ключевая бизнес-логика, дыра в системе безопасности, проблема, приведшая к временному падению сервера или приводящая в нерабочее состояние некоторую часть системы, без возможности решения проблемы, используя другие непрямые пути (workaround).
Значительный (Major) - часть основной бизнес логики работает некорректно, есть возможность для работы с тестируемой функцией, используя обходные пути (workaround); либо дефект с высоким visibility – обычно не сильно влияющие на функциональность дефекты дизайна, которые, однако, сразу бросаются в глаза.
Тривиальная (Trivial) - ошибка, не касающаяся бизнес-логики приложения, не оказывающая никакого влияния на общее качество продукта, например, опечатки в тексте, несоответствие шрифта и оттенка и т.д.
Приоритет (Priority) — указывает на очередность выполнения задачи или устранения дефекта. Чем выше приоритет, тем быстрее нужно исправлять дефект. Выставляется менеджером, тимлидом или заказчиком.
НЕКОТОРЫЕ ТЕХНИКИ ТЕСТ-ДИЗАЙНА
Эквивалентное Разделение (Equivalence Partitioning) — это техника, при которой функционал (часто диапазон возможных вводимых значений) разделяется на группы эквивалентных по своему влиянию на систему значений. ПРИМЕР: есть диапазон допустимых значений от 1 до 10, выбирается одно верное значение внутри интервала (например, 5) и одно неверное значение вне интервала — 0.
Анализ Граничных Значений (Boundary Value Analysis) — это техника проверки поведения продукта на крайних (граничных) значениях входных данных. Если брать выше ПРИМЕР: в качестве значений для позитивного тестирования берется минимальная и максимальная границы (1 и 10), и значения больше и меньше границ (0 и 11). BVA может применяться к полям, записям, файлам, или к любого рода сущностям имеющим ограничения.
Доменный анализ (Domain Analysis Testing) — это техника основана на разбиении диапазона возможных значений переменной на поддиапазоны, с последующим выбором одного или нескольких значений из каждого домена для тестирования.
Предугадывание ошибки (Error Guessing — EG). Это когда тестировщик использует свои знания системы и способность к интерпретации спецификации на предмет того, чтобы «предугадать» при каких входных условиях система может выдать ошибку.
Причина / Следствие (Cause/Effect — CE). Подразумевается ввод условий, для получения ответа от системы (следствие).
Сценарий использования (Use Case Testing) — Use Case описывает сценарий взаимодействия двух и более участников (как правило — пользователя и системы).
Исчерпывающее тестирование (Exhaustive Testing — ET) — подразумевается проверка всех возможные комбинации входных значений. На практике не используется.
Попарное тестирование (Pairwise Testing) — это техника формирования наборов тестовых данных из полного набора входных данных в системе, которая позволяет существенно сократить общее количество тест-кейсов. Используется для тестирования, например, фильтров, сортировок. Этот интересный метод заслуживает отдельного внимания и более подробно рассматривается в статье по ссылке (в конце которой упоминаются инструменты для автоматизации применения PT ).
Тестирование на основе состояний и переходов (State-Transition Testing) — применяется для фиксирования требований и описания дизайна приложения.
Таблица принятия решений (decision table) — инструмент для упорядочения бизнес-требований, которые должны быть реализованы в продукте. Применяется для систем со сложной логикой. В таблицах решений представлен набор условий, одновременное выполнение которых приводит к определенному действию.
ВИДЫ ТЕСТИРОВАНИЯ
Основные виды тестирования ПО
Классификация по целям
Функциональное тестирование (functional testing) рассматривает заранее указанное поведение и основывается на анализе спецификации компонента или системы в целом, т.е. проверяется корректность работы функциональности приложения.
Тестирование пользовательского интерфейса (GUI Testing) — проверка интерфейса на соответствие требованиям (размер, шрифт, цвет, consistent behavior).
Тестирование удобства использования (Usability Testing) — это метод тестирования, направленный на установление степени удобства использования, обучаемости, понятности и привлекательности для пользователей разрабатываемого продукта в контексте заданных условий. Состоит из: UX — что испытывает пользователь во время использования цифрового продукта, и UI — инструмент, позволяющий осуществлять интеракцию «пользователь — веб-ресурс».
Тестирование безопасности (security testing) — это стратегия тестирования, используемая для проверки безопасности системы, а также для анализа рисков, связанных с обеспечением целостного подхода к защите приложения, атак хакеров, вирусов, несанкционированного доступа к конфиденциальным данным.
Инсталляционное тестирование (installation testing) направленно на проверку успешной установки и настройки, а также обновления или удаления приложения.
Конфигурационное тестирование (Configuration Testing) — специальный вид тестирования, направленный на проверку работы программного обеспечения при различных конфигурациях системы (заявленных платформах, поддерживаемых драйверах, при различных конфигурациях компьютеров и т.д.)
Тестирование на отказ и восстановление (Failover and Recovery Testing) проверяет тестируемый продукт с точки зрения способности противостоять и успешно восстанавливаться, т.е. обеспечивать сохранность и целостность данных, после возможных сбоев, возникших в связи с ошибками программного обеспечения, отказами оборудования или проблемами связи (например, отказ сети).
Тестирование локализации (localization testing) — проверка адаптации программного обеспечения для определенной аудитории в соответствии с ее культурными особенностями.
Нагрузочное тестирование (load testing) — определение или сбор показателей производительности и времени отклика программно-технической системы или устройства в ответ на внешний запрос с целью установления соответствия требованиям, предъявляемым к данной системе (устройству).
Тестирование стабильности или надежности (Stability / Reliability Testing) — это проверка работоспособности приложения при длительном (многочасовом) тестировании со средним уровнем нагрузки.
Стрессовое тестирование (Stress Testing) позволяет проверить насколько приложение и система в целом работоспособны в условиях стресса (например, повышение интенсивности выполнения операций до очень высоких значений или аварийное изменение конфигурации сервера) и также оценить способность системы к регенерации, т.е. к возвращению к нормальному состоянию после прекращения воздействия стресса.
Объемное тестирование (Volume Testing) — тестирование, которое проводится для получения оценки производительности при увеличении объемов данных в базе данных приложения.
Тестирование масштабируемости (scalability testing) — тестирование, которое измеряет производительность сети или системы, когда количество пользовательских запросов увеличивается или уменьшается.
Классификация по позитивности сценария
Позитивное — тест кейс использует только корректные данные и проверяет, что приложение правильно выполнило вызываемую функцию.
Негативное — тест кейс оперирует как корректными так и некорректными данными (минимум 1 некорректный параметр) и ставит целью проверку исключительных ситуаций; при таком тестировании часто выполняются некорректные операции.
Классификация по знанию системы
Тестирование белого ящика (White Box) — метод тестирования ПО, который предполагает полный доступ к коду проекта, т.е. внутренняя структура/устройство/реализация системы известны тестировщику.
Тестирование серого ящика — метод тестирования ПО, который предполагает частичный доступ к коду проекта (комбинация White Box и Black Box методов).
Тестирование чёрного ящика (Black Box) — метод тестирования ПО, также известный как тестирование, основанное на спецификации или тестирование поведения — техника тестирования, которая не предполагает доступа (полного или частичного) к системе, т.е. основывается на работе исключительно с внешним интерфейсом тестируемой системы.
Классификация по исполнителям тестирования
Альфа-тестирование — является ранней версией программного продукта, тестирование которой проводится внутри организации-разработчика; может быть вероятно частичное привлечение конечных пользователей.
Бета-тестирование — практически готовое ПО, выпускаемое для ограниченного количества пользователей, разрабатывается в первую очередь для тестирования конечными пользователями и получения отзывов клиентов о продукте для внесения соответствующих изменений.
Классификация по уровню тестирования
Модульное (компонентное) тестирование (Unit Testing) проводится самими разработчиками, т.к. предполагает полный доступ к коду, для тестирования какого-либо одного логически выделенного и изолированного элемента (модуля) системы в коде, проверяет функциональность и ищет дефекты в частях приложения, которые доступны и могут быть протестированы по-отдельности (модули программ, объекты, классы, функции и т.д.).
Интеграционное тестирование (Integration Testing) направлено на проверку корректности взаимодействия нескольких модулей, объединенных в единое целое, т.е. проверяется взаимодействие между компонентами системы после проведения компонентного тестирования.
Снизу вверх (Bottom Up Integration) Все низкоуровневые модули, процедуры или функции собираются воедино и затем тестируются. После чего собирается следующий уровень модулей для проведения интеграционного тестирования. Данный подход считается полезным, если все или практически все модули, разрабатываемого уровня, готовы. Также данный подход помогает определить по результатам тестирования уровень готовности приложения.
Сверху вниз (Top Down Integration) Вначале тестируются все высокоуровневые модули, и постепенно один за другим добавляются низкоуровневые. Все модули более низкого уровня симулируются заглушками с аналогичной функциональностью, затем по мере готовности они заменяются реальными активными компонентами.
Большой взрыв («Big Bang» Integration) Все или практически все разработанные модули собираются вместе в виде законченной системы или ее основной части, и затем проводится интеграционное тестирование. Такой подход очень хорош для сохранения времени. Однако если тест кейсы и их результаты записаны не верно, то сам процесс интеграции сильно осложнится, что станет преградой для команды тестирования при достижении основной цели интеграционного тестирования.
Системное тестирование (System Testing) — это проверка как функциональных, так и не функциональных требований в системе в целом. При этом выявляются дефекты, такие как неверное использование ресурсов системы, непредусмотренные комбинации данных пользовательского уровня, несовместимость с окружением, непредусмотренные сценарии использования и т.д., и оцениваются характеристики качества системы — ее устойчивость, надежность, безопасность и производительность.
Операционное тестирование (Release Testing). Даже если система удовлетворяет всем требованиям, важно убедиться в том, что она удовлетворяет нуждам пользователя и выполняет свою роль в среде своей эксплуатации. Поэтому так важно провести операционное тестирование как финальный шаг валидации. Кроме этого, тестирование в среде эксплуатации позволяет выявить и нефункциональные проблемы, такие как: конфликт с другими системами, смежными в области бизнеса или в программных и электронных окружениях и др. Очевидно, что нахождение подобных вещей на стадии внедрения — критичная и дорогостоящая проблема.
Классификация по исполнению кода
Статическое тестирование — процесс тестирования, который проводится для верификации практически любого артефакта разработки. Например, путем анализа кода (code review). Анализ может производиться как вручную, так и с помощью специальных инструментальных средств. Целью анализа является раннее выявление ошибок и потенциальных проблем в продукте. Также к этому виду относится тестирование требований, спецификаций и прочей документации.
Динамическое тестирование проводится на работающей системе, т.е. с осуществлением запуска программного кода приложения.
Классификация по хронологии выполнения
Повторное/подтверждающее тестирование (re-testing/confirmation testing) — тестирование, во время которого исполняются тестовые сценарии, выявившие ошибки во время последнего запуска, для подтверждения успешности исправления этих ошибок, т.е. проверяется исправление багов.
Регрессионное тестирование (regression testing) — это тестирование после внесения изменений в код приложения (починка дефекта, слияние кода, миграция на другую операционную систему, базу данных, веб сервер или сервер приложения), для подтверждения того факта, что эти изменения не внесли ошибки в областях, которые не подверглись изменениям, т.е. проверяется то, что исправление багов, а также любые изменения в коде приложения, не повлияли на другие модули ПО и не вызвали новых багов.
Приёмочное тестирование проверяет соответствие системы потребностям, требованиям и бизнес-процессам пользователя.
ДОКУМЕНТАЦИЯ
Требования — это спецификация (описание) того, что должно быть реализовано. Требования описывают то, что необходимо реализовать, без детализации технической стороны решения.
Основные атрибуты требований:
Полнота — в требовании должна содержаться вся необходимая для реализации функциональности информация.
Непротиворечивость — требование не должно содержать внутренних противоречий и противоречий другим требованиям и документам.
Недвусмысленность — требование должно содержать однозначные формулировки.
Проверяемость (тестопригодность) — формулировка требований таким образом, чтобы можно было выставить однозначный вердикт, выполнено все в соответствии с требованиями или нет.
Приоритетность — у каждого требования должен быть приоритет (количественная оценка степени значимости требования).
Тест план (Test Plan) — документ, описывающий весь объем работ по тестированию:
Что нужно тестировать?
Как будет проводиться тестирование?
Когда будет проводиться тестирование?
Критерии начала тестирования.
Критерии окончания тестирования.
Основные пункты из которых может состоять тест-план перечислены в стандарте IEEE 829.
Неотъемлемой частью тест-плана является Traceability matrix — Матрица соответствия требований (МСТ) — это таблица, содержащая соответствие функциональных требований (functional requirements) продукта и подготовленных тестовых сценариев (test cases). В заголовках колонок таблицы расположены требования, а в заголовках строк — тестовые сценарии. На пересечении — отметка, означающая, что требование текущей колонки покрыто тестовым сценарием текущей строки. МСТ используется для покрытия продукта тестами.
Эта статья была начата ещё в апреле текущего (2020) года. И с тех пор я её несколько раз переписывал. Я никак не мог достичь того результата, который бы меня устроил. Я не хотел писать очередную статью про 7 принципов тестирования, куда бы просто скопипастились переводы этих принципов из ISTQB, а потом (как в лучших из статей) сопровождались разъяснениями на тему "Что это всё означает". Получилось бы очередное переписывание "священного писания" с его толкованием. Однако, поистине священное писание в толковании не нуждается.
Моя статья будет не про то, что же это за 7 столпов тестирования. Я специально опущу некоторые детали при объяснении принципов. Легким движением руки по клавиатуре вы сможете нагуглить всё это сами. Мы поговорим сразу о боли.
Принципы тестирования — это своеобразная конституция, манифест и договорённости нашей профессии. Но, как и в реальной жизни, как бы чётко ни был написан документ, какими бы благими намерениями не руководствовались авторы, конституцию можно трактовать по-разному, на манифест можно забить, о договорённостях можно забыть.
Вот об этом я бы хотел поговорить в этой статье. О том, как же мы живём с семью принципами тестирования на самом деле.
Это статья-рассуждение. Тут не будет слишком много полезностей, будьте к этому готовы. Скорее призыв к диалогу и попытка поделиться своим опытом и кое-где даже болью. Так что комментарии приветствуются.
Немного о себе, прежде чем начать (эту часть можно пропустить)
Меня зовут Кирилл, я в ИТ с 2009 года, тестированием занимаюсь уже почти 10 лет. Сейчас я работаю на руководящей должности в QA, а так же помогаю в обучении начинающих тестировщиков и параллельно этому всему веду свой телеграм-канал для джуниоров QA (ссылочка будет в конце статьи)
Я не всегда руководствовался в жизни 7ю принципами тестирования. Более того, я не всегда даже знал о них (как и многие тестировщики, я думаю). Но, чем больше сила, тем больше и ответственность, как говаривал дядя Бен. И со временем до меня начал доходить смысл каждого принципа, а после я начал замечать как эти принципы трактуются, искажаются и видоизменяются под тяжестью корпоративных культур каждой отдельной компании.
Собственно семь принципов тестирования
- Тестирование демонстрирует (только) наличие дефектов (Testing shows presence of defects)
- Исчерпывающее тестирование недостижимо (Exhaustive testing is impossible)
- Раннее тестирование (экономит время и деньги) (Early testing saves time and money)
- Принцип скопления дефектов (Defect clustering)
- Парадокс пестицида (Pesticide paradox)
- Тестирование зависит от контекста (Testing is context dependent)
- Заблуждение об отсутствии ошибок (Absence-of-errors fallacy)
Тестирование может показать наличие дефектов в программе, но не доказать их отсутствие.
На этот принцип довольно часто плюют с высоты бизнеса и проджект менеджмента. Менеджменту иногда кажется, что если багов не нашли на этапе тестирования (не важно сколько у вас степеней фильтрации в жизненном цикле), то багов нет. И когда юзеры находят баги на проде, бизнес искренне удивляется и недоумевает: "Как же вы тестируете? Очевидно вы вообще ничего не делаете, ведь если бы тестировали - баг был бы найден".
Но, коллеги, не забывайте, что иногда бизнес спрашивает "почему этот баг попал на продакшн?". На этот вопрос вы обязаны ответить вполне конкретно. У каждого конкретного бага есть причины появления/пропуска. Но давая ответ на вопрос, так же давайте понять бизнесу, что отсутствие найденных дефектов в процессе тестирования не гарантирует отсутствия ошибок в системе.
Сколь бы скрупулёзным тестирование не было, нельзя учесть все возможные сценарии, а значит и предвидеть все возможные ошибки.
Запомнили принцип выше? Отсутствие багов не гарантирует отсутствие ошибок, кажется, что второй принцип очевидно вытекает из первого, верно?
Некоторые недобросовестные тестировщики используют этот принцип, чтобы оправдывать свою некомпетентность. Ушёл критичный баг в продакшн - "ну что поделать, нельзя предусмотреть всё на свете. Вы вообще знаете, что исчерпывающее тестирование невозможно?". Но они забывают о том, что хотя предусмотреть всё невозможно, это не повод не предусматривать ничего.
В мире ограниченных ресурсов и возможностей нужно уметь оценивать риски и расставлять приоритеты. Тестируя, мы снижаем риски. Делая правильный тест-дизайн, мы ещё сильнее снижаем риски. Так и живём.
Чем раньше начнутся активности тестирования, тем дешевле исправление выявленных ошибок. Грубо говоря, вычитка требований стоит пары часов обсуждений и времени аналитика, в то время, как тот же баг в боевой системе стоит потерянных клиентов, времени разработчиков и всего цикла релиза.
Это избитая истина, примерно такого же плана, как и "ПО надо тестировать, т.к. писать код без ошибок физически невозможно". Но многим руководителям кажется, что на самом деле тестирование отнимает время релизного цикла, т.к. задерживает доставку фич, а так же тратит время тестировщиков, на то, чтобы они читали "бумажки" вместо того, чтоб тестировать.
Я всю свою жизнь сталкиваюсь с этим удивительным противоречием; парадоксом, если угодно. Менеджеры говорят, что качество ПО превыше всего, недовольные клиенты — недопустимо, если надо тестировать, то мы выделим на это время. Но на деле почти всегда оказывается, что рук не хватает, бюджета нет и "давайте вы сейчас проверите, чтобы катнуть побыстрее, а потом уже будете свои тест-кейсы писать".
Дефекты не размазаны равномерно по приложению, а сконцентрированы в больших количествах в некоторых модулях системы
Для начала хотелось бы заметить, что об этом принципе вообще не вспоминают. Наоборот, найдя пару ошибок в каком-то блоке функционала некоторые тестировщики успокаиваются, мол "ну мы там баги нашли, отлично, пойдем дальше".
Крайний случай (но справедливости ради замечу, что это не самый распространенный случай) - это "тест до первого бага". Причин тому может быть несколько: ленивый или некомпетентный тестировщик, или же метрики/kpi, которые поджимают тестировщика быстрее перекинуть мяч на сторону разработчиков.
Просто помните, если вы уже нашли несколько багов в каком-то модуле, стоит перелопатить его ещё тщательнее, скорее всего там есть ещё скрытые дефекты.
В то же время, отсутствие дефектов в других модулях не говорит, что дефектов там нет (помните первый принцип?)
Это самый распиаренный принцип тестирования. Суть его в том, что если вы долго проводите одни и те же проверки, скорее всего новых багов вы не найдете. Именно поэтому периодически нужно "встряхивать" вашу тестовую базу, ревьюить её новыми сотрудниками и проводить исследовательское тестирование.
Некоторые коллеги во имя избегания этого эффекта "забивают" на классические подходы к тестированию и всё время проводят только исследовательское тестирование. Часто объясняют это тем, что "раз регрессионные прогоны одних и тех же тестов не помогают выявлять новые дефекты, проще полностью отказаться от этого подхода и каждый раз тестировать как на новенького". К сожалению в этом суждении забывается тот факт, что парадокс пестицида говорит лишь о том, что имеющиеся наборы больше не находят новые баги, а не о том, что формальные повторяющиеся из раза в раз проверки вообще не способны находить ошибки.
Об этом я уже как-то упоминал в одной из предыдущих статей. Набор методологий и инструментов, а также подходов и ресурсов для тестирования зависит от того, что именно вы тестируете и на сколько объект тестирования важен
Иногда забывают о том, что каждой задаче своё решение и подход. Очень распространённая тактика, везде использовать старую методологию, если она себя показала хорошо. Однако этот принцип как раз напоминает нам о противоположном.
Тем не менее, многие прикрываются этим принципом со словами "Если у других методика работает - не значит, что и у нас будет". Это безусловно верно по-умолчанию. Но дело в том, что "чморение новой идеи" не доказывает, что выбранные сейчас подходы оптимальны для тестирования (так же как и доказательства вредности фаст-фуда не подтверждают полезность овощей).
Зачастую, говоря о контексте, тестировщики рассуждают о внешнем контексте: доменных областях и пользователях (которые не меняются длительное время в рамках одного продукта). Но они забывают внутренний контекст: новые разработчики, больше разработчиков, другие владельцы компании, нагрузка на сотрудников, внутриполитические силы в компании. Этот внутренний контекст и позволяет нам поднимать вопрос о смене методологии и процессов, которые раньше были неуместны.
Тот факт, что тестирование не обнаружило дефектов, ещё не значит, что программа хорошая.
Ну вот снова! Хочется сорвать с себя шапку-ушанку и крикнуть: "Ай, да катись оно всё пропадом", раз никаких гарантий нет, то нафига вообще тестировать!? Ответ прост: чтобы снизить риски. Протестированный продукт с вероятностью 95% bug free, но не протестированный продукт с вероятностью 95% уйдет в продакшн с багами.
С учетом того, как этот принцип доносят на просторах интернета, легко спутать его с первым принципом. Многие забывают, что суть принципа: отсутствие дефектов - необходимое, но не достаточное условие хорошего ПО. Есть и другие факторы, влияющие на качество продукта. И вот о них-то как раз все забывают, считая, что лишь тестировщики и тестирование ответственны за качество.
Не могу сказать, что я всю свою сознательную QA жизнь только и вижу, как принципы тестирования нарушаются. Нет, ни в коем случае. Я просто подобрал для каждого принципа распространенные случаи игнорирования или иной трактовки. В том или ином виде, объёме, сознательно или нет, но часть принципов соблюдается почти всеми командами, в которых присутствует процесс тестирования ПО. Мне лишь хотелось подсветить некоторые моменты/признаки, по которым чуть легче пустить факт нарушения принципов в своё сознание.
И напоследок вопрос без ответа, который я задаю сам себе (а теперь задам и вам): можно ли поступиться принципами тестирования во имя каких-то благих целей, или принципы тестирования, как семь смертных грехов (ох, вот это аллюзия. только сейчас это понял), являются нерушимой догмой, нарушение которой есть зло?
На просторах интернета я наткнулся ещё на парочку неофициальных доп.принципов, которые мне кажутся более понятными, приземленными и интуитивно полезными:
- тестирование должно производиться независимыми специалистами;
- тестируйте как позитивные, так и негативные сценарии;
- не допускайте изменений в ПО в процессе тестирования;
- указывайте ожидаемый результат выполнения тестов.
Данная статья раскрывает понятие тестирования программного обеспечения, объясняет, для чего нужно тестирование, а также описывает наиболее интересные и эффективные способы тестирования программного обеспечения.
Одним из этапов создания программного обеспечения является его тестирование. Наверняка каждый разработчик в начале своего пути пытался выяснить, когда же процесс тестирования и отладки может быть завершен? В какой момент можно анализировать результаты и передавать проект в эксплуатацию?
Большинство разработчиков понимает, что программ без ошибок не бывает, но на определенном этапе тестирования возникает вопрос: «Стоит ли дальше искать ошибки, или можно оставить некоторые из них до следующего этапа разработки?".
На сегодняшний день не существует такого метода тестирования, который бы позволил полностью обнаружить все дефекты и установить корректность функционирования исследуемого программного обеспечения.
Как говорил Эдгар Дейкстра (1970): «Тестирование программ может использоваться для демонстрации наличия ошибок, но оно никогда не покажет их отсутствие».
Ошибки бывают разные, и на поиск каждой ошибки уходит разное время. Зачастую, на полное тестирование программы просто не хватает времени, поэтому во всех режимах и со всеми параметрами оно трудно реализуемо.
Тестирование программного обеспечения — это процесс исследования, испытания программного продукта, для демонстрации разработчикам и заказчикам, что программа соответствует требованиям и (или) для выявления ситуации, в которых поведение программы является неправильным, нежелательным или не соответствующим спецификации.
За всю историю своего развития, процедура тестирования претерпела множество изменений, начиная от строго формализованного тестирования, которое использовалось для тестирования программ для нужд министерства обороны. В 1960-х внимание в основном уделялось полному тестированию, предполагающему полный проход всех алгоритмов с различными входными данными. Позднее такое тестирование было признано невозможным. В 1970-х понятие тестирования определялось двойственно. С одной стороны, тестирование считалось успешным, когда программа демонстрировала корректную работу, но, с другой стороны, успешным считалось то тестирование, в результате которого были найдены некоторые ошибки в работе программы. В 1980-е годы тестирование вышло на новый уровень. Тестированию подвергался не уже готовый продукт, а продукт в процессе всего цикла разработки. В это время появлялись первые инструменты для автоматизированного тестирования. В 1990-х начали появляться различные программные инструменты для поддержки процесса тестирования. В 2000-х появилось еще более широкая методология тестирования, которая предполагала максимизацию значимости всех этапов жизненного цикла программы.
Существует несколько подходов к тестированию, которые предлагают различные алгоритмы. Но в основном, это процесс творческий, который не всегда придерживается определенных правил.
Конечно, тестирование наиболее полезно на ранних этапах разработки проекта, так как это более экономично. Программа считается готовой к выпуску, когда устранены абсолютно все критические ошибки и ~85 % не критических ошибок. Считается, что дальнейшее тестирование экономически не целесообразно.
Так как у программного обеспечения (ПО) отсутствует эталон, к которому необходимо стремится, чтобы оно считалось полностью протестированным, то следует стремиться к некоторым уровням качества.
К таким уровням относятся:
- отсутствие остановок работы ПО;
- отсутствие синтаксических ошибок;
- выполнение функций ПО, описанных в техническом задании без ошибок;
- соответствие расчетных значений эталонным.
В тот момент, когда программное обеспечение соответствует всем вышесказанным уровням, оно считается протестированным и его можно передавать в эксплуатацию. Далее ПО будет передано на тестирование пользователям, которое будет продолжаться в течение всего времени пользования.
За все время существования программирования определилось несколько признаков, по которым принято производить тестирование программы: по объекту тестирования, по знанию системы, по степени автоматизации, по степени изолированности компонентов, по времени проведения тестирования, по признаку позитивности сценариев, по степени подготовленности к тестированию.
По уровням тестирования можно выделить несколько основных типов:
- модульное тестирование — тестируется минимальный компонент программы (класс, функция);
- интеграционное тестирование — тестируются межкомпонентные элементы;
- системное тестирование — тестирование всей системы на соответствие установленным требованиям;
- альфа-тестирование — штатные разработчики или потенциальные пользователи имитируют реальную работу с системой;
- бета-тестирование — распространение пробной версии программного обеспечения для большей группы лиц, с целью удостоверится в отсутствии ошибок.
Все технологии тестирования можно разделить на две большие группы: статическое и динамическое тестирование. В динамическом тестировании код исполняется, а в статическом — не выполняется. Здесь анализ программы происходит на основе исходного кода.
К наиболее интересным и эффективным техникам можно отнести тестирование белого ящика и тестирование черного ящика. Обе эти техники предполагают, что код исполняется, и разница состоит лишь в том, какой информацией владеет тестировщик.
При тестировании белого ящика, разработчик теста имеет доступ к исходному коду программ и может писать код, который связан с библиотеками тестируемого программного обеспечения.
При тестировании чёрного ящика, тестировщик имеет доступ к программе только через те же интерфейсы, что и заказчик или пользователь, либо через внешние интерфейсы, позволяющие другому компьютеру либо другому процессу подключиться к системе для тестирования.
Так же эффективным во многих случаях может быть регрессионное тестирование. Эта технология тестирования позволяет подтвердить, что изменения, внесенные в программу при выпуске новой версии, не повлияли на работоспособность программы.
В некоторых случаях, тестировщики прибегают к тестовым скриптам. Тестовые скрипты пишутся для проверки компонентов, в которых высока вероятность появления отказов или вовремя не найденная ошибка может быть дорогостоящей.
Помимо технологий тестирования были разработаны несколько эвристик, которые предлагают ситуации для остановки тестирования. Эвристики — это быстрые, недорогие способы решения проблемы или принятия решения. Эвристики подвержены ошибкам, то есть они могут, как сработать, так и не сработать. Таких эвристик на данный момент существует 11 штук. Каждая из них работает в определенном контексте, поэтому предполагается, что они будут использоваться людьми, имеющими знания и навыки для их разумного использования. Рассмотрим их.
1. Эвристика «Время вышло!". Самая распространенная эвристика. Тестирование заканчивается, как только вышло отведенное на него время.
2. Эвристика «Мертвой лошади». Тестирование заканчивается, когда обнаруживается слишком много ошибок, и дальнейшее тестирование не имеет смысла.
3. Эвристика «Освежающей паузы» предполагает приостановку тестирования, когда стало скучно или пропало вдохновение. Так же пауза может возникнуть из-за появления ошибки большего приоритета.
4. Эвристика «Отсутствие продвижения». Любые тесты приводят к одним и тем же результатам.
5. Эвристика «Больше нет интересных вопросов». Все важные основные вопросы получили свои ответы. Используется обычно в дополнение с другими эвристиками.
6. Эвристика «Пиньяты». Тестирование прекращается в тот момент, когда возникает достаточно явная серьезная проблема.
7. Эвристика «Задание выполнено». Тестирование прекращается тогда, когда получены ответы на поставленные вопросы.
8. Эвристика «Отмена задания». К этой категории относится прекращение тестирование по требованию заказчика.
9. Эвристика «Зашел в тупик». Остановка тестирование происходит по причине того, что имеется блокирующая ошибка, которая не препятствует тестированию области программы. Проблема может исходить от недостатка оборудования или же от недостатка квалификации тестировщиков.
10. Эвристика «Привычного завершения». Тестирование завершается в соответствие с протоколом, задающим некоторое количество идей для тестирования или циклов тестирования.
11. Эвристика «Уклонения/безразличия». Такой вариант возможен в том случае, если тестировщикам не интересно как работает программа, или тестируемое ПО является первой версией, которую вскоре заменят.
Подводя итоги вышесказанному, тестирование программного обеспечения — это трудоемкий процесс, который не подвергается определенным правилам и не всегда следует по определенному алгоритму. Нельзя сказать, что для определенного типа программ больше подходит определенная технология тестирования. Для каждого определенного случая подбирается своя методика тестирования и свои эвристики остановки. Этот выбор зависит от многих критериев, таких как тип программного обеспечения, цели создания программного обеспечения, задачи, для выполнения которых создавалось данное программное обеспечение. Человек, занимающийся тестированием программного обеспечения должен обладать большим багажом знаний для эффективного и своевременного поиска ошибок.
1. Гленфорд Майерс, Том Баджетт, Кори Сандлер. Искусство тестирования программ, 3-е издание = The Art of Software Testing, 3rd Edition. — М.: «Диалектика», 2012.
2. Канер Кем, Фолк Джек, Нгуен Енг Кек. Тестирование программного обеспечения. Фундаментальные концепции менеджмента бизнес-приложений. — Киев: ДиаСофт, 2001.
3. Калбертсон Роберт, Браун Крис, Кобб Гэри. Быстрое тестирование. — М.: «Вильямс», 2002.
Основные термины (генерируются автоматически): программное обеспечение, тестирование, Эвристика, ошибка, технология тестирования, белый ящик, время, дальнейшее тестирование, тестирование программ, черный ящик.
Читайте также: