Какие проверки сайта стоит автоматизировать на Python, а какие пока оставить человеку
Лена работает тестировщиком в небольшом интернет-магазине канцтоваров. После каждого обновления она открывает корзину, добавляет блокноты, меняет количество и пересчитывает доставку. В понедельник разработчик менял поиск, в среду — фотографии товаров, но корзину Лена проверяет снова: изменения в одной части сайта иногда задевают другую.
Повторяющиеся действия можно поручить программе. Она откроет нужную страницу, заполнит поля и сравнит результат с тем, который должен получиться. Такую программу называют автотестом. Но сначала человеку нужно определить, что проверять, какие данные использовать и какой ответ считать правильным. Запись движений мыши сама по себе этого не объясняет.
На примере корзины посмотрим, как Лена проверит сумму заказа и стоимость доставки, а затем поручит программе повторять эти проверки. Отдельно выясним, почему программа иногда сообщает об ошибке только из-за того, что страница ещё не закончила пересчёт. Все товары, цены, правила и результаты в примере придуманы.
Сначала договоритесь, как должна работать корзина
Лена просит разработчика Андрея помочь с автоматизацией. Технически он может написать программу, которая добавит товар и нажмёт «Оформить». Но по успешному нажатию ещё нельзя понять, правильно ли магазин посчитал заказ. Поэтому они начинают с правил, которые подтвердил владелец магазина.
Для нашего примера условия такие:
- Один блокнот стоит 600 рублей, скидок и дополнительных сборов нет.
- Если стоимость товаров меньше 3 000 рублей, доставка стоит 300 рублей.
- Начиная с 3 000 рублей за товары доставка бесплатная. Стоимость доставки в этот порог не входит.
- В корзине можно указать только целое положительное количество. При нуле или отрицательном числе сайт объясняет ошибку и не позволяет оформить заказ.
По этим правилам два блокнота стоят 1 200 рублей, доставка — ещё 300, а итог — 1 500. Пять блокнотов стоят ровно 3 000 рублей, поэтому доставку прибавлять не нужно. Проверка пяти штук особенно полезна: она показывает, правильно ли работает само условие «начиная с 3 000».
Выбирать проверки, описывать ожидаемый результат и оформлять найденные ошибки вы научитесь на курсе «Тестировщик на Python» от Skillfactory. В программе есть ручное тестирование, а в направлении автоматизации на Python — работа с элементами страницы, проверками введённых данных и ожиданиями. Эти знания помогают сначала разобраться в поведении корзины, а затем поручить программе повторение уже понятных действий.
Лена отдельно записывает начальные условия: корзина пустая, нужный блокнот есть в наличии, цена не меняется во время проверки. Теперь Андрей понимает, с чего начать и с чем сравнить ответ сайта. Если завтра владелец изменит условия доставки, команда сначала обновит правило, а затем соответствующие проверки.
Выберите повторяющиеся проверки с понятным результатом
В первую очередь Лена хочет избавиться от пересчёта одних и тех же сумм после каждого обновления. У этих проверок есть подходящие для автоматизации свойства: они нужны регулярно, используют известные данные и заканчиваются ответом, который можно однозначно сравнить с ожидаемым.
Для начала она выбирает небольшой набор:
- Два блокнота: товары на 1 200 рублей, доставка 300, итог 1 500.
- Четыре блокнота: товары на 2 400 рублей, доставка 300, итог 2 700.
- Пять блокнотов: товары на 3 000 рублей, доставка бесплатная, итог 3 000.
- Нулевое количество: появляется понятное сообщение, оформление недоступно.
- Отрицательное количество: сайт также объясняет ошибку и не позволяет оформить заказ.
После изменения сайта эти проверки помогут заметить, что прежнее поведение нарушилось. Проверку того, что изменения не сломали ранее работавшие функции, называют регрессионным тестированием. Для Лены за термином стоит обычная задача: убедиться, что работающий вчера расчёт не сломался после сегодняшней доработки.
При этом новый экран оформления она сначала изучит сама. Понятно ли, куда вводить адрес? Видно ли, что доставка платная? Что происходит, если вернуться из оформления в корзину? Пока команда исследует поведение и уточняет требования, готовый список автоматических сравнений ещё не заменит эту работу.
Даже на знакомом экране остаются вопросы, которые полезно рассматривать шире заданного сценария. Например, автотест может подтвердить наличие сообщения об ошибке, но человек заметит, что длинная подсказка закрыла кнопку на узком экране. Часть подобных проверок тоже можно автоматизировать. Однако для этого сначала нужно решить, какие признаки программа должна оценивать.
Не заставляйте браузер заново проверять всю арифметику
Андрей замечает, что для проверки суммы не всегда нужно открывать сайт. Расчёт выполняет определённая часть программы: она получает количество блокнотов и возвращает итог. Её можно проверить отдельно, передав два, четыре или пять штук. Такие небольшие проверки обычно проще разобрать: если сумма неверная, не придётся сначала выяснять, открылась ли страница и нашлась ли кнопка.
Но отдельный расчёт не покажет, что видит покупатель. Программа может правильно вернуть 1 500 рублей, а страница — по ошибке оставить старую сумму. Поэтому Лена сохраняет и проверку через браузер: добавить два блокнота, дождаться пересчёта и сверить показанный итог. Два вида проверок отвечают на разные вопросы и дополняют друг друга.
Так не приходится открывать страницу и повторять весь путь покупателя ради проверки каждого отдельного расчёта. В статье о пирамиде тестирования Мартин Фаулер объясняет, почему набору автотестов полезны проверки отдельных частей программы, а не только действия через пользовательский интерфейс. Это ориентир для выбора проверок, а не требование выдержать определённую пропорцию любой ценой.
Чтобы записывать проверки на Python, Андрей может использовать pytest — инструмент, который запускает тесты и показывает, где результат не совпал с ожиданием. В начальном руководстве pytest такой принцип показан на небольших функциях. Для нашего магазина смысл проверки можно выразить коротким фрагментом:
def test_two_notebooks(): actual_total = order_total(quantity=2) assert actual_total == 1500
Здесь order_total — условное имя уже написанной функции расчёта магазина, её реализация в этом фрагменте не приведена. Проверка передаёт ей количество 2 и требует получить 1 500. Команда assert проверяет это равенство. Если функция вернёт 1 200, тест сообщит о расхождении: товары посчитаны, а доставка в итог не попала.
Ожидаемые 1 500 Лена получила заранее из согласованного правила. Если вместо этого взять число с проверяемой страницы и сравнить его с ним же, программа ничего полезного не выяснит. Правильный ответ должен иметь независимое основание, иначе тест может пройти даже при неверном расчёте: оба сравниваемых числа взяты из одного ошибочного результата.
Писать функции, обрабатывать ошибки и проверять программную логику вы сможете научиться на курсе «Python-разработчик» от Skillfactory. В нём также изучают базы данных и создание веб-приложений. Такая подготовка полезна, если вам интересно не только управлять браузером, но и разбираться, откуда берётся сумма заказа и как устроена программа, которая её рассчитывает.
Готовьте исходные данные для каждой проверки отдельно
Теперь Андрей пишет проверку корзины на сайте. Первая попытка выглядит удачно: программа добавляет два блокнота и видит 1 500 рублей. Но следующий тест должен проверить бесплатную доставку для пяти штук. Если он просто добавит ещё пять в ту же корзину, получится уже семь. Так тест с названием «Пять блокнотов» фактически проверит семь и не ответит на исходный вопрос о пороге бесплатной доставки.
Поэтому перед каждым тестом Андрей подготавливает известное состояние. Для проверки двух блокнотов нужна пустая корзина, в которую добавят два. Для проверки пяти — своя пустая корзина, в которую добавят пять. Следующий тест не должен зависеть от того, что случайно оставил предыдущий.
В учебном проекте это можно организовать через отдельные тестовые сеансы и подготовку данных. Сеанс здесь означает отдельное посещение сайта с собственным состоянием пользователя. Если корзина сохраняется в учётной записи на сервере, одного нового окна браузера недостаточно: нужно также подготовить данные этой записи. Поэтому Андрей проверяет, что корзина действительно пустая, прежде чем добавлять товары для следующего теста.
Лена заранее знает и свойства товара. Если другой сотрудник изменит цену блокнота во время запуска, автотест получит неожиданный итог. Для повторяемых проверок они используют отдельную тестовую копию магазина с согласованными товарами и запасом. В ней можно менять корзины, не мешая покупателям.
На этой копии отключены настоящие оплаты и отправка заказов на склад. Если позже Андрей добавит проверку оформления, она будет создавать только тестовый заказ. Так команда сможет свободно повторять сценарий, не создавая настоящие покупки и задания на отправку товаров.
Ждите нужного изменения страницы, а не просто истечения секунды
Суммы и начальные данные согласованы, но проверка всё равно иногда сообщает об ошибке. Лена запускает её снова, и она проходит. Выясняется, что после изменения количества страница получает новый расчёт не мгновенно. В один раз ответ приходит за 0,6 секунды, в другой — за 1,8. Эти времена тоже условные: они нужны только для объяснения.
В первой версии Андрей написал: изменить количество, подождать одну секунду, прочитать итог. При быстром ответе всё успевает обновиться. При медленном программа читает прежнюю сумму и сообщает о расхождении, хотя новая появляется чуть позже. Причина в том, что команда задала время паузы, но не связала проверку с окончанием пересчёта.
Андрей меняет порядок: программа ждёт завершения пересчёта, а затем читает новый итог и сравнивает его с ожидаемым. Признак завершения Андрей выбирает с учётом работы страницы: одного наличия суммы недостаточно, ведь на экране могла остаться прежняя. Для примера они устанавливают предельное ожидание в три секунды. Если пересчёт закончился раньше, проверка продолжается сразу. Если не закончился за это время, тест сообщает о проблеме и сохраняет сведения для разбора.
Для управления браузером из Python можно использовать Selenium. В его руководстве по ожиданиям разобрана именно такая трудность: код проверки может перейти к следующему действию раньше, чем страница будет готова. Инструмент позволяет ждать заданного условия. Разработчику остаётся выбрать условие, которое действительно связано с проверяемым действием.
При этом трёхсекундное ожидание в нашем примере не становится требованием к любому сайту. Если магазин обязан пересчитывать корзину быстрее, нужно отдельно проверять это требование. Нельзя увеличивать время до тех пор, пока исчезнет неприятное сообщение, и считать вопрос решённым.
Лена также проверяет, что программа обращается к нужному полю. Поиск «второй кнопки на странице» сломается, если дизайнер добавит перед ней ещё одну. Лучше, когда тест находит элемент по согласованному устойчивому признаку, а команда понимает, какой именно элемент требуется. Тогда перестановка блоков не обязательно потребует переписывать всю проверку.
Разбирайте нестабильность, даже если повторный запуск прошёл
Проблема с ожиданием показывает, почему одного повторного запуска недостаточно. Он помогает сравнить попытки, но сам по себе не объясняет, что произошло. Если Лена будет нажимать «Повторить» до первого успешного результата, команда увидит зелёный отчёт и потеряет сведения о прежних сбоях.
Результат, который при неизменном коде то проходит, то нет, называют нестабильным. Причина может находиться в самой проверке, в подготовке данных, в условиях запуска или в магазине. Например, неверный расчёт тоже способен появляться лишь иногда. Поэтому списывать каждое такое сообщение на «опять автотест» рано.
В разборе нестабильных тестов в Google Джон Микко описывает, как команда выявляла и отслеживала такие проверки. Он также отмечает ограничение временного исключения теста из обязательного запуска: это может скрыть настоящую ошибку программы. Для нашего магазина вывод практический — сохранять причину и задачу на исправление, даже если мешающую проверку пришлось временно запускать отдельно.
Для поиска причины Лена и Андрей сравнивают попытки. Был ли выбран тот же товар? Сохранилась ли цена? Была ли корзина пустой? Что показывала страница в момент ошибки? Если не открылся сам тестовый магазин, проверка расчёта вообще не состоялась. Такой запуск нельзя записывать как подтверждение правильной суммы.
Когда причина найдена, Андрей исправляет соответствующую часть: подготовку корзины, ожидание, поиск элемента либо работу сайта. Затем они проверяют, что сценарий проходит повторно и по-прежнему замечает известное нарушение. Проверка, которая всегда проходит, но не замечает заведомо неверную сумму, бесполезна.
Сохраняйте сообщение, по которому понятно, что исправлять
Предположим, разработчик случайно изменил условие бесплатной доставки: теперь она действует только при сумме товаров больше 3 000 рублей. Для пяти блокнотов магазин начал прибавлять 300 рублей и показывать итог 3 300. Здесь ожидание страницы не поможет: расчёт закончился, но дал неправильный результат.
Лена должна получить не просто красную строку «Тест не пройден», а понятный отчёт. В нашем примере в нём будут:
- Условия: пустая корзина, блокнот по 600 рублей, количество 5.
- Действия: добавить товар, установить количество и дождаться завершения пересчёта.
- Ожидание: товары на 3 000 рублей, доставка 0, итог 3 000.
- Фактический результат: доставка 300, итог 3 300.
- Подтверждение: снимок страницы и сведения о версии магазина, в которой выполнялась проверка.
С такой записью Андрей сможет повторить проблему и найти ошибочное условие. Если отчёт показывает только неудачное нажатие кнопки, из него ещё не следует, что сломалась доставка. Поэтому действия программы, данные и результат важно связать в одном описании.
Подключайте автотесты к обычной работе команды
После исправления Лена хочет повторять выбранные проверки при следующих обновлениях. Если запускать их умеет только Андрей со своего ноутбука, команда снова зависит от его свободного времени. Поэтому он сохраняет код вместе с проектом и описывает, как подготовить данные, запустить проверки и прочитать результат.
Позже запуск можно добавить к подготовке новой версии: разработчик отправляет изменения, рабочая система выполняет согласованные проверки и показывает отчёт. Для Лены это означает, что ей не нужно при каждом обновлении отдельно просить Андрея запустить пять выбранных проверок корзины. Но кто-то всё равно должен разбирать неудачные запуски. Если никто не отвечает за разбор ошибок, уведомления могут оставаться без реакции, а неисправности — без исправления.
Проверки нужно поддерживать и после запуска. Если владелец утвердил новый порог бесплатной доставки, ожидаемые суммы следует пересчитать по новому правилу. Если Андрей перестроил страницу, может понадобиться обновить способ поиска элементов. А если тест обнаружил нарушение прежних требований, менять ожидаемый ответ под ошибку нельзя.
Для первого проекта достаточно нескольких полезных проверок
Начинающему не обязательно сразу автоматизировать весь магазин. Можно взять отдельный учебный проект и пройти небольшой, но законченный путь:
- Описать цену, условия доставки и допустимое количество товара.
- Проверить несколько случаев вручную и записать ожидаемые суммы.
- Автоматизировать расчёт и один понятный сценарий через браузер.
- Подготовить отдельную корзину для каждого запуска и ожидать завершения пересчёта.
- Намеренно внести ошибку в учебный расчёт, убедиться, что тест её заметил, затем вернуть правильное поведение.
- Оформить отчёт и инструкцию, по которой другой человек сможет повторить проверку.
В описании проекта укажите, какие сценарии уже проверяются, а какие пока остались за его пределами. Успешная проверка пяти блокнотов ничего не говорит о восстановлении пароля или оплате. Честная граница полезнее обещания «сайт полностью протестирован»: по ней видно, на какие результаты команда может опираться.
После такого проекта проще понять, какая часть вам интереснее. Тестировщик выбирает случаи, исследует поведение и объясняет найденные расхождения. Для автоматизации ему также нужно программировать и поддерживать проверки. Python-разработчик глубже занимается самой логикой приложения, но тоже использует тесты, чтобы проверять свои изменения. Другие направления обучения можно посмотреть в каталоге курсов для старта в IT.
Планировать проверки и переходить от ручного тестирования к автоматизации вы сможете на курсе «Тестировщик на Python». Писать программы, разбираться в расчётах и серверной логике — на курсе «Python-разработчик».