В программе может быть огромное количество функций и различных способов их использования. В идеальном мире, тестировщик может проверить все функции и все сценарии их применения. Например, фильтры по цене в интернет-магазине, вроде таких:
Если бы у нас было бесконечное количество времени, то мы могли бы проверить, как программа реагирует на ввод в фильтры всех возможных цифр (0, 1, 2, 3...), чисел (-10, 134, 0.877, 1e10...), слов (торт, mark, ONE, 시험, триста...), символов (@#&, +-=, {{...) и так далее. Возможно, нам и удалось бы таким образом отловить все баги, но, возможно, произошла бы ситуация из старого мема про тестировщиков:
Чтобы среди множества проверок, которые приходят нам в голову, выбрать самые критичные, составить грамотную стратегию тестирования, не упустить важные аспекты программы и избежать ненужных проверок нужно ориентироваться на 7 принципов тестирования:
1. Исчерпывающее тестирование невозможно
Как бы тщательно мы ни тестировали продукт, сколько бы времени и ресурсов ни потратили, сколько бы багов ни нашли и исправили, всё равно останется что-то, что мы могли упустить.
ПРИМЕР: рассмотрим игру с открытым миром, вроде Cyberpunk 2077, где игроки могут свободно перемещаться, взаимодействовать с окружающей средой, выполнять квесты и сражаться с врагами. В подобной игре существует огромное количество возможных действий и ситуаций: разная последовательность взаимодействий с персонажами, разнообразные маршруты, которые игрок может выбрать, множество комбинаций оружия, брони и навыков. Тестировщики должны проверить, как игра ведет себя во всех случаях. Однако количество возможных сценариев и их вариаций настолько велико, что даже при самых тщательных тестах невозможно охватить все комбинации. Даже после долгих месяцев тестирования всё равно может остаться ситуация, которая не была учтена, например, редкий баг, проявляющийся только при определенной последовательности действий.
Но это не означает, что тестирование бесполезно. Тщательный анализ требований, расстановка приоритетов, понимание предметной области, изучение поведения пользователей, применение техник тест-дизайна — всё это помогает повысить качество и обеспечить правильную работу программы в критически важных ситуациях.
2. Тестирование демонстрирует наличие багов, а не их отсутствие
Тестировщики могут найти баги в продукте, но не могут гарантировать что багов нет. Тестирование программы часто напоминает попытку «найти то, не знаю что». Мы не знаем заранее, как выглядит баг и где он может быть, пока не столкнемся с ним. Поскольку невозможно заранее определить, что искать, нельзя гарантировать, что этого нет.
ПРИМЕР: проводим тестирование мобильной игры, вроде "3 в ряд" и обнаруживаем, что при победе игрока ему не начисляются очки. Оформляем баг-репорт и передаем его разработчикам на исправление, баг исправлен, мы проводим ретест и убеждаемся, что баг больше не воспроизводится. Кажется, что всё в порядке, но мы не можем утверждать, что в игре больше нет багов. Например, может выясниться, что при выполнении определённой комбинации действий (закрыть приложение во время игры, отключить смартфон от интернета, затем снова открыть приложение, закончить и выиграть игру, затем вновь подключиться к интернету, но уже в другом регионе) этот баг все равно воспроизводится - баллы игроку не начисляются.
Как следует из первого принципа: тестировщик физически не может охватить все возможные ситуации и условия, в которых может работать программа. Тестировщик может выявить ошибки в наиболее вероятных сценариях и тем самым повысить качество продукта, но это не означает, что дефекты не проявятся в других, менее очевидных ситуациях.
3. Раннее тестирование экономит время и деньги
Эффективность тестирования возрастает, если оно начинается на более ранних этапах жизненного цикла продукта. Чем раньше обнаруживаются ошибки, тем меньше затрат требуется на их исправление. На этапе проектирования продукта легче устранить дефекты, так как исправление не потребует переделки продукта. Однако, если ошибка выявляется в уже созданной программе, это приводит к длительному и дорогостоящему процессу исправления, потере лояльности пользователей и убыткам компании.
ПРИМЕР: представим, что мы решили приготовить торт согласно стадиям жизненного цикла ПО: нашли рецепт, написали список ингредиентов, купили их в магазине, испекли торт, попробовали сами, накормили семью. На этапе составления списка продуктов, мы забыли внести в список муку. Получился не торт, а непонятно что, семья осталась голодной. Мы выяснили, что в торте нет муки уже потратив много времени и сил на поход в магазин и приготовление торта. Чтобы исправить эту ошибку, нам придется снова сходить в магазин и снова приготовить торт. Второй раз делать одно и то же не пришлось бы, если бы ошибка была выявлена на этапе составления списка покупок.
4. Кластеризация дефектов
Когда в определенной части программы обнаруживается несколько багов, это может указывать на наличие других багов в этом же участке. Такой сценарий требует особого внимания и более тщательного тестирования. Ошибки не возникают без причины, особенно если они сосредоточены в одном месте. Они могут быть следствием недостатка времени на разработку, плохо сформулированных требований, недостаточной квалификации разработчика или использования новой, сложной технологии, которую команда еще не освоила. В любом случае, обнаружение нескольких ошибок в одном участке программы — это сигнал к более детальной проверке, так как велика вероятность того, что есть и другие скрытые проблемы.
ПРИМЕР: представим, что мы тестируем мессенджер, вроде Telegram. Мы обнаружили, что:
- приложение автоматически закрывается, если пользователь меняет аватарку,
- чтобы добавить в профиле статус, нужно ввести его 2 раза,
- изменить пароль в профиле просто нельзя - выводится сообщение "Произошла ошибка".
Мы видим, что у всех этих багов есть нечто общее - они все связаны с изменением данных в профиле пользователя. Следуя принципу скопления дефектов, нам следует тщательно проверить все операции с редактированием данных пользователей. Скорее всего мы обнаружим еще несколько багов.
5. Тесты устаревают (парадокс пестицида)
Парадокс пестицида в тестировании напоминает проблему в сельском хозяйстве, когда постоянное использование одного и того же пестицида приводит к устойчивости вредителей. В тестировании это выражается в том, что повторное использование одних и тех же тестов может сделать их менее эффективными со временем, и новые ошибки остаются незамеченными. Чтобы избежать этой проблемы, важно регулярно обновлять чек-листы и тест-кейсы, привлекать новые ресурсы для тестирования и не забывать об исследовательском тестировании.
ПРИМЕР: продолжим пример с мессенджером. Предположим у нас есть регрессионые тесты на проверку профиля пользователя, в одном из них мы проверяем добавление аватарки. Мы сохранили картинку с котиком и каждый месяц, в рамках регресса, добавляем эту картинку в профиль, убеждаемся, что она отображается и думаем, что багов связанных с аватарками нет. Но технологии развиваются, камеры смартфонов становятся все мощнее, пользователи теперь делают селфи в разрешении 4К и пытаются загрузить их в свой профиль. Мессенджер выдает ошибку, пользователи недовольны и уходят в другой мессенджер. Если бы мы каждый месяц брали новую актуальную картинку, то смогли бы заметить баг раньше пользователей и сохранить их лояльность.
6. Тестирование зависит от контекста
Все программы имеют свои особенности: они предназначены для разных людей, используются в разных условиях, разрабатываются с применением разных языков программировани и технологий, решают разные задачи и преследуют разные цели. Все это важно для определения подхода к тестированию и организации работы тестировщиков. Простое копирование тестов из одного проекта в другой неэффективно, поскольку универсального подхода к тестированию не существует. Каждая программа требует индивидуального подхода.
ПРИМЕР: например, при тестировании сайта для онлайн-банкинга необходимо сосредоточиться на безопасности транзакций, точности отображения баланса, совместимости с различными браузерами и устройствами, а также на удобстве пользовательского интерфейса. В то время как для проверки мобильного приложения - навигатора важны проверки на точность определения местоположения, корректность расчёта маршрутов, интеграция с сервисами карт, а также отзывчивость при изменении маршрута.
7. Заблуждение об отсутствии дефектов(или отсутствие багов - это не цель создания продукта)
Независимо от того, насколько тщательно протестирован продукт и как много ошибок удалось выявить и исправить - это не гарантия его успеха. Считать, что тестирование обеспечит успешность программы, — это ошибка. Даже если тщательно протестировать абсолютно все функции и исправить все обнаруженные дефекты, это не гарантирует, что система будет удовлетворять потребности пользователей, помогать в достижении бизнес-целей или превосходить конкурентные продукты. Тестирование может улучшить качество продукта, но не может сделать его успешным и полезным для пользователей.
ПРИМЕР: как бы ни бы хороши телефоны BlackBerry с физической клавиатурой, прогресс не стоит на месте, появились iphone с сенсорным экраном и вытеснили BlackBerry. На пике своего успеха телефоны BlackBerry занимали 45% рынка, сейчас их доля составляет 0%,.