排毒测试 + React Native + PouchDB 应用程序:由于一些 PouchDB 同步,我们的登录测试一直失败并超时?
Posted
技术标签:
【中文标题】排毒测试 + React Native + PouchDB 应用程序:由于一些 PouchDB 同步,我们的登录测试一直失败并超时?【英文标题】:Detox testing + React Native + PouchDB app: our login test keep failing with timeout because of some PouchDB syncing? 【发布时间】:2021-07-04 15:58:47 【问题描述】:tldr
似乎初始化 PouchDB 客户端的一个实例(调用 new PouchDB(...)
)会导致一些队列工作者或后台进程产生定期向其 CouchDB 服务器发送网络请求,这样做会阻止我们的 Detox 测试套件让我们的React Native 应用程序 + ios 模拟器闲置并继续下一个断言,导致我们的测试失败,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
) 在计时器到期之前在模拟器中清晰可见,这通常会导致两种方式之一的失败。
场景 1 - 测试因超时而失败
测试运行了很长时间,直到它失败并显示错误消息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””
场景 2 - 测试过早失败
测试运行时间更短,失败并显示错误消息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(['.*']);
但似乎没有一个可以使它工作。
【问题讨论】:
【参考方案1】:有什么方法可以让 Detox 忽略 PouchDB 网络请求,或者手动暂停 PouchDB,以便我们可以进行下一个断言?
作者在这里,只要我们在测试环境中,我就可以通过将此配置值切换为 false 来手动暂停 PouchDB 的实时同步。来源:PouchDB docs on sync。
// localDB, authDB have been initialized with new PouchDB(...)
// isTestEnv=true
localDB.sync(authDB,
live: (isTestEnv)?false:true,
// rest of options
);
在此更改之后,Detox 测试能够超越登录步骤并在应用程序内进行更多断言!感觉很老套,但至少它又能正常工作了。
【讨论】:
以上是关于排毒测试 + React Native + PouchDB 应用程序:由于一些 PouchDB 同步,我们的登录测试一直失败并超时?的主要内容,如果未能解决你的问题,请参考以下文章
排毒自动化框架指南:React Native?创建 End 2 端和集成测试框架
使用 react-navigation 和 react-native-fluid-transitions 进行排毒 e2e 测试 - 期望 .toBeVisible 失败
如何用排毒模拟@react-native-community/geolocation?
排毒测试 + React Native + PouchDB 应用程序:由于一些 PouchDB 同步,我们的登录测试一直失败并超时?