Вместо 100 Запусков Приложения — Один Автотест, Или Как Сэкономить Qa-Инженеру 20 Лет Жизни

Всем привет, меня зовут Евгений Демиденко.

Последние несколько лет я занимаюсь разработкой автоматизированной системы тестирования игр в Pixonic. Сегодня я хотел поделиться нашим опытом разработки, поддержки и использования такой системы на проекте War Robots. Для начала давайте разберемся, что мы автоматизируем с помощью этой системы.

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

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

.

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



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

Позвольте мне привести вам некоторые цифры.

На данный момент для War Robots написано более 600 UI-тестов и около 100 основных тестов.

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

Мы используем платформы Android и iOS — всего в парке 12 устройств.

Разработкой системы и ее поддержкой занимаются два программиста, а написанием и анализом тестов занимается один QA-инженер.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

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

Для основного игрового процесса и тестов проверки сборки мы используем встроенное решение от Unity — Unity Test Tools. Для написания и анализа отчетов после этих тестов используется Allure Test Report от Яндекса, а также TeamCity — как система непрерывной интеграции для создания приложения, развертывания сервера и запуска тестов.

Мы используем репозиторий Nexus и базу данных PostgreSQL для хранения наших артефактов.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



Как создавать, анализировать и запускать тесты

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

Итак, мы написали тест и зафиксировали его в определенной ветке нашего тестового репозитория.

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

Теперь запускаем тест, ждем некоторое время и получаем результат.

Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

При этом было запущено 575 тестов, из них 97% оказались успешными.

На прохождение всех тестов у нас ушло около трех часов.

Для сравнения, те же тесты, если проводить их вручную, потребовали бы не менее 50 часов непрерывной работы.

Так что же случилось с 3% неудачных тестов? Открываем конкретный тест и видим сообщение о том, что при сопоставлении скриншотов произошла ошибка.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

Затем открываем скриншот, который был в тот момент на устройстве, и видим, что красными пикселями отмечены области, не соответствующие оригиналу.

Для сравнения приведем и его.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

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



Выглядит круто.

Зачем все это нужно?

Некоторое время назад на проекте War Robots нам нужно было провести один небольшой рефакторинг.

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

В ходе тестирования мы обнаружили один интересный нюанс: скорострельность пулеметов напрямую зависела от FPS. Обнаружить такой баг при ручном тестировании было бы невозможно: во-первых, из-за особенностей расчета сетевых повреждений на проекте, а во-вторых, из-за того, что приложение War Robots достаточно хорошо оптимизировано и на тот момент было запущено на у всех устройств примерно одинаковый фпс - 30 фпс.

Конечно, были небольшие отклонения, но их было недостаточно, чтобы при ручном тестировании заметить увеличение урона от стрелкового оружия.

Тогда мы спросили себя: сколько этих ошибок у нас еще есть и сколько может появиться в ходе рефакторинга? Так как мы хотели не уменьшать количество тестов, а наоборот увеличивать его, так как мы планировали большие обновления и увеличение количества контента, мы не хотели расти по горизонтали и увеличивать количество QA-отдела.

сотрудники.

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



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



Какие инструменты мы используем?

Когда мы только начинали автоматизировать тесты, мы в первую очередь обратили внимание на встроенное на тот момент в Unity решение — Unity Integration Test Tools. Мы написали на нем несколько UI и ядерных тестов, завершили начатый ранее рефакторинг и остались этим довольны, поскольку решение уже работало, а значит, наши предположения были верны, и нам нужно было двигаться дальше.

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

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

Appium принял эту концепцию и добавил драйверы iOS и Android в дополнение к существующим веб-драйверам в Selenium: они используют собственные среды тестирования для каждой из этих платформ.

Поскольку в Unity нет нативных элементов пользовательского интерфейса, а есть только один элемент пользовательского интерфейса, в котором отображается картинка, нам пришлось добавить в Appium UnityDriver, который позволяет работать с иерархией сцен, получать объекты сцены и многое другое.

