Перейти к основному содержимому

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

Тестировщику Разработчику Аналитику

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

Что такое тестирование

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

Для этого существует тестирование программного обеспечения.

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

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

Классическое определение, предложенное Гленфордом Майерсом в 1979 году, гласит: «Тестирование — это процесс выполнения программы с намерением найти ошибку». Однако современное понимание расширяет эту формулировку.

Тестирование — это дисциплина, включающая в себя:

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

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

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


А что может пойти не так?

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

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

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

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

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

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


Кто такой тестировщик и QA-инженер

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

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

Тестировщики:

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

Верификация и валидация

Верификация — это процесс оценки того, правильно ли система построена. Она отвечает на вопрос: «Соблюдены ли требования при реализации?». Верификация проводится без запуска кода и включает в себя такие виды деятельности, как:

  • рецензирование требований;
  • анализ архитектуры;
  • проверка кода (code review);
  • статический анализ.

Валидация — это процесс оценки того, правильно ли построена нужная система. Она отвечает на вопрос: «Соответствует ли продукт потребностям пользователя?». Валидация требует выполнения программы и включает:

  • функциональное тестирование;
  • приёмочное тестирование;
  • тестирование юзабилити;
  • проверку на соответствие бизнес-целям.

Обе дисциплины дополняют друг друга и необходимы для комплексного обеспечения качества.


Ожидаемое и фактическое поведение системы

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

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

Сравнение этих двух состояний — основа любого теста. Без чётко определённого ожидания невозможно объективно судить о корректности работы системы.


QC (Quality Control) и QA (Quality Assurance)

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

  • выполнение тестов;
  • анализ логов;
  • проверку соответствия требованиям.

Quality Assurance (Обеспечение качества) — это системный подход к предотвращению дефектов путём улучшения процессов разработки и сопровождения. QA охватывает:

  • стандартизацию процессов;
  • обучение команды;
  • внедрение метрик;
  • аудиты и ретроспективы.

QC — это реактивная деятельность, QA — проактивная. Обе составляют полную систему управления качеством.


Требования

Давайте вспомним аналитику и то, что такое требования.

Требования бывают разных видов:

  • бизнес-требования;
  • пользовательские требования;
  • продуктовые требования (функциональные и нефункциональные).

Бизнес-требования могут быть:

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

Обычно требования представляются в виде документации, к примеру, это может быть User Story (как пользователь, я хочу, чтобы...) или Use Case (сценарий использования). Их составляют, как правило, аналитики, путём выявления требований через:

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

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

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

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

  • сначала сбор и анализ потребностей;
  • затем формулирование требований;
  • согласование с командой и обработка обратной связи;
  • разработка;
  • тестирование.

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

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


Анализ требований как основа тестирования

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

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

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

Требования, как правило, имеют следующие свойства:

  • обязательность;
  • актуальность;
  • атомарность;
  • завершённость;
  • выполнимость;
  • важность;
  • стабильность;
  • срочность;
  • недвусмысленность;
  • непротиворечивость;
  • прослеживаемость;
  • модифицируемость.

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

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

  • Неполнота — отсутствие описания определённых сценариев использования, исключений или граничных условий. Например, требование «Система должна сохранять данные пользователя» не уточняет, какие именно данные, в каком формате, при каких условиях и с какими ограничениями.
  • Двусмысленность — использование терминов, допускающих несколько интерпретаций. Фраза «Система должна быть быстрой» не содержит измеримых критериев.
  • Противоречивость — наличие в спецификации взаимоисключающих условий. Например, «Система должна отвечать за 200 мс» и «Система должна использовать асинхронную обработку с задержкой до 1 секунды».
  • Избыточность — дублирование одних и тех же требований в разных разделах документа, что усложняет поддержку и приводит к рассогласованности при изменениях.
  • Непроверяемость — формулировки, которые невозможно верифицировать технически. «Интерфейс должен быть удобным» — субъективное суждение, требующее количественной оценки (например, через метрики юзабилити).

Способы устранения таких проблем включают:

  • Проведение рецензирования требований (requirements review) с участием аналитиков, тестировщиков, разработчиков и представителей заказчика.
  • Формализацию требований в виде пользовательских историй или сценариев использования (use cases).
  • Использование моделей поведения (state diagrams, decision tables) для уточнения сложных логических ветвлений.
  • Применение спецификаций в виде executable requirements (например, через Gherkin и BDD-подход), которые одновременно служат документацией и основой для автоматизированных тестов.

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


Различия между основными категориями тестирования

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

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

Функциональное тестирование проверяет соответствие поведения системы заданным функциональным требованиям. Оно отвечает на вопрос: «Делает ли система то, что от неё ожидается?». Примеры — проверка корректности расчёта итоговой суммы в корзине интернет-магазина, верификация правил авторизации или валидации формы.

Нефункциональное тестирование оценивает атрибуты качества программного обеспечения, которые не связаны напрямую с конкретными функциями, но критически важны для эксплуатации. Оно отвечает на вопрос: «Насколько хорошо система это делает?». К таким атрибутам относятся производительность, безопасность, надёжность, масштабируемость, удобство использования и совместимость.

Ручное и автоматизированное тестирование

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

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

Позитивное и негативное тестирование

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

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


