Тесты как код: хранение ручных тест-кейсы в Git и работа с ТестОпс
Тесты как код: хранение ручных тест-кейсы в Git и работа с ТестОпс
В Открытой мобильной платформе используется инструмент ТестОпс, который позволяет решать много разных задач — хранение тестов, запуск автоматизированных и ручных сценариев, анализ результатов, составление отчетов по тестированию и многое другое.
Ручные тесты могут быть кодом
Ручные тест-кейсы нужны не только для таблиц и интерфейсов, их можно хранить в Git как код. И не просто хранить, а интегрировать с ТестОпс. Почему это удобно? Потому что это делает управление тестами более эффективным, а данные — безопасными и надёжными.
Почему было решено хранить ручные тесты в Git?
Однажды сервер, где был развернут ТестОпс, дал сбой, и часть данных пропала. Это побудило команду к поиску надёжного способа их хранения. Автотесты были восстановлены, условно, за пару дней, а вот с ручными тестами всё было намного хуже: на их восстановление ушли месяцы работы нескольких человек.
Это стало уроком. Появилась идея: если автотесты отлично чувствуют себя в Git, то почему бы не хранить там и ручные тест-кейсы? При использовании Git не только данные будут в большей безопасности, но и появится целый набор бонусов:
- Стабильность: никакой потерянной работы.
- Контроль: каждая правка на виду.
- Удобство массового рефакторинга: нужно поменять общий шаг? Пара строк в коде — и готово.
И самое главное: Git учит людей расти профессионально. Многим тестировщикам, проводящим ручные проверки, интересно двигаться в сторону автоматизации. Работа с Git и IDE — это отличный способ подтянуть навыки и понять азы кодинга. А ведь в будущем такие знания могут стать билетом в мир автоматизации!
Как были перенесены тесты из ТестОпс в Git?
Встает вопрос: как забрать всё накопленное в ТестОпс и аккуратно сложить в Git? Ответ прост: написать свой скрипт для выгрузки. Без него это было бы похоже на попытку собрать пазл без картинки на коробке.
Итак, что сделал скрипт?
-
Подключение к API ТестОпс. Заранее известно, какие наборы тестов (suites) нужно перенести. Через API скрипт запрашивал информацию и поэтапно проходился по всем тестам. В процессе пришлось учитывать правила RQL (Request Query Language), который задаёт формат и синтаксис для работы с данными. Этот подход позволил чётко структурировать запросы, обеспечив точность и полноту извлекаемой информации:
def get_all_suite_allure_ids(suite: str) -> list: """Получить все id указанного Suite.""" ids = [] page = 0 params = { "projectId": project_id, "rql": f'cf["Suite"] = "{suite}"', "deleted": False, "page": str(page), "size": "20" } response: Response = requests.get( "https://omp.allure.pro/api/rs/testcase/__search", params=params, headers=headers, json=json_data ) totalPages = response.json()["totalPages"] print(f"Найдено страниц: {totalPages}") while page < totalPages: params["page"] = str(page) response: Response = requests.get( "https://omp.allure.pro/api/rs/testcase/__search", params=params, headers=headers, json=json_data ) cases_list = response.json()['content'] for case in cases_list: if "id" in case: id = case["id"] ids.append(id) page += 1 print(f"Found: {len(ids)}") return ids
-
Сохранение в файлы. Внутри этого файла тесты превращались в понятный, поддерживаемый код. Сохранялись все метки (labels), слои (layers) и имена тестов:
@allure.id('23290') @allure.title('Сообщения сортируется по дате') def test_23290(): """ Предварительное условие: 1. Пользователь успешно аутентифицирован системой (выполнен UC Аутентификация пользователя в EMM или AppStore); 2. Устройство создано в системе и находится в группе устройств, в группе есть политика, назначаем правило. """ with allure.step('[Phone] Нажать "Получить обновления" в клиенте "Аврора Центр"'): with allure.step('Обновления получены'): pass with allure.step('[EMM] Добавить любое правило в политику'): with allure.step('Правило добавлено'): pass with allure.step( '[Phone] Повторно нажать "Получить обновления" в клиенте "Аврора Центр"' ): with allure.step('Обновления получены'): pass with allure.step('[Phone] Обратить внимание на сортировку сообщений'): with allure.step('Сообщения сортируются по дате/времени'): pass
Примечание: не стоит удивляться отсутствию отступов в документации функции. Такое решение было принято намеренно, о чём можно прочитать далее в разделе “Сложности? Конечно, без них никуда”.
-
Чистота и порядок. Логика настроена так, чтобы скрипт автоматически устранял дубли и корректно обрабатывал сложные сценарии. А если попадалась какая-то экзотика, например, нестандартный формат шага, он просто сигнализировал.
-
Унификация. Когда скрипт закончил работу, все тесты в Git стали выглядеть единообразно: структура, формат, соглашения. Теперь они выглядят так, будто всегда хранились в коде, а не в интерфейсе ТестОпс:
@allure.id('23290') @allure.title('Сообщения сортируется по дате') def test_23290(): """ Предварительное условие: 1. Пользователь успешно аутентифицирован системой (выполнен UC Аутентификация пользователя в EMM или AppStore); 2. Устройство создано в системе и находится в группе устройств, в группе есть политика, назначаем правило. """ with allure.step('[Phone] Нажать "Получить обновления" в клиенте "Аврора Центр"'): with allure.step('Обновления получены'): pass with allure.step('[EMM] Добавить любое правило в политику'): with allure.step('Правило добавлено'): pass with allure.step( '[Phone] Повторно нажать "Получить обновления" в клиенте "Аврора Центр"' ): with allure.step('Обновления получены'): pass with allure.step('[Phone] Обратить внимание на сортировку сообщений'): with allure.step('Сообщения сортируются по дате/времени'): pass
Сложности? Конечно, без них никуда
Не всё прошло гладко, были нюансы. Вот самые яркие:
-
"Автотест" по умолчанию. Оказывается, ТестОпс считает, что всё, загружаемое через Git, — автоматизированное. Чтобы обозначить, что тест-кейс ручной, пришлось искать, как это "сказать" в коде. Достаточно просто указать метку:
allure.label('ALLURE\_MANUAL', 'true')
-
Документация и Python: битва за форматирование. Python рекомендует форматировать отступы в документации. Казалось бы, что может пойти не так? Но ТестОпс воспринимает такие отступы как цитаты. В итоге пришлось нарушать правила Python, чтобы описания выглядели нормально:
@allure.id('23290') @allure.title('Сообщения сортируется по дате') def test_23290(): """ Предварительное условие: 1. Пользователь успешно аутентифицирован системой (выполнен UC Аутентификация пользователя в EMM или AppStore); 2. Устройство создано в системе и находится в группе устройств, в группе есть политика, назначаем правило. """
-
Неудобство обновления ручных тестов. Есть рабочее расписание: запуски закрываются через неделю, так удобнее для регресса. Пришлось автоматизировать процесс: в pipeline был добавлен шаг с закрытием запусков через api принудительно:
Ревью: новая жизнь ручных тестов
Автоматизированные тесты почти всегда проходят ревью. Было решено, что ручные тесты заслуживают такого же внимания.
Теперь каждый ручной тест-кейс проходит цикл проверки:
- Тест-кейс отправляется на ревью.
- Коллеги анализируют его, дают обратную связь и предлагают улучшения.
- Только после одобрения тест попадает в мастер.
Этот подход помогает повысить качество тестов. В результате команда уверена, что каждый тест понятен и не вызовет вопросов при прохождении.
Git: новые возможности для ручных тестов
Хранение ручных тестов в Git принесло несколько важных преимуществ:
- История изменений. Всегда можно увидеть, кто и что менял. Это особенно важно для крупных проектов, где над тестами работает большая команда.
- Масштабируемость. Изменить шаг во всех кейсах? Добавить новую функциональность? Всё это легко сделать через код.
- Надёжность. Даже если с ТестОпс что-то случится, все данные останутся в Git.
- Коллаборация. Git позволяет обсуждать спорные моменты, вносить коллективные изменения и улучшать тесты.
- Интеграция и единство. Не проводится чёткая граница между “ручниками” и “автоматизаторами”. Важно, чтобы каждый мог развиваться в обеих областях. Ручные тестировщики получают возможность погружения в автоматизацию и развитие своих навыков (в данном случае использование Git и IDE), а автоматизаторы — шанс стать более гибкими и креативными, участвуя в тест-дизайне и ручном тестировании. Этот подход позволяет создавать сильную команду, где каждый чувствует себя важным звеном.
Стоит ли игра свеч?
Конечно, не всё так идеально. Некоторые вещи пришлось делать через костыли. Но результат стоит того. Удалось объединить удобство работы с кодом и гибкость ТестОпс, получив инструмент, который работает на команду, а не наоборот.
Тесты как код — это не просто тренд. Это способ делать свою работу быстрее и надёжнее.