Введение
Автоматизация тестирования в мире САПР – это вызов, который невозможно переоценить. Инженеры, архитекторы и проектировщики создают сложнейшие модели, а разработчики ПО ломают голову, чтобы их инструменты работали без сбоев. Но чем мощнее становится программное обеспечение, тем сложнее его тестировать. Проверять САПР вручную – всё равно что искать иголку в стоге сена, который кто-то ежедневно переворачивает. Мы быстро поняли, что такой подход не работает. Поэтому решили изменить систему и построить свою.
Нашей целью было – создать решение, которое избавит от рутины, ускорит тестирование и обеспечит его стабильность, а также будет легко масштабируемым. Одна из главных проблем – повторяющиеся проверки. Тестировать одни и те же функции вручную после каждого обновления – долго, монотонно и неэффективно. Можно что-то упустить, ошибиться и просто устать. Мы пошли дальше: наша система не просто заменяет тестировщиков на скрипты, а полностью автоматизирует весь процесс – от запуска тестов до анализа результатов.
Мы использовали Python, VirtualBox, JSON и PowerShell, чтобы тесты запускались в чистой среде, результаты были понятны всем, а интеграция с разработкой максимально простой. Архитектура гибкая, удобная и кроссплатформенная.
В этой статье мы расскажем, каким образом мы создали систему, как эта система работает и какие задачи она позволяет решить.
Архитектура системы автотестирования
Автоматизированное тестирование — это непросто набор скриптов. Для того чтобы оно было удобным, надёжным и масштабируемым, мы разделили систему на несколько частей. Каждая из которых отвечает за свою задачу, а вместе они делают процесс тестирования понятным и управляемым.
Компоненты системы
Запись действий – сохраняет действия пользователей и превращает их в тесты.
Запуск тестов – выполняет пользовательские сценарии в программе и далее фиксирует их результаты.
Тестовая среда – использует виртуальные машины для максимально чистого и точного тестирования.
Описание архитектуры
Система работает через основное приложение, которое запускает тесты и управляет всеми модулями.
Принципы работы:
Модули. Каждый блок (запись действий, запуск тестов, анализ результатов) работает отдельно, что упрощает поддержку.
Гибкость. Тесты хранятся в JSON, их можно менять без правок в коде.
Параллельное выполнение. Для ускорения тестирования была использована многопоточная обработка, которая запускает несколько тестов одновременно. Вместо стандартного threading.Thread был использован ThreadPoolExecutor, который управляет потоками, контролирует выполнение и обрабатывает ошибки. Таким образом тестирование проходит быстрее, процессор используется эффективнее а ошибки в одном тесте не мешают другим.
Структура работы движка тестирования
Инициализация тестового окружения
Подготовка рабочего каталога и очистка результатов предыдущих тестов.
Загрузка тестовых сценариев из JSON-файлов.
Запуск тестов
Последовательное выполнение действий из сценариев (эмуляция кликов, ввод данных, работа с UI).
Управление процессами тестируемого ПО, отслеживание его состояния.
Логирование каждого шага теста.
Обработка сбоев и перезапуск тестов
Мониторинг зависаний и ошибок с помощью анализа логов и сравнения скриншотов.
Автоматическое завершение и перезапуск тестируемого приложения при сбоях.
Фиксация и анализ результатов
Сравнение полученных результатов с эталонными данными.
Генерация отчётов в текстовом и HTML-формате.
Отправка уведомлений о результатах тестов.
Взаимодействие между модулями
Процесс тестирования начинается с записи действий пользователя. Для этого используется инструмент, который отслеживает взаимодействия с интерфейсом – клики, ввод текста, перемещение курсора. Эти данные сохраняются в формате JSON, что позволяет легко управлять тестами и редактировать их без изменения кода.
Движок выполнения тестов загружает сценарии и последовательно воспроизводит зафиксированные действия в тестируемом ПО. Он взаимодействует с приложением через эмуляцию пользовательского ввода и отслеживает, насколько фактическое поведение совпадает с ожидаемым.
Чтобы тесты были воспроизводимыми, мы используем виртуальные машины. Каждое тестирование запускается в чистой среде, что исключает влияние внешних факторов. VirtualBox позволяет автоматически поднимать тестовые окружения, загружать нужные сборки ПО и управлять процессом тестирования.
Автоматизация тестирования в разных средах
Система построена так, чтобы её можно было адаптировать под разные платформы и условия тестирования. Пока основной фокус – Windows-среда, но закладываются возможности для Linux. За счёт использования PowerShell и Python тесты можно запускать в различных конфигурациях, управляя установкой ПО, настройкой окружения и анализом логов.
Этот подход обеспечивает гибкость, позволяет легко вносить изменения и масштабировать тестирование на новые продукты. Следующий шаг – разбор того, как именно тесты создаются, загружаются и исполняются в нашей системе.
Управление тестами и выполнение сценариев
Чтобы тестирование работало как надо, важно не просто написать автотесты, а грамотно их организовать. Они должны храниться в удобном формате, легко изменяться и запускаться без лишних настроек. Мы сделали систему, где все тесты оформлены одинаково, а процесс их выполнения чётко выстроен.
Формат и работа с JSON-файлами тестов
Чтобы система была гибкой и удобной, мы храним тесты в формате JSON . Это не просто так, а потому, что это формат, в котором удобно редактировать тесты и с которым удобно анализировать их, это лучше всего поддерживает автоматизированные процессы.
Использование JSON даёт несколько преимуществ:
Лёгкость редактирования. Мы получаем возможность редактировать тесты без правки движка тестирования
Читаемость. Тесты хороши как людям, так и машинам.
Структурирование. Cценарии делятся просто: есть шаги, ожидаемые результаты шагов, и разные параметры.
Структура JSON-файлов
Пример Json-файла:
{ "test_name": "Открытие файла", "steps": [ {"action": "click", "target": "menu_file"}, {"action": "click", "target": "open"}, {"action": "input", "target": "filename", "value": "test_file.dwg"}, {"action": "click", "target": "open_button"} ], "expected_result": "Файл открыт без ошибок"}
Шаги теста содержат в себе следующие параметры:
action — тип действия.
target — элемент интерфейса.
value — дополнительные параметры, например, данные для ввода.
expected_result — ожидаемый результат.
Система тестирования обрабатывает JSON-файлы при запуске тестов. Она:
Парсит JSON-файл – система загружает данные JSON, формирует список действий.
Интерпретирует шаги – каждое действие из списка преобразуется в соответствующую команду.
Выполняет команды – клик, ввод или что-либо еще.
Проверяет результат – пройден тест или нет.
Такой способ создания тестов позволяет тестировщикам легко создавать новые сценарии, менять уже готовые, не трогая код движка автотестирования.
Интерпретация и выполнение тестов
Когда тест загружается в систему, движок тестирования пошагово выполняет все действия, имитируя работу реального пользователя. Это включает:
Инициализацию среды – система загружает тестовое окружение и готовит файлы.
Выполнение действий – клик, введение текста, работа в меню.
Проверку результатов – фактическое состояние системы сравнивается с ожидаемым результатом.
Логирование – шаги каждого теста записываются в лог-файл.
Поскольку тесты реализуются без присутствия человека, их результаты могут проанализированы с большой степенью точности.
Имитация пользовательских действий
Наш движок тестирования способен эмулировать все основные действия пользователя. Это в том числе:
Работа с мышью – клики, наведение, перемещение курсора.
Ввод с клавиатуры – набор текста, применение сочетаний клавиш.
Ожидание загрузки интерфейса – обработка временных задержек, паузы перед следующими шагами.
Для эмуляции пользовательского ввода мы используем результаты библиотек pyautogui и keyboard:
pyautogui управляет мышью и взаимодействиями с экраном, позволяя кликать, двигать курсор и манипулировать элементами графического интерфейса.
keyboard обеспечивает обработку клавиатурных ввода, в том числе отправку текста, нажатие горячих клавиш и эмуляцию сложных комбинаций клавиш.
Обработка пауз и задержек
САПР-программы – это не просто обычные приложения, где клики работают мгновенно. Здесь важно учитывать:
Время загрузки интерфейса.
Обеспечение сложных операций: открытие крупных файлов или перестроение модели.
Время ожидания перед следующим действием.
Для избегания случая ложных срабатываний система использует фиксированные паузы, которые задаются в конфигурации теста. Также для отдельных мест, где минимальное время загрузки элемента или операции точно известно, есть паузы перед следующим шагом теста. Так тестирование становится более стабильным, но в то же время труднее настраивается под разные сценарии использования. Далее в следующем параграфе мы рассмотрим, как система обрабатывает ошибки и сбои.
Обнаружение и обработка сбоев
Невозможно избежать проблем при тестировании — зависания, крэши, различного рода баги могут сломать самый продуманный тесткейс. Чтобы это происходило как можно реже и чтобы после каждого теста надо было туда не забираться с фонариком, мы разработали собственную систему автоматического детектирования и анализа проблем, которая помогает находить их и устранять без участия человека.
Автоматическое выявление ошибок
Главная задача — не просто заметить, что тест не прошёл, а понять, почему это произошло. Для этого используются несколько методов:
Сравнение скриншотов. Когда программа вдруг разучилась открывать файлы или элементы интерфейса неожиданно исчезают, тесты сравнивают ниспадающий скриншот с эталоном. Если разница превышает определенный порог, что-то стало отклоняться. Эта функция также может использоваться в сравнениях между разными браузерами или разными платформами.
Анализ логов. Тесты оставляют после себя след в виде логов — записи о любых ошибках, сбоях и подозрительных вещах. Система сама анализирует эти записи и поймет, когда тест действительно сломался, а когда это случайный недосчет.
Отслеживание зависаний. Если приложение вдруг “задумалось” и не отвечает в течение определенного времени, то система не будет ждать вечно: он перезапустит процесс и зафиксирует сбой.
Мониторинг состояния приложения
Для контроля за стабильностью работы тестируемого ПО используется отдельный механизм, который отслеживает зависания и аномалии в поведении системы. В его основе лежит:
Анализ отклика окна – если окно приложения не реагирует на ввод или зависает, это фиксируется как потенциальный сбой.
Логирование критических событий – при обнаружении зависаний система записывает все доступные данные о процессе: загрузку CPU, использование памяти, статус окон и ошибки в логе.
Проверка активности процесса – если процесс неожиданно завершился или перешёл в неотвечающее состояние, это расценивается как критическая ошибка.
Сравнение скриншотов
Еще один важный метод обнаружения ошибок — сравнение внешнего вида приложения до и после запуска теста. Для этого система применяет алгоритм, который:
Делает скриншоты экрана в ключевые моменты теста.
Сравнивает их с образцовыми изображениями.
Находит расхождения, с учетом допустимых отклонений . Например, небольших изменений, связанных со сглаживанием шрифтов, тенями и т.д.
Если они превышают заданный порог, тест считается неудавшимся.
Это метод позволяет обратить внимание на неожиданные изменения в интерфейсе, вызванные ошибками в коде.
Перезапуск тестируемого ПО при сбоях
Все сбои не равноценны. Некоторые ошибки — всего лишь случайность. Это может быть перегрузка системы, сетевой лаг, временный сбой. Чтобы не порождать ложные тревоги тестам был добавлен механизм перезапуска:
Каждый тест будет запущен заново, если программа зависла, или тест не закончился в выделенное время.
Перед повторным тестированием среда максимально очищается: удаляются временные файлы, среда перезапускается и создаются новые условия тестирования.
Если такая ошибка происходит несколько раз подряд в одном и том же географическом расположении, то это уже не случайность, а реальная проблема, которую можно решить только путем вмешательства со стороны разработчика.
Для этого специально используемый скрипт, который:
Завершается работа приложения которое зависло.
Очищает временные файлы, связанные с тестами.
Перезапускает тестируемое ПО в чистом состоянии.
Фиксируя момент сбоя в логах .
С помощью автоматического перезапуска ПО мы позволяем работе тестов проходить дальше, даже при неожиданных сбоях, что обеспечивает стабильность работы тестирования.
Интеграция с логированием и анализом результатов
Интеграция с логированием и анализом результатов. Чтобы анализ сбоев не перетекал именно в гадание на кофейной гуще, система также самостоятельно формирует отчёты по каждому сбою. В этих отчётах присутствует следующее:
Подробное описание ошибки.
Скриншоты до и после возникновения сбоя.
Куски логов с ключевыми ошибками.
Система дополнительно выводит информацию среде тестирования — версию ПО, основные настройки, параметры системы.
Это позволяет разработчикам сразу определиться с причиной сбоя и не тратить часы на поиск проблемы.
Система автоматической обработки сбоев сводит к минимуму влияние случайных факторов и упрощает диагностику проблем. Благодаря такому подходу автотесты не просто фиксируют ошибки, а помогают разработчикам быстрее их исправлять.
Инфраструктура тестирования
Для обеспечения стабильности работы автотестов важно, чтобы эти тесты запускались в одинаковых условиях. Если запускать тесты на разных машинах с различными настройками, можно не получить стабильных результатов. Поэтому для решения этих проблем вся тестовая инфраструктура строится на виртуальных машинах.
VirtualBox позволяет пересоздавать чистую среду перед каждым тестовым запуском. Виртуальные машины запускаются с образами, где заранее прописано что установить, скачать, и что уже установлено. Можно быть уверенным, что тесты запускаются в чистой среде, и случайные изменения не повлияют на его результаты.
Перед запуском тестирования система автоматически подготавливает окружение:
Удаление временных файлов и кэша предыдущих вариантов тестов.
Обновление конфигурации и подгрузка новых сборок ПО.
Запуск необходимых сервисов и получение тестовых данных.
Управление виртуальными машинами
Специальные скрипты автоматизируют работу тестовой инфраструктуры с помощью управления работой виртуальных машин, их стартом, распределением ресурсов между ними и запуском тестов в изолированной среде.
Настройка окружения и запуск тестов
По заданному расписанию система загружает готовые образы и разворачивает тестовые стенды
Выполняется настройка всех параметров среды - экран, язык, профиль пользователя
В подготовленном окружении запускается тестируемый продукт и начинается прогон тестов
Управление памятью и процессорами в VirtualBox
Память и количества процессорных ядер виртуальных машин настраиваются динамически в зависимости от текущей нагрузки.
Для оптимальной работы было задействовано заранее созданная конфигурация, здраво балансирующие между собой сложность тестов, производительность и затраты ресурсов системы.
Работа в headless-режиме
Тесты выполняются без рендеринга графического интерфейса, что снижает общие нагрузки на систему, и позволяет ускорить процессы.
Ручное вмешательство не требуется. Загрузка, остановка и т. д. происходят через API VirtualBox.
Если была изменена только часть приложения и требуется проверка его работоспособности, она обновляется, а виртуальная машина снова загружает новый билд. Этой схеме удалось обеспечить гибкость тестирующего процесса и не сделать его зависимым от любых изменений на основной машине разработчика.
Анализ результатов тестирования
Запустить тесты - это только полдела. Важно еще понять, что пошло не так, если тест упал. Поэтому мы проверяем результаты со всех сторон - смотрим логи, сравниваем как выглядит программа до и после, проверяем, что система ведет себя как надо.
Методы проверки и фиксации ошибок
Каждый тестовый сценарий содержит множество логических критериев, по которым система оценивает прохождение их. :
Сравнение скриншотов — анализирует изменения интерфейса и обнаруживает отклонения от стандартных изображений.
Проверка логов — оценивает, какие ошибки дала система во время выполнения теста, и выделяет их.
Контроль файловых изменений — проверяет, создаются или изменяются ли нужные файлы и их содержимое, а также, изменяется ли их размер.
Анализ времени выполнения — выделяет запаздывания или зависания работы тестируемого программного обеспечения.
Если тест не прошел, система сразу сохраняет всю картину происходящего, чтобы позже мы могли найти причину неудачи.
Генерация отчетов
Все результаты тестов собираются в понятные отчеты. В них вы найдете:
Что тестировали и как прошла проверка.
Если возникли сбои - все детали с логами и скриншотами.
Разбор причин ошибок - будь то проблемы с интерфейсом, загрузкой файлов или системные неполадки.
Мы гибко подходим к формату: можем сделать как простой текстовый файл, так и наглядную веб-страницу с изображениями проваленных тестов. Это помогает быстрее находить и исправлять ошибки.
Передача результатов
У нас все настроено так, чтобы команда быстро узнавала о проблемах:
Как только тесты завершаются, каждый в команде получает письмо. И разработчики сразу видят, где нужно что-то поправить
А если нужно копнуть глубже, все отчеты лежат в общей папке. Там можно глянуть, как тесты проходили раньше и что изменилось
Мы не просто собираем ошибки - мы видим, как программа себя ведет с каждым обновлением. Это реально помогает сделать её стабильнее и лучше. Кстати, часто именно через эти отчеты находим места, где можно что-то улучшить.
Перспективы развития системы
Наша система автотестов уже неплохо работает, но есть куда расти.
Первым делом хотим научить тесты подстраиваться под меняющийся интерфейс. Сейчас система умеет записывать и повторять действия, но приходится переписывать сценарии при каждом изменении дизайна.
Еще подключим систему к Jenkins и GitLab. Тогда тесты будут запускаться сами после каждого обновления кода. Так быстрее поймем, если что-то сломалось.
Пока работаем только с Windows, но добавим и Linux. Это нужно для импортозамещения и упростит настройку DevOps.
Сделаем поиск ошибок умнее - пусть система сама анализирует логи, находит странности в работе программы и создает тикеты в баг-трекере.
Ну и конечно, сделаем интерфейс на Qt попроще, чтобы с системой мог работать любой человек, даже без технической подготовки.
В общем, хотим сделать инструмент, с которым будет удобно работать каждый день.
Заключение
В статье мы не можем рассказать, где именно разработали эту систему - компания просит держать это в секрете. По той же причине нельзя показать скриншоты. Но думаю, наш опыт и подходы к автоматизации тестов будут полезны всем, кто работает над похожими задачами.
Разработчики: Толмачев Кирилл, Ларина Татьяна, Вараксин Максим, Чернолеций Кирилл, Трушкова Мария, Вяткин Роман.
Комментарии (6)
Anton_Menshov
18.02.2025 16:37Я так полагаю, что тестирование путем кликов сделано так как среда САПР не поддерживает запросы через API (или API примитивно и не дает доступ для полной конфигурации)? Или речь идет именно о тестировании GUI?
Babaji Автор
18.02.2025 16:37У нас все тесты работают через интерфейс, потому что в САПР без этого никак. Тут важно не только проверить, что команды отрабатывают, но и как все выглядит - особенно когда работаешь с 2D/3D моделями. Многие вещи просто нельзя проверить через API - как модель крутится, как инструменты работают, как выглядят настройки. Поэтому мы решили пойти путем эмуляции действий пользователя - так можно все проверить, включая графику.
Anton_Menshov
18.02.2025 16:37Понимаю. Просто хочу отметить, что при разработке САПР стоит разделять тесты самого САПР (по максимуму через API, хороший САПР имеет хороший API), GUI (кнопочки, комбобоксы, и т.д.), рендеринг (как выглядит) и экспорт.
Эмуляция действий пользователя - хороша для проверки GUI и немного для рендеринга. Остальные вещи, в идеальном мире САПР, тестируют через API. Проблема в том, что API во многих САПРах страдает либо отсутствием, либо плохой архитектурой, либо половинчаностью.Babaji Автор
18.02.2025 16:37Ответ:
Да, вы совершенно правы — в идеальном мире API для САПР должно закрывать все потребности тестирования. Но у нас ситуация такая, что оно, к сожалению, не охватывает весь функционал, особенно если говорить про рендеринг, работу с 2D/3D-моделями и визуализацию.
Поэтому мы идем через эмуляцию действий пользователя: это помогает не просто проверить интерфейс, но и убедиться, что сама система — взаимодействие с моделью, отрисовка, поведение инструментов — работает как надо. По сути, мы воспроизводим реальный сценарий использования, чтобы ничего не упустить.
Если бы API давало полный контроль над этими штуками, мы бы, конечно, с радостью на него опирались. Но пока оно не тянет, особенно в части рендеринга и динамики инструментов.
Dotarev
То, что вы сделали, звучит здорово.
Один вопрос. С одной стороны, запись скриншотов и их контроль. С другой стороны - "Тесты выполняются без рендеринга графического интерфейса". Это как сочетается?
Babaji Автор
Виртуальные машины действительно работают без вывода графического интерфейса на физический монитор (headless-режим), однако это не мешает нам брать скриншоты. Виртуализация даёт доступ к видеобуферу приложения, поэтому система сохраняет изображения напрямую оттуда, без необходимости фактического отображения интерфейса на экране пользователя.