Ключевые направления тестирования

Современное тестирование охватывает множество специализированных областей, каждая из которых фокусируется на определённом аспекте качества:

  • Регрессионное тестирование — проверка того, что изменения в коде не привели к нарушению ранее работавшей функциональности. Является основой стабильности в итеративной разработке.
  • Приёмочное тестирование (UAT) — финальная верификация системы со стороны заказчика или конечного пользователя. Подтверждает, что продукт решает бизнес-задачу.
  • Нагрузочное тестирование — оценка поведения системы под ожидаемой или пиковой нагрузкой (количество пользователей, транзакций, запросов в секунду).
  • Стрессовое тестирование — проверка устойчивости системы за пределами нормальных условий эксплуатации, вплоть до её отказа (например, при исчерпании памяти или сетевого канала).
  • Тестирование безопасности — анализ на уязвимости, такие как SQL-инъекции, XSS, несанкционированный доступ, утечки данных. Может включать как автоматизированные сканирования, так и ручной пентест.
  • Тестирование юзабилити — оценка удобства, интуитивности и эффективности взаимодействия пользователя с интерфейсом. Часто включает проведение юзабилити-сессий и анализ пользовательских метрик.

Как проводят ручное тестирование

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

  1. Анализ требований — понимание того, что должно быть проверено.
  2. Проектирование тестовых сценариев — создание последовательностей действий, ожидаемых результатов и предусловий.
  3. Подготовка тестовой среды — настройка окружения, данных и конфигураций.
  4. Выполнение тестов — последовательное выполнение шагов и фиксация результатов.
  5. Сравнение с ожидаемым поведением — определение наличия или отсутствия дефекта.
  6. Документирование дефектов — создание отчётов с описанием, шагами воспроизведения, скриншотами и логами.
  7. Повторная проверка — верификация исправления после устранения дефекта.

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


Как проводят автоматизированное тестирование

Автоматизированное тестирование использует программные средства для выполнения тестов. Этапы:

  1. Выбор фреймворка и инструментов — например, Selenium, Cypress, Playwright, JUnit, pytest, xUnit.
  2. Написание тестовых скриптов — код, имитирующий действия пользователя или вызывающий API.
  3. Интеграция в CI/CD — настройка автоматического запуска тестов при каждом коммите или сборке.
  4. Настройка отчётов — генерация понятных отчётов о прохождении/падении тестов.
  5. Поддержка и актуализация — регулярное обновление тестов при изменении функционала.

Автоматизация особенно ценна для:

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

Как проводят ключевые виды тестирования

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

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

Приёмочное тестирование (UAT)

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

Нагрузочное тестирование

Моделирует ожидаемую рабочую нагрузку (например, 10 000 одновременных пользователей). Используются инструменты вроде JMeter, k6, Gatling. Цель — оценить производительность и стабильность.

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

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

Тестирование безопасности

Включает:

  • сканирование на уязвимости (OWASP ZAP, Burp Suite);
  • проверку на SQL-инъекции, XSS, CSRF;
  • анализ прав доступа;
  • ручной пентест.

Тестирование юзабилити

Проводится с участием реальных пользователей. Оценивается:

  • интуитивность интерфейса;
  • скорость выполнения задач;
  • частота ошибок;
  • субъективное восприятие.

Стратегия тестирования и планирование процедур

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

  • цели тестирования;
  • типы тестов;
  • уровни покрытия;
  • критерии входа и выхода;
  • роли и ответственности;
  • инструменты и технологии.

Планирование процедур — это детализация стратегии на конкретный релиз или итерацию. Включает:

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

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


Серьёзность дефекта и градация

Серьёзность (Severity) — степень влияния дефекта на работоспособность системы:

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

Приоритет дефекта

Приоритет (Priority) — насколько быстро дефект должен быть исправлен:

  • Высокий — исправление требуется до следующего релиза.
  • Средний — можно исправить в ближайших итерациях.
  • Низкий — исправление откладывается на будущее.

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


Тестовые среды

  • Среда разработки (Development Env) — используется разработчиками для написания и отладки кода. Часто локальная или персональная.
  • Среда тестирования (Test Env) — выделенная среда для тестировщиков. Здесь проводятся функциональные, регрессионные и smoke-тесты.
  • Интеграционная среда (Integration Env) — предназначена для проверки взаимодействия между модулями, микросервисами или внешними системами.
  • Предпродакшен (Preprod Env) — максимально приближена к продакшену по конфигурации, данным и нагрузке. Используется для финального UAT и проверки развёртывания.
  • Продакшен (Production Env) — рабочая среда, доступная конечным пользователям. Тестирование здесь крайне ограничено и проводится осторожно (например, A/B-тесты).

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

  • Pre-Alpha — прототип с неполным функционалом и множеством ошибок. Используется для внутренней демонстрации идей.
  • Alpha — ранняя версия, тестируемая внутри компании. Функционал почти полный, но стабильность низкая.
  • Beta — практически готовый продукт, распространяемый среди ограниченного круга внешних пользователей для получения обратной связи.
  • Release Candidate (RC) — кандидат на релиз. Все известные критические ошибки исправлены. Проводится финальное регрессионное тестирование.
  • Release — финальная версия, официально выпущенная для всех пользователей.