26 апреля 2024

Блог

Тестирование

Автоматизация UI-тестирования на мобильных платформах

Рассказываем про плюсы и минусы UI-тестирования мобильных приложений.

Что такое UI Тестирование Мобильных приложений. 

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

В основании такой пирамиды лежат unit-тесты. Если говорить простым языком, то это тесты, проверяющие функционал модулей (зачастую просто классов) и не зависят ни от чего более. На втором уровне располагаются интеграционные тесты, которые могут ответить на вопрос, правильно ли работают готовые модули в рамках архитектуры системы. А в самой вершине находятся E2E (end-to-end) тесты. В отличие от основания пирамиды, где тестируются отдельные части системы, E2E – это тесты, которые взаимодействуют с системой через внешние интерфейсы.

Пирамида тестирования

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

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

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

Плюсы и минусы 

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

Итак, плюсы, т.е. что дает проекту применение автоматизированных UI-тестов: 

  • Позволяют автоматически проверить основную функциональность приложения. 
  • Позволяют выявлять ошибки не только в логике, но и в поведении приложения. 
  • Закрывают часть регрессионного тестирования. Т.е. за счет автоматизации снижают стоимость и увеличивают скорость регресса. Казалась бы – ну уменьшили регресс, меньше придется QA специалисту тыкать, в чем выгода? Но! Во-первых, автоматизация уменьшает показатель time-to-market и позволяет чаще и быстрее выводить версии продукта на рынок. А во-вторых, когда продукт уже большой и многофункциональный, позволяет не увеличивать количество QA-специалистов, что является уже постоянными и несокращаемыми, по сути, издержками в проекте (не проверять же мы приложение не можем, так ведь?) 
  • Повышают уровень покрытия проекта регулярными автоматическими проверками. А покрытие – это снижение рисков и гарантированное покрытием качество продукта.  

Но есть и некоторые минусы: 

  • Ресурсные затраты на создание и поддержку выше, чем у интеграционных и unit-тестов. И сильно выше, чем «один раз проверить вручную» (не даром они на вершине пирамиды). Именно поэтому имеет смысл автоматизировать проверку UI-тестами «стабильной» функциональности. А новые фичи и функциональность проверять в ручном режиме до тех пор, пока функциональность не станет стабильной и, по сути, не будет включена в ядро продукта или приложения. 
  • UI-тесты требуют времени и ресурса для поддержки в актуальном состоянии. Как ни крути, но даже интерфейсы стабильной функциональности дорабатываются, обновляются визуально, анализируется обратная связь от пользователей и вносятся улучшения 
  • Имеют ограничение, так как привязаны к элементам пользовательского интерфейса и могут «делать выводы» только на основе изменений в нём.  

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

  1. Они позволяют быстро проверить и гарантировать работоспособность всей критичной функциональности  
  2. Сделать это управляемо и без кратного увеличения команды тестирования 
  3. Провести проверку гарантированно «быстро», т.е. оставаясь в целевых сроках. Иногда это может быть автоматическая проверка «ночной сборки», иногда регресс перед релизом или смоук-тестирование выпущенной сборки на промышленном окружении.  

На круг это позволяет сделать ваше продукт на рынке более конкурентным – гибким и быстрым к изменениям. 

С теорией более-менее разобрались. Давайте заглянем под капот, чтобы понимать, что это из себя представляет для мобильных приложений на iOS и на Android. 

Как мы тестируем мобильные проекты в True Engineering 

Тестирование мобильных приложений – процесс иной, часто более сложный, чем тестирование web-приложений. При тестировании мобильных приложений необходимо учитывать, что приложение может быть запущено на разных версиях устройства и мобильной ОС, и при этом вести себя по-разному. Также в отличие от web-приложения, мобильное взаимодействует с некоторыми встроенными функциями смартфона – биометрия, камера, датчики. Дополнительными этапами проверки может быть тестирование приложения в условиях отсутствия стабильного интернет-соединения, севшей батарейки и режим энергосбережения и т.д. 

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

Android 

Для тестирования Android приложений мы используем «нативный» стек. Тесты пишем на Kotlin с помощью библиотеки Kaspresso. Данная библиотека содержит набор классов для удобного взаимодействия с элементами интерфейса, существенно упрощая написание сценария теста. С помощью этого же фреймворка собираются артефакты запуска теста, которые могут содержать как текстовый лог сценария, так и скриншоты ключевых точек прохождения теста, ошибочных ситуаций. Т.е. после прогона теста мы видим всё, что нужно для анализа. 

Код теста выглядит вот так: 

   {  

        step("1. Авторизация") { 

            scenario( 

                AuthorizeScenario(auth = TestData.auth) 

            ) 

        } 

 

        step("2. Перейти в профиль и открыть паспорт") { 

            HomeScreen.avatar.click() 

            ProfileDetailsScreen.editProfileButton.click() 

            EditProfileScreen.editPassportDataClick() 

        } 

 

        step("3. Установить фокус на поле \"Серия и номер\"") { 

            EditPassportScreen.seriesNumberFieldInput.click() 

        } 

 

        step("4. Нажать на плашку \"Сканировать документ\"") { 

            EditPassportScreen.scanDocumentButton.click() 

        } 

 

        step("5. Отсканировать файл из вложения") { 

            step("Выбрать фото из галереи") { 

                CameraScreen.fromGalleryButton.click() 

                StartFragmentScreen { 

                    pickPhotoButton.isVisible() 

                    idle(1_000) 

                    pickPhotoButton.click() 

                } 

 

                SelectFileScreen { 

                    clicksToPhoto() 

                    photoClick(TestData.file.resName) 

                } 

            } 

        } 

 

        step("Поля паспорта заполнились содержимым из отсканированного паспорта ${TestData.file.resFullName}") { 

            EditPassportScreen { 

                seriesNumberFieldInput.isVisible() 

 

                compareValue(seriesNumberFieldInput, TestData.passportData.seriesNumber) 

                compareValue(startDateFieldInput, TestData.passportData.issueDate) 

                compareValue(issuerCodeFieldInput, TestData.passportData.issuerCode) 

                compareValue(issuedByFieldInput, TestData.passportData.issuerBy) 

                compareValue(birthDateFieldInput, TestData.passportData.birthDate) 

            } 

        } 

    } 

В этом тесте мы выполнили несколько простых и стандартных для приложения шагов: 

  1. Открыли приложение 
  2. Авторизовались 
  3. Зашли в профиль и встали на поле заполнения паспорта 
  4. Вместо внесения руками нажали на управляющий элемент “сканировать документ” 
  5. Дополнительно проверили возможность загрузить фото паспорта из галереи. Часто ведь нет паспорта под рукой, но есть его фото. 
  6. Убедились, что распознавание прошло успешно и поля формы заполнились. 

Profit! 

iOS 

В продуктах для этой платформы используются средства Xcode, т.е “нативные” уже для платформы от Apple. Xcode предоставляет нам фреймворк XCTest, который мы используем для написания как unit, так и UI тестов. XCTest использует API специальных возможностей (Accessibility API) для доступа к элементам управления в вашей иерархии представлений и взаимодействия с ними. По сути, это средства разработки приложения, которые сделали удобными и для разработчиков тестов.

Код для проверки приложения для iPhone выглядит так: 

func testCheckForClaimRolledVision() { 

        feature("Отображение списка заявок (сокращенный/развернутый вид)") 

         

        let checkCellsForSwitchChanges = { [weak self] in 

            func cellID(for switchValue: Bool) -> String { 

                return switchValue ? InspectionUIElements.cellShort.rawValue : InspectionUIElements.cell.rawValue 

            } 

             

            guard let self else { return } 

            turnClaimSwitch(isOn: true) 

            app.tables.first.cells.toArray.forEach { XCTAssert($0.identifier == cellID(for: true)) } 

             

            turnClaimSwitch(isOn: false) 

            app.tables.first.cells.toArray.forEach { XCTAssert($0.identifier == cellID(for: false)) } 

             

            turnClaimSwitch(isOn: true) 

        } 

         

        step("Заявок 3 и меньше") { 

            showClaimsScreen(for: .user8) 

            XCTAssert(app.tables.first.cells.count < 3) 

            XCTAssert(!isClaimSwitchON) 

        } 

        step("Щелкнуть на тумблер \"Отобразить карточки списком\"") { 

            checkCellsForSwitchChanges() 

        } 

         

        back() 

        openMainTab() 

        logout() 

         

        step("Заявок более 3") { 

            showClaimsScreen(for: .user9) 

            XCTAssert(app.tables.first.cells.count >= 3) 

            XCTAssert(isClaimSwitchON) 

        } 

        step("Щелкнуть на тумблер \"Отобразить карточки списком\"") { 

            checkCellsForSwitchChanges() 

        } 

    } 

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

Прекрасно, тесты есть, мы их можем запускать сами или вставить в конвейер CI/CD. Но вот как обработать результатов десятков, а чаще сотней тестов? 

Визуализация и обработка результатов 

Для визуализации результатов на обоих платформах мы используем фреймворк Allure. Это специальный и довольно мощный open-source инструмент, нацеленный как на обработку и визуализацию результатов тестирования. Он предоставляет как сводную, общую информацию, так и может обогащать результаты тестов дополнительной информацией для анализа – логи, шаги тестов, временные метки (тайминги) и т.д. И плюс он интегрируется с конвейерами сборки и доставки (CI/CD) и трекинговыми платформами. А это значит, что он аккуратно вписывается в производственную инфраструктуру нашей компании и, при желании, компании заказчика. 

Отчет о прохождении теста выглядит вот так:

Отчет о прохождении теста

Платформа бесплатная и развивается сообществом. 

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

Заключение 

Работа над качеством продукта начинается с проработки концепции продукта и плана внедрения MVP и не заканчивается никогда. У нас в компании есть объединенный отдел тестирования и сопровождения. Это позволяет нам анализировать ошибки и найденные баги на всех стадиях производства продукта и его последующего промышленного сопровождения.  

Сегодня мы рассказали только о небольшом кусочке комплексного процесса обеспечения качества продуктов, которые мы создаем. Часто автотесты преподносятся как «модный и современный» инструмент. Мы с этим не спорим. Но, как и всё остальное, что мы используем в нашей работе, автотесты нацелены в первую очередь на получение качественного бизнес-результата в виде веб-решения или приложения и быстрому выводу этого решения на рынок. 

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