Данная статья является переводом статьи UI Testing in Swift with XCTest framework. В этой статье мы не  говорить о важности тестирования в целом, но я хочу поговорить о тестировании пользовательского интерфейса. Одним из очевидных преимуществ тестирования пользовательского интерфейса по сравнению с модульным тестированием является возможность писать тесты пользовательского интерфейса, даже если у вас есть пахнущая и глубоко связанная кодовая база. В этой статье мы рассмотрим, как писать тесты пользовательского интерфейса как для проектов на основе SwiftUI, так и для UIKit. Тест пользовательского интерфейса - это программный способ проверить, правильно ли работает конкретный пользовательский поток в вашем приложении. Например, вы можете написать тест пользовательского интерфейса, имитирующий поведение пользователя при добавлении товара в корзину покупок и оформлении заказа. Xcode предоставляет нам фреймворк XCTest, который мы используем для написания как unit, так и UI тестов. XCTest использует API специальных возможностей ( Accessibility API ) для доступа к элементам управления в вашей иерархии представлений и взаимодействия с ними. Как вы, наверное, знаете, UIKit и Swift UI предоставляют поддержку специальных возможностей "из коробки". Вот почему вы можете легко использовать XCTest framework для написания тестов пользовательского интерфейса для ваших приложений, написанных на UIKit или SwiftUI. Давайте напишем наш первый пользовательский тест для простого представления, отображающего сообщение. Чтобы создать новую цель тестирования пользовательского интерфейса, перейдите в меню Xcode File -> New -> Target -> UI Testing bundle. Теперь мы можем написать наш первый пользовательский тест. Чтобы написать тест пользовательского интерфейса, мы должны создать класс Swift, который расширяет XCTestCase. Xcode запускает каждый метод, начинающийся со слова test, как отдельный тест. Как вы можете видеть в примере выше, мы переопределяем метод setUp.  Xcode запускает этот метод перед каждым тестом в тестовом примере. Это отличное место для начальной настройки перед каждым тестированием. Здесь мы запускаем приложение с нуля перед каждым тестированием пользовательского интерфейса.  XCTest предоставляет нам класс XCUIApplication в качестве посредника для приложения, указанного в целевой настройке “Target Application”. Мы можем получить доступ к нашему приложению и взаимодействовать с ним через экземпляр класса XCUIApplication. В нашем простом тесте мы проверяем, что наше приложение отображает статический текст с определенным сообщением. XCUIApplication предоставляет множество свойств для запроса в иерархии представлений. Вы можете получить доступ к кнопкам, меткам, таблицам, слайдерам, переключателям и другим представлениям, расположенным в вашей иерархии представлений. Основным требованием для доступа к представлению является включенный режим доступности (accessibility). По умолчанию поддержка специальных возможностей (accessibility) включена для любого представления. Как вы можете видеть, мы можем получить доступ ко всем необходимым представлениям, используя синтаксис сабскриптов. Мы передаем строку, чтобы найти элемент управления в иерархии представлений. Xcode пытается найти представление, соответствующее лейблу специальных возможностей  (accessibility label) или идентификатору специальных возможностей (accessibility identifier). Надписи, кнопки и переключатели используют заголовки в качестве меток специальных возможностей (accessibility labels) из коробки. Но нам все равно нужно вручную установить идентификаторы специальных возможностей для таких представлений, как UITableView и UICollectionView. Чтобы узнать больше о свойствах запроса XCUIApplication, ознакомьтесь с документацией по протоколу XCUIElementTypeQueryProvider. Фреймворк XCTest предоставляет нам множество функций для взаимодействия с представлениями. Вы можете нажимать, дважды нажимать, смахивать, сжимать и поворачивать (tap, double‑tap, swipe, pinch and rotate) виды. Чтобы узнать больше о действиях, которые предоставляет нам XCTest, ознакомьтесь с документацией для класса XCUIElement. Теперь мы можем взаимодействовать с нашим приложением, используя фреймворк XCTest. Давайте напишем более интересный тест, который проверяет процесс входа в систему. Предположим, что у вас есть представление входа в систему, написанное в Swift UI. Это могло бы выглядеть примерно так: Здесь у нас есть Content View , которое представляет LoginView и заменяет его сообщением, как только пользователь вошел в систему. В приведенном выше примере у нас есть тест, который проверяет процесс входа в систему. Пожалуйста, обратите внимание, что здесь мы используем функцию waitForExistence. Он ожидает определенного тайм-аута и возвращает значение false, если элемент не отображается. С другой стороны, он возвращает значение true, как только элемент появляется на экране. UI тесты выполняются медленнее, чем модульные тесты, потому что им необходимо запустить все приложение целиком. Вот почему мы обычно стараемся написать как можно больше модульных тестов и охватить основные пользовательские потоки тестами пользовательского интерфейса. Но все же есть способ повысить производительность, отключив анимацию во время выполнения тестов пользовательского интерфейса. Здесь мы проверяем, запускается ли приложение в рамках теста пользовательского интерфейса, используя аргументы командной строки. В предыдущих примерах мы задавали аргументы запуска во время выполнения тестов пользовательского интерфейса, и именно так мы можем проверить аргументы и подготовить наше приложение к тестам пользовательского интерфейса. Например, мы можем сбросить состояние приложения, удалив настройки пользователя по умолчанию, данные цепочки для ключей и очистив локальную базу данных. Тесты пользовательского интерфейса - это отличный способ проверить наиболее важные пользовательские потоки в вашем приложении. XCTest framework предоставляет очень приятный и простой API, который мы можем использовать для непосредственного написания сложных тестов. Вы можете написать свой первый пользовательский тест просто взаимодействуя с пользовательским интерфейсом вашего приложения.  iOS Developer