[英]Detox testing + React Native + PouchDB app: our login test keep failing with timeout because of some PouchDB syncing?
似乎初始化 PouchDB 客戶端的實例(調用new PouchDB(...)
)會導致一些隊列工作者或后台進程產生,它們會定期向其 CouchDB 服務器發送網絡請求,這樣做會阻止我們的 Detox 測試套件讓我們的 React Native 應用程序 + iOS 模擬器 go 空閑並繼續下一個斷言,導致我們的測試失敗, App has not responded to the network requests below
或DetoxRuntimeError: Test Failed: No elements found for “MATCHER(identifier == “foo”)”
。
我們已經嘗試調用device.disableSynchronization
/ device.enableSyncronization
或使用launchArgs: { detoxURLBlacklistRegex: '.*' }
或device.setURLBlacklist(['.*'])
設置黑名單,但似乎都沒有成功。
有什么方法可以讓 Detox 忽略 PouchDB 網絡請求,或者手動暫停 PouchDB,以便我們可以進行下一個斷言?
我的團隊正在嘗試使用 Detox 為在使用 React Native 構建的模擬器中運行的 iOS 應用程序編寫登錄測試。 該應用程序使用 PouchDB 作為其網絡/數據層,因此它可以連接到遠程 CouchDB 服務器。
問題是 Detox 似乎總是失敗/凍結/掛起和超時超過某個點,這基本上是每當 PouchDB 被初始化時(通過調用new PouchDB(...)
)。
在我們的測試中,這是使用有效憑據點擊登錄按鈕的副作用:
await element(by.id('auth.login.button')).tap();
該行之前的所有有效斷言都可以正常工作(例如,嘗試單擊忘記密碼按鈕,查看下一個組件加載等)。 該行之后的任何斷言都不會成功,
await expect(element(by.id('auth.linkedin.skip'))).toBeVisible();
即使我們引用的確切組件( auth.linkedin.skip
)在計時器到期之前在模擬器中清晰可見,這通常會導致兩種方式之一的失敗。
測試運行了很長時間,直到失敗並顯示錯誤消息Timeout exceeded
,或者更准確地說:
App has not responded to the network requests below:
(id = 8) invoke: {"type":"expectation","predicate":{"type":"id","value":"auth.linkedin.skip"},"expectation":"toBeVisible"}
That might be the reason why the test "Login test allow existing the existing test user to sign in" has timed out.
在詳細模式下,我們還會一遍又一遍地看到它,直到它失敗:
detox[35499] INFO: [actions.js] The system is busy with the following tasks:
Dispatch Queue
⏱ Queue: “Main Queue (<OS_dispatch_queue_main: com.apple.main-thread>)” with 2 work items
Run Loop
⏱ “Main Run Loop”
One-time Events
⏱ “Network Request” with object: “URL: “https://our.couch.endpoint/userdb-foo/bar/baz””
⏱ “Network Request” with object: “URL: “https://our.couch.endpoint/userdb-foo/bar/baz””
測試運行時間較短並失敗並顯示錯誤消息DetoxRuntimeError: Test Failed: No elements found for “MATCHER(identifier == “auth.linkedin.skip”)”
並打印加載到模擬器中的本機組件堆棧對應於前一個登錄屏幕(而不是下一個屏幕,它具有linkedin按鈕,並且在失敗時已經加載到模擬器中)。
這里另外令人困惑的是,這兩種情況大約會發生 67% / 33% 的時間,這意味着對於沒有超時的每個單一故障,超時故障大約會發生兩次,所有這些都使用完全相同的測試命令、測試和執行之間的配置。
describe('Login test', () => {
beforeAll(async () => {
await device.launchApp({
newInstance: true,
launchArgs: {
// detoxURLBlacklistRegex: '.*',
}
});
});
beforeEach(async () => {
await device.reloadReactNative();
});
it('allow existing the existing test user to sign in', async () => {
// see login screen
await expect(element(by.id('auth.login.keyboardView'))).toBeVisible();
// run login
await element(by.id('auth.login.emailInput')).replaceText('test@example.com');
await element(by.id('auth.login.passwordInput')).replaceText('pass123');
await element(by.id('auth.login.button')).tap();
// the test fails on the line below (it times out while waiting for some pouchdb thing...even though the skip button is visible in the simulator)
await expect(element(by.id('auth.linkedin.skip'))).toBeVisible();
});
});
節點:12.18.3
xcode:12.0.1
package.json:
"@craftzdog/pouchdb-core-react-native": "^7.0.0",
"@craftzdog/pouchdb-replication-react-native": "^7.0.0",
"detox": "^18.9.0",
"jest": "^25.1.0",
"jest-circus": "^26.6.3",
"pouchdb-adapter-http": "^7.2.1",
"pouchdb-adapter-react-native-sqlite": "^2.0.0",
"pouchdb-authentication": "^1.1.3",
"pouchdb-debug": "^7.2.1",
"pouchdb-find": "^7.2.1",
"pouchdb-upsert": "^2.2.0",
"pouchdb-upsert-bulk": "^1.0.2",
"pouchdb-validation": "^4.2.0",
"react": "16.11.0",
"react-native": "0.62.2",
`detox test -c ios -l verbose --record-logs all`
.detoxrc.json
{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"apps": {
"ios": {
"type": "ios.app",
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/hooli.app",
"build": "xcodebuild -workspace appName.xcworkspace/ -scheme appScheme -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build"
},
"android": {
"type": "android.apk",
"binaryPath": "SPECIFY_PATH_TO_YOUR_APP_BINARY"
}
},
"devices": {
"simulator": {
"type": "ios.simulator",
"device": {
"type": "iPhone 11"
}
},
"emulator": {
"type": "android.emulator",
"device": {
"avdName": "Pixel_3a_API_30_x86"
}
}
},
"configurations": {
"ios": {
"device": "simulator",
"app": "ios"
},
"android": {
"device": "emulator",
"app": "android"
}
}
}
e2e/config.json
{
"testEnvironment": "./environment",
"testRunner": "jest-circus/runner",
"testTimeout": 35000,
"testRegex": "\\.e2e\\.js$",
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true
}
e2e/environment.js
const {
DetoxCircusEnvironment,
SpecReporter,
WorkerAssignReporter,
} = require('detox/runners/jest-circus');
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
constructor(config, context) {
super(config, context);
// Can be safely removed, if you are content with the default value (=300000ms)
this.initTimeout = 300000;
// This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
// This is strictly optional.
this.registerListeners({
SpecReporter,
WorkerAssignReporter,
});
}
}
module.exports = CustomDetoxEnvironment;
我們試過打電話
device.disableSynchronization();
...
device.enableSynchronization();
並設置黑名單
// this
device.launchApp({
launchArgs: { detoxURLBlacklistRegex: '.*' },
});
// or this
device.setURLBlacklist(['.*']);
但似乎沒有一個能夠讓它發揮作用。
有什么方法可以讓 Detox 忽略 PouchDB 網絡請求,或者手動暫停 PouchDB,以便我們可以進行下一個斷言?
作者在這里,只要我們在測試環境中,我就可以通過將此配置值切換為 false 來手動暫停 PouchDB 的實時同步。 資料來源: PouchDB 文檔同步。
// localDB, authDB have been initialized with new PouchDB(...)
// isTestEnv=true
localDB.sync(authDB, {
live: (isTestEnv)?false:true,
// rest of options
});
在此更改之后,Detox 測試能夠超越登錄步驟並在應用程序內進行更多斷言。 感覺很hacky,但至少它又可以工作了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.