[Разработка под iOS, Swift, Тестирование мобильных приложений] Погружение в автотестирование на iOS. Часть 3. Жизненый цикл iOS приложения во время прогона тестов
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Привет, хабр!В этой статье я расскажу про жизненый цикл iOS приложения во время прогона тестов, а в частности про:
- Предусловия и постусловия в ui-тестах;
- Запуск/завершение работы приложения;
- Запуск стороних приложений;
- Сброс permissions;
- Определение состояния приложения.
Предусловия и постусловия в ui-тестахВ классе с автотестами мы можем кофигурировать предусловия и постусловия используя следующие методы:
- Переопределить метод класса setUp(), чтобы установить предусловия для всех тестов в классе(выполняется перед первым тестом в классе);
- Переопределить метод setUpWithError(), чтобы установить предусловия и обработать ошибки перед запуском каждого теста;
- Переопределить метод setUp(), чтобы установить предусловия перед запуском каждого теста в классе;
- Объявить addTearDownBlock(_:) внутри своего тесты, чтобы выполнить очистку необходимых условий в рамках прохождения теста;
- Переопределить метод tearDown(), чтобы выполнить очистку после каждого теста в клаcсе
- Переопределить метод tearDownWithError(), чтобы выполнить очистку после каждого теста в клаcсе и обработать ошибки;
- Переопределить метод класса tearDown(), чтобы выполнить очистку после того как все тесты в классе завершаться.
Пример объявления и использования методов отображен в коде ниже:
//Source: developer.apple.com
class SetUpAndTearDownExampleTestCase: XCTestCase {
override class func setUp() { // 1.
// This is the setUp() class method.
// It is called before the first test method begins.
// Set up any overall initial state here.
}
override func setUpWithError() throws { // 2.
// This is the setUpWithError() instance method.
// It is called before each test method begins.
// Set up any per-test state here.
}
override func setUp() { // 3.
// This is the setUp() instance method.
// It is called before each test method begins.
// Use setUpWithError() to set up any per-test state,
// unless you have legacy tests using setUp().
}
func testMethod1() throws { // 4.
// This is the first test method.
// Your testing code goes here.
addTeardownBlock { // 5.
// Called when testMethod1() ends.
}
}
func testMethod2() throws { // 6.
// This is the second test method.
// Your testing code goes here.
addTeardownBlock { // 7.
// Called when testMethod2() ends.
}
addTeardownBlock { // 8.
// Called when testMethod2() ends.
}
}
override func tearDown() { // 9.
// This is the tearDown() instance method.
// It is called after each test method completes.
// Use tearDownWithError() for any per-test cleanup,
// unless you have legacy tests using tearDown().
}
override func tearDownWithError() throws { // 10.
// This is the tearDownWithError() instance method.
// It is called after each test method completes.
// Perform any per-test cleanup here.
}
override class func tearDown() { // 11.
// This is the tearDown() class method.
// It is called after all test methods complete.
// Perform any overall cleanup here.
}
}
На картинке ниже отображена последовательность выполнения методов:
Запуск/завершение работы приложенияЕсли мы хотим запустить/завершить приложение, мы можем легко сделать это с помощью метода запуска или завершения:
// Запускаем приложение
XCUIApplication().launch()
// Завершаем работу приложения
XCUIApplication().terminate()
Если мы хотим запустить приложение с определенными аргументами или переменными окружения, которые были настроены в основном приложении, мы можем запустить приложение с launchArgument или launchEnvironment. Более подробно об аргументах и переменных окружения можно почитать здесь.
let app = XCUIApplication()
// Добавляем аргумент для запуска приложения
app.launchArguments.append("-debugServer")
// Добавляем переменную окружения для запуска приложения
app.launchEnvironment = ["inAppPurchasesEnabled":"false",
"inAppAdsEnabled":"false"]
app.launch()
Также это можно сделать через тест-план. Во вкладке Configuration разделе Arguments будут два поля:
- Arguments Passed on launch — сюда добавляем необходимые аргументы для запуска нужного состояния приложения;
- Environment variables — сюда добавляем необходимые переменные окружения для запуска нужного состояния приложения.
Более подробно о тест-планах можно прочитать в этой статье.Запуск стороних приложенийБывают ситуации, когда нужно запустить стороннее приложение. Например, Safari для проверки диплинков. Это можно сделать в рамках прохождения теста или на старте приложения. Для этого нужно знать bundle id приложения и передать его в качестве аргумента в XCUIApplication.Информация об доступных bundle id можно найти на сайте apple.Пример кода для запуска приложения по bundle id:
// Запускаем safari
XCUIApplication(bundleIdentifier: "com.apple.mobilesafari").launch()
// Во время прохождения теста открываем safari
XCUIApplication(bundleIdentifier: "com.apple.mobilesafari").activate()
Сброс permissionsНа WWDC 2020 Apple представили возможность в тестах сбрасывать permissions. Это удобная функция, если вам нужно протестировать разные состояния экрана, завязанные на permissions. Важно, что метод доступен на симуляторах с версией iOS выше или равно 13.4.Список permissions для сброса, можно посмотреть в перечислении — XCUIProtectedResource:
@available(iOS 13.4, *)
public enum XCUIProtectedResource : Int {
// All platforms
case contacts = 1
case calendar = 2
case reminders = 3
case photos = 4
case microphone = 5
case camera = 6
case mediaLibrary = 7
case homeKit = 8
// macOS-specific resources
// iOS Family-specific resources
case bluetooth = -1073741824
case keyboardNetwork = -1073741825
case location = -1073741826
}
Пример как отключить permissions доступа к контактам в рамках теста:
override func setUpWithError() throws {
if #available(iOS 13.4, *) {
application.resetAuthorizationStatus(for: .contacts)
} else {
throw XCTSkip("Required API is not available for this test.")
}
}
В коде выше мы сбрасываем доступ к контактам в предусловии, если симулятор с версией iOS выше или равно 13.4. Если же нет, мы пропускам тест в прогоне.Состояния приложенияБывают ситуации, когда нужно понять, в каком состоянии приложение находилось во время прогона тестов.У приложения есть несколько состояний, которые можно получить во время прохождения теста:
public enum State : UInt {
case unknown = 0 // Текущее состояние приложения неизвестно
case notRunning = 1 // Приложение не запущено
case runningBackgroundSuspended = 2 // Приложение работает в фоновом режиме, но приостановлено
case runningBackground = 3 // Приложение работает в фоновом режиме
case runningForeground = 4 // Приложение работает
}
Представим ситуацию, что нам нужно нажать на кнопку home на iPhone 5s и проверить, что приложение перешло в состояние foreground.Пример реализации такого кейса:
// Нажимаем на текущем симуляторе кнопку home
XCUIDevice.shared.press(.home)
// Делаем явное ожидания, чтобы состояния приложение обновилось и мы перешли на экран home симулятора
Thread.sleep(forTimeInterval: 5)
// Проверяем что состояние приложения - runningForeground
XCTAssertEqual(XCUIApplication().state, .runningForeground)
Самое важное:
- Вы можете конфигурировать предусловия и постусловия ваших тестов, используя методы setUp() и tearDown();
- Запустить приложения, зная его bundle id;
- Если в приложении есть аргументы или переменные окружения, их можно добавить перед прогоном тестов;
- Сбрасывать состояния пермишенов вашего приложения можно на симуляторах версии iOS выше или равно 13.4.
В следующей заключительной статье по погружению в iOS-автоматизацию мы расскажем: что такое ожидания в ui-тестах, для чего они нужны, какие бывают, и приведем пример, как написать эффективные ожидания для ваших тестов.Навигация по статьям:
- Погружение в автотестирование на iOS. Часть 1. Как работать с accessibilityidentifier объектов
- Погружение в автотестирование на iOS. Часть 2. Как взаимодействовать с ui-элементами iOS приложения в тестах
===========
Источник:
habr.com
===========
Похожие новости:
- [Информационная безопасность, Тестирование веб-сервисов] «Осторожно, печеньки!»: советы начинающим тестировщикам в сфере безопасности
- Проблема с загрузкой Linux на Intel NUC7PJYH, всплывшая после обновления BIOS 0058
- [Системное администрирование, IT-инфраструктура, DevOps] Что вам нужно знать, если вы поменяете nginx на envoy: впечатления спустя два года
- [SQL, Хранилища данных, Веб-аналитика, Управление продуктом] Как мы в IVI используем массивы в ClickHouse для подсчета продуктовых метрик
- [Карьера в IT-индустрии, Лайфхаки для гиков, Удалённая работа] Один рабочий день QA
- [Анализ и проектирование систем, Управление разработкой, Agile] ИТ-разработка на примере строительства дома: тонкая грань
- [Тестирование веб-сервисов, Тестирование мобильных приложений] Видео с Kolesa QA Meetup 3.0: QAцентризм, подготовка данных к тестам и независимые моки
- [Информационная безопасность, Антивирусная защита, IT-инфраструктура] Приглашаем к бета-тестированию Dr.Web Enterprise Security Suite 13.0
- [Информационная безопасность, Тестирование мобильных приложений, Исследования и прогнозы в IT, IT-компании] Clubhouse в Китае: безопасны ли данные? Исследование SIO (перевод)
- [Информационная безопасность, Разработка под iOS, Монетизация мобильных приложений] Google ввела ярлыки конфиденциальности в сервис Gmail для iOS
Теги для поиска: #_razrabotka_pod_ios (Разработка под iOS), #_swift, #_testirovanie_mobilnyh_prilozhenij (Тестирование мобильных приложений), #_ios, #_testirovanie (тестирование), #_avtomatizatsija (автоматизация), #_mobile_testing, #_qa, #_mobile_automation, #_qa_automation, #_xcuitest, #_blog_kompanii_vivid_money (
Блог компании Vivid Money
), #_razrabotka_pod_ios (
Разработка под iOS
), #_swift, #_testirovanie_mobilnyh_prilozhenij (
Тестирование мобильных приложений
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:00
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Привет, хабр!В этой статье я расскажу про жизненый цикл iOS приложения во время прогона тестов, а в частности про:
//Source: developer.apple.com
class SetUpAndTearDownExampleTestCase: XCTestCase { override class func setUp() { // 1. // This is the setUp() class method. // It is called before the first test method begins. // Set up any overall initial state here. } override func setUpWithError() throws { // 2. // This is the setUpWithError() instance method. // It is called before each test method begins. // Set up any per-test state here. } override func setUp() { // 3. // This is the setUp() instance method. // It is called before each test method begins. // Use setUpWithError() to set up any per-test state, // unless you have legacy tests using setUp(). } func testMethod1() throws { // 4. // This is the first test method. // Your testing code goes here. addTeardownBlock { // 5. // Called when testMethod1() ends. } } func testMethod2() throws { // 6. // This is the second test method. // Your testing code goes here. addTeardownBlock { // 7. // Called when testMethod2() ends. } addTeardownBlock { // 8. // Called when testMethod2() ends. } } override func tearDown() { // 9. // This is the tearDown() instance method. // It is called after each test method completes. // Use tearDownWithError() for any per-test cleanup, // unless you have legacy tests using tearDown(). } override func tearDownWithError() throws { // 10. // This is the tearDownWithError() instance method. // It is called after each test method completes. // Perform any per-test cleanup here. } override class func tearDown() { // 11. // This is the tearDown() class method. // It is called after all test methods complete. // Perform any overall cleanup here. } } Запуск/завершение работы приложенияЕсли мы хотим запустить/завершить приложение, мы можем легко сделать это с помощью метода запуска или завершения: // Запускаем приложение
XCUIApplication().launch() // Завершаем работу приложения XCUIApplication().terminate() let app = XCUIApplication()
// Добавляем аргумент для запуска приложения app.launchArguments.append("-debugServer") // Добавляем переменную окружения для запуска приложения app.launchEnvironment = ["inAppPurchasesEnabled":"false", "inAppAdsEnabled":"false"] app.launch()
Более подробно о тест-планах можно прочитать в этой статье.Запуск стороних приложенийБывают ситуации, когда нужно запустить стороннее приложение. Например, Safari для проверки диплинков. Это можно сделать в рамках прохождения теста или на старте приложения. Для этого нужно знать bundle id приложения и передать его в качестве аргумента в XCUIApplication.Информация об доступных bundle id можно найти на сайте apple.Пример кода для запуска приложения по bundle id: // Запускаем safari
XCUIApplication(bundleIdentifier: "com.apple.mobilesafari").launch() // Во время прохождения теста открываем safari XCUIApplication(bundleIdentifier: "com.apple.mobilesafari").activate() @available(iOS 13.4, *)
public enum XCUIProtectedResource : Int { // All platforms case contacts = 1 case calendar = 2 case reminders = 3 case photos = 4 case microphone = 5 case camera = 6 case mediaLibrary = 7 case homeKit = 8 // macOS-specific resources // iOS Family-specific resources case bluetooth = -1073741824 case keyboardNetwork = -1073741825 case location = -1073741826 } override func setUpWithError() throws {
if #available(iOS 13.4, *) { application.resetAuthorizationStatus(for: .contacts) } else { throw XCTSkip("Required API is not available for this test.") } } public enum State : UInt {
case unknown = 0 // Текущее состояние приложения неизвестно case notRunning = 1 // Приложение не запущено case runningBackgroundSuspended = 2 // Приложение работает в фоновом режиме, но приостановлено case runningBackground = 3 // Приложение работает в фоновом режиме case runningForeground = 4 // Приложение работает } // Нажимаем на текущем симуляторе кнопку home
XCUIDevice.shared.press(.home) // Делаем явное ожидания, чтобы состояния приложение обновилось и мы перешли на экран home симулятора Thread.sleep(forTimeInterval: 5) // Проверяем что состояние приложения - runningForeground XCTAssertEqual(XCUIApplication().state, .runningForeground)
=========== Источник: habr.com =========== Похожие новости:
Блог компании Vivid Money ), #_razrabotka_pod_ios ( Разработка под iOS ), #_swift, #_testirovanie_mobilnyh_prilozhenij ( Тестирование мобильных приложений ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:00
Часовой пояс: UTC + 5