К этому моменту на проекте уже появился QA-инженер, дело пошло вперед, и количество тестовых скриптов стало значительно расти, которые мы постепенно автоматизировали.

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

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



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

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

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

После дальнейших нововведений и доработок архитектура всей системы стала выглядеть вот так.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

Берем сборку War Robots, берем свои тесты, которые находятся в отдельном репозитории, добавляем туда некоторые параметры запуска, позволяющие настроить запуск тестов в каждом конкретном случае, и отправляем все это агенту TeamCity на удаленном ПК.

Агент TeamCity запускает наши тесты, передает им параметры сборки и запуска «Роботов», после чего тесты начинают работать и самостоятельно «общаться» с устройствами, которые зашиты на агент TeamCity: устанавливать на них сборки, запускать их, выполнять определенные скрипты, удалять сборки, перезапускать приложение и так далее.

Поскольку тесты и само приложение запускаются на физически разных устройствах — мобильном телефоне и Mac mini — нам нужно было реализовать связь между нашим фреймворком, API War Robots и API Unity. Мы добавили в приложение небольшой UDP-сервер, который получает команды от фреймворка и общается с API приложения и Unity через обработчики.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

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

В частности, распараллеливание для ускорения работы, правильный выбор устройств и скриншотов, связь со сборкой.

После завершения тестов наш фреймворк должен сохранить все сгенерированные артефакты и сформировать отчет.

Советы по выбору устройств

Отдельно хотелось бы обратить внимание на выбор устройств для тестирования.

Важное внимание следует уделить хабам.

Если вы хотите провести тесты на своих устройствах, особенно на устройствах Android, они потребуют много ресурсов.

Концентраторы должны обеспечивать необходимую мощность для используемых устройств.

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

У нас есть такие хабы, и это очень неудобно.

Если вы хотите запустить регрессионное тестирование пользовательского интерфейса и протестировать логику на устройствах, не используйте разные устройства.

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

Отдельный вопрос об использовании облачных ферм.

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



Отчет о тестировании

После завершения тестов мы создаем отчет Allure, который включает в себя все артефакты, созданные во время выполнения нашего теста.

Основная «рабочая лошадка» для анализа произошедшего и выявления причин падения во время теста — логи.

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

Мы разделяем логи на системные (более подробные) и QA-логи (более компактные и удобные для анализа).

Также мы собираем системные логи с устройств (например, logcat) и логи из приложения Unity. Во время тестовых сбоев мы также делаем снимок экрана, чтобы понять, что происходило на устройствах в момент сбоя, записываем видео, чтобы понять, что происходило до сбоя, и стараемся собрать информацию о состоянии устройства, такие как пинги с наших серверов и информация ifconfig, чтобы понять, имеет ли устройство IP. Вы удивитесь, но если вы запустите приложение вручную 50 раз, все будет хорошо, а если вы запустите его 50 тысяч раз в автоматическом режиме, вы обнаружите, что интернет на устройстве может пропасть, а во время теста он пропадет. не быть ясным.

была ли связь до и после падения? Также собираем список процессов, заряд батареи, температуру и вообще все, что попадется под руку.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



В чем преимущества скриншотов и видео?

Некоторое время назад наш QA-инженер предложил, помимо снятия скриншотов при возникновении сбоя, в определенных местах тестов сравнивать эти скриншоты с шаблонами, которые есть в нашем репозитории.

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

То есть одним тестом мы могли проверить и логику, и визуальную часть.

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

Но это осознанный шаг: мы умеем все это правильно анализировать, поэтому рискнули добавить такой функционал.

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



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

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

Именно это мы и сделали с тестовой локализацией.

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

-UPS. up's, и в этот момент создаются скриншоты.

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

Да, скриншоты все равно нужно смотреть, но это гораздо быстрее, чем вручную просматривать все экраны на устройстве.

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

Более того, иногда непонятно, что произошло всего за несколько мгновений до сбоя теста.

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

С помощью таких видеороликов очень удобно отслеживать сбои и зависания приложений.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



Что еще может наша система?

Некоторое время назад мы получили запрос от отдела тестирования QA на разработку инструмента для сбора метрик во время ручного плейтеста.

Для чего это? Это нужно для того, чтобы после ручного плетеста QA-инженеры могли дополнительно проанализировать поведение FPS и потребления памяти в приложении, одновременно просматривая скриншоты и видео, отражающие происходящее на этом устройстве.

Разработанная нами система работала следующим образом.

QA-инженер запустил на устройстве War Robots, включил запись сессии playbench - нашего аналога gamebench, - провел плейтест, затем нажал «завершить сессию playbench», сформированный отчет сохранялся в репозитории, после чего инженер с данными этого плетеста мог зайти на свою рабочую машину и посмотреть отчет: какие были падения FPS, какое потребление памяти, что происходило на устройстве.

Мы также автоматизировали запуск тестов проекта War Robots, по сути просто обернув существующие тесты в автоматический запуск.

Результатом бенчмарков обычно является одна цифра.

В нашем случае это обычно средний FPS по бенчмарку.

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

Мы запускаем так называемый тест проверки сборки для каждого запроса на включение.

Вы можете запускать их как на устройствах, так и в редакторе Unity, чтобы ускорить проверку логики.

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



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни



И другие полезные функции

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

Для нового проекта Pixonic Dino Squad мы разработали систему, в которой QA-инженер мог провести плейтест вместе с ботами, чтобы не ждать коллег, а самому проверить любую гипотезу.

Наш QA-инженер, в свою очередь, попросил добавить возможность не просто играть с ботами, но и чтобы боты могли играть друг с другом.

Таким образом, мы просто запускаем приложение, и в этот момент бот начинает играть с другими ботами.

Причём всё взаимодействие сетевое, с реальными серверами; компьютер просто играет вместо игроков.

Все это завернуто в тесты и сессию playbench с триггерами для ночных запусков.

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

Утром приходит QA-инженер и может посмотреть, какие плейтесты проводились и что в них происходило.

Также стоит отметить проверку утечки текстур.

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

Соответственно, в бою не должно быть атласов, которые используются в гараже, а когда мы выходим из боя, в памяти не должны оставаться текстуры, которые использовались в бою.

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

В случае с War Robots это время не существенно, но оно постоянно растёт, потому что добавляется новый контент, и качество этого контента улучшается — но мы можем держать этот параметр под контролем и всегда осознавать его значение.



Вместо заключения

В заключение хотелось бы обратить внимание на те проблемы, которые у нас есть, о которых мы знаем и которые хотели бы решить в первую очередь.



Вместо 100 запусков приложения — один автотест, или как сэкономить QA-инженеру 20 лет жизни

Первое и самое болезненное — изменения пользовательского интерфейса.

Поскольку мы работаем с «черным ящиком», мы не встраиваем в приложение War Robots ничего, кроме своего сервера — то есть тестируем все так же, как тестировал бы QA-инженер.

Но каким-то образом нам нужен доступ к элементам сцены.

И мы находим их, используя абсолютный путь.

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

К сожалению, сейчас мы ничего не можем с этим поделать.

Конечно, есть некоторые решения, но они приносят свои дополнительные проблемы.

Вторая большая проблема – инфраструктура.

Как я уже сказал, если вы запустите свое приложение вручную 50 раз, вы не заметите большую часть проблем, которые возникнут, если вы запустите свое приложение 50 тысяч раз.

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

В частности, нам необходимо определить, почему тесты не прошли: было ли это из-за сбойной логики, какой-то проблемы с инфраструктурой или по какой-либо другой причине.

Проблем с бюджетными устройствами очень много: на них не устанавливаются сборки, отваливается интернет, устройства зависают, вылетают, не включаются, быстро разряжаются и так далее.

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

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

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

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.