Версия для разработчиков
Совершенно новая мобильная среда
Вероятно, как и вы, я пришел к React Native из другого опыта JavaScript, а не как нативный мобильный разработчик. Это совершенно новая среда со своими уловками и хитростями.
Одна из важных новых областей, которые вам предстоит изучить, - это тестирование. Когда в модульных тестах более или менее ясно, как мы выполняем сквозные тесты пользовательского интерфейса? Есть iOS, есть Android. Рынок с множеством устройств на выбор.
Несмотря на относительно новые технологии по сравнению с обычными мобильными устройствами, это по-прежнему мобильная среда, и многие вещи мы перенимаем и извлекаем из собственного опыта.
Вот два фреймворка, которые я решил использовать, чтобы облегчить себе жизнь как разработчика React Native.
Аппиум
Использование Selenium WebDriver за кулисами Appium - это мощный фреймворк для тестирования, за которым стоит большое собственное мобильное сообщество. Выпущенный еще до React.js, это номер один в отрасли.
Начать легко, просто установив пакеты «appium» и «appium-doctor» глобально или для своего проекта с помощью npm. Выполнение команды «appium-doctor» сообщит вам, что вам нужно добавить и установить в вашей системе перед написанием и запуском тестов, и, если возможно, поможет вам исправить проблемы. Когда все будет отсортировано, пакеты установлены и настроена конфигурация jest, вы можете запустить сервер Appium, а затем проводить тесты.
Я не буду подробно останавливаться на настройке и написании теста, но вот как выглядит базовый тест (с добавленными комментариями):
/* selenium webdriver client for node */ import wd from 'wd' /* default timeout */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000 /* localhost because we run Appium server from our machine + port */ const URL = 'localhost' const PORT = 4723 /* creates webdriver object */ const driver = wd.promiseChainRemote(URL, PORT) /* Server capabilities. * This is how you tell Appium Server, * how to run the test, in other words config. * You probably will want to move this out of here. */ const capabilities = { platformName: 'iOS', // or Android platformVersion: '12.1', // version of the OS deviceName: 'iPhone 8', // or Android Emulator or specific device automationName: 'XCUITest', // platform specific framework (UIAutomator2 for Android) app: '/path/to/.app' // path to app (in case of Android it's .apk) } beforeAll(async () => { try { // before running our test await driver.init(capabilities) // initialise webdriver await driver.sleep(4000) // yes, we need to wait for launch screen finish his work before running test, hint of flaky stuff! } catch(err) { console.log(err) // just in case something goes wrong } }) afterAll(async () => { try { await driver.quit() // end testing session after test } catch(err) { console.error(err) } }); /* Jest, now do whatever you want! * in this case we check if elements with testIDs * 'topLabel' and 'subLabel' contain the text we want * Check Appium documentation */ describe("Home Screen landing", () => { test("render search screen", async () => { let topLabel = await driver.elementById('topLabel') let subLabel = await driver.elementById('subLabel') expect(await topLabel.text()).toBe("OK") expect(await subLabel.text()).toBe("Home Screen") }) })
Фактическая часть теста - это последние несколько строк Jest, которые проверяют, есть ли на экране текст «ОК» и «Главный экран». Как видите, это похоже на типичный Jest-тест, поэтому нет никаких проблем с его написанием. Страница документации Appium дает вам обзор возможностей и примеры.
Не нравится строка `await driver.sleep (4000)`. Нам это нужно, потому что тесты не знают, что, черт возьми, на самом деле происходит в приложении. Черный ящик. Представьте, что вы напишете код узла с HTTP-вызовом и установите тайм-аут перед ним вместо использования обещания или обратного вызова. Шаткость.
В этой базовой настройке мы говорим Appium (webdriver) подождать 4 секунды перед запуском теста, так как нам нужно запустить приложение и пройти мимо «LaunchScreen», но по мере того, как приложение становится более сложным, вам нужно будет использовать его чаще - http вызовы или анимации, само реагирование-native - мост между JavaScript и собственным кодом вызовет задержки.
Существуют альтернативы, такие как неявное ожидание, но это не меняет модель черного ящика.
Что мне нравится в Appium
- 7+ лет в индустрии.
- Возможности API, палец вверх.
- Легко найти помощь и поддержку в Интернете (также не нравится, см. Ниже)
- Для написания тестов поддерживаются различные языки, включая JavaScript.
- Обычная для JS-разработчика среда для написания тестов с использованием Jest.
- Используется для сквозных тестов в MS AppCenter, BrowserStack и AWS Device Farm.
- Тесты на реальных устройствах.
Что мне не нравится в Appium
- Поиск помощи в Интернете дает результаты на всех языках, в основном на Java.
- Тестирование черного ящика (тесты не знают о внутреннем процессе)
- Не синхронизируется с приложением. Нестабильный, даже более нестабильный на реакции родного.
- Свойство testID игнорируется в случае Android.
Детокс
Wix's Detox работает так же, как Appium, но важным отличием здесь является тестирование серого ящика. Одна из причин, по которой появился Detox, - решить проблему «нестабильности» - он будет ждать, пока действие в приложении не будет завершено, и будет продолжаться только тогда, когда приложение простаивает. Это возможно благодаря другой структуре под названием EarlGrey.
Так же, как и в Appium, мы сначала устанавливаем конфигурацию.
/* Our Device config is in package file, see below */ const detox = require("detox"); const config = require("./package.json").detox; /* Jest adapter */ const adapter = require("detox/runners/jest/adapter"); /* Set the default timeout * and use Jest adapter */ jest.setTimeout(120000); jasmine.getEnv().addReporter(adapter); beforeAll(async () => { /* Initialise and start the server */ await detox.init(config); }); /* beforeEach and afterEach detox test * we run beforeEach of the Jest and * do cleanup */ beforeEach(async function() { await adapter.beforeEach(); }); afterAll(async () => { await adapter.afterAll(); await detox.cleanup(); });
И дополнительная конфигурация в файле пакета.
"detox": { "configurations": { "ios.detox": { // configuration for iOS (run by detox test -c ios.detox) "binaryPath": "path/to/.app", "build": "xcodebuild -workspace ios/app.xcworkspace -scheme scheme -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", // workspace or project file. In this case we’re building debug package rather than production (release). "type": "ios.simulator", "name": "iPhone 8" }, "android.detox": { // configuration for Android (run by detox test -c android.detox) "binaryPath": "path/to/.apk", "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", // In this case we’re building debug package rather than production. "type": "android.emulator", "name": "Pixel_2_API_28" // name of the simulator. “adb devices” command will list available attached devices } }, "test-runner": "jest", "runner-config": { "setupTestFrameworkScriptFile" : "./detox.init.js", // our configuration above "testEnvironment": "node", "testRegex": "(.*|\\.(ui))\\.(ts|tsx)$" // test regex for UI tests } "specs": "./__tests__/" // location of UI tests }
Тесты написаны так же, вместо использования Appium API мы используем возможности и ограничения Detox. Проверьте ссылки в конце для получения подробной документации по настройке и справочной информации.
Что мне нравится в Детоксе
- Сделано Wix для React Native.
- Сосредоточен на JavaScript.
- Тестирование серого ящика (есть связь между тестами и внутренними процессами).
- Работает синхронно с приложением. Не так уж и плохо.
Что мне не нравится в Детоксе
- Возможности не такие широкие, как у Appium
- Меньшее сообщество.
Слоистый, хлопьевидный, шелушащийся
Несмотря на то, что Детокс использует тесты серого ящика, он все еще нестабилен. Тест, который я написал с вводом текста и жестом смахивания по неизвестной причине, 1 из 10 раз не удался. В тестах пользовательского интерфейса нельзя быть уверенным на 100%.
Скорость
Appium будет работать медленнее из-за ручных команд «сна», Detox в этом случае выигрывает, поскольку он автоматически продолжает действие, как только оно будет завершено. В целом, пока не буду делать никаких выводов, пока не проведу большое количество тестов. В небольших 30-секундных тестах и базовой настройке для этой статьи Детокс работал на несколько секунд быстрее. Что касается iOS и Android, я попробовал несколько тестов на обеих платформах на обеих платформах, для выполнения тестов потребовалось + - одинаковое количество времени. Только будьте готовы, что на это уходит гораздо больше времени, чем на обычные модульные тесты.
Что выбрать
Я все еще изучаю обе эти платформы, и потребуется время, чтобы полностью понять обе, но пока как разработчик JavaScript я выбираю Detox.
Попробуйте оба. К счастью, их всего двое. Это действительно зависит от приложения, которое вы разрабатываете, и от структуры вашей команды.
UI тесты, которые будут использоваться только в команде разработчиков, я бы предложил Detox. В длительных и сложных сквозных тестах из-за более широких возможностей API, а также поддержки автоматизированных платформ, таких как BrowserStack, AWS DeviceFarm и MS AppCenter, я бы предпочел Appium. Это пока.
Полезные ссылки
Сайт Appium. Вы найдете то, что вам нужно, в верхнем меню.
http://appium.io
Документы Detox.
https://github.com/wix/Detox/tree/master/docs
Detox: Gray Box End to End Testing Framework для мобильных приложений от Ротема Мизрахи-Мейдана.
https://hackernoon.com/detox-gray-box-end-to-end-testing-framework-for-mobile -apps-196ccd9564ce
Презентация Detox от разработчика Wix Ротема Мизрахи-Мейдана.
https://www.youtube.com/watch?v=GgFFeI70PWw
Детокс: начало работы
https://github.com/wix/Detox/blob/master/docs/Introduction.GettingStarted.md
Если вы не знали, в React Native есть свойство testID.
https://facebook.github.io/react-native/docs/view#testid