react-native-vision-camera 自动化测试指南:3 步在真机上跑通第一条相机用例
【免费下载链接】react-native-vision-camera📸 A powerful, high-performance React Native Camera library.项目地址: https://gitcode.com/GitHub_Trending/re/react-native-vision-camera
react-native-vision-camera 是面向 React Native 的高性能相机库,覆盖拍照、录像、帧输出、条码扫描等能力。本文带你摸清仓库里真实存在的测试体系:3 步跑通第一条真机用例,知道每类测试该放在哪一层,以及怎么把失败用例交给流水线。
一次改动,拍照链路就翻了
你改了一个看似无关的会话配置字段,本地没发现异常,发版后用户反馈"拍照黑屏"。相机功能无法靠肉眼回归——它依赖真实传感器、权限、系统相机管线,每层都可能出问题。这个仓库的答案是把所有公开 API 的行为固化成可执行测试:API 一回归,CI 直接变红;用户报的每个 bug,都要以一条能复现它的测试形式合入。规则写得明明白白:修 bug 的人,必须顺手把一条失败的测试带上。
3 步搭好 react-native-vision-camera 真机测试环境
整个测试体系的入口是示例应用apps/simple-camera,测试用例以.harness.ts(x)文件的形式放在apps/simple-camera/__tests__/下,由 react-native-harness 驱动——它把 Jest 兼容的测试运行器嵌进真机应用里执行。按下面 3 步走:
git clone https://gitcode.com/GitHub_Trending/re/react-native-vision-camera cd react-native-vision-camera bun i && cd apps/simple-camera && bun run build:android第二步把 debug APK 装到手机并授权相机(权限只授予一次安装,重装后要重跑授权命令,命令在apps/simple-camera/__tests__/README.md里逐条写好了)。第三步只跑一个文件验证闭环:
bun run test:harness:android -- --testPathPatterns=photo看到绿色的通过摘要,你的 react-native-vision-camera 测试环境就通了。
文档站的 Playwright 截图测试基线:截图漂移超过阈值时测试失败
分层策略:真机 Harness 为主,单元测试与截图测试各管一段
这个仓库没有采用"Jest 模拟一切"的路子,因为相机行为只有在真硬件上才可信。三层分工如下:
| 测试层 | 验证什么 | 代表工具 | 何时用 |
|---|---|---|---|
| 真机 Harness 测试 | 拍照、录像、帧回调、多相机等完整相机链路 | react-native-harness + Jest | 改相机库、写回归用例,主力层 |
| 文档站单元测试 | 纯 TS 逻辑(链接解析、结构化数据等) | Bun Test | 改docs/src下的工具函数 |
| 文档站截图测试 | 官网页面渲染是否漂移 | Playwright | 改文档站 UI 或样式 |
日常你只需要关心第一层。后两层是文档站自己的质量保障,命令分别是bun run test:logic和bun run test:screenshots(在docs/目录下执行)。
从写用例到读报告:一条用例的完整旅程
用例按领域分文件存放:拍照在visioncamera.photo.harness.ts,会话生命周期在visioncamera.session.harness.ts,坐标换算、条码扫描各有对应文件。找不到合适的文件时,新建visioncamera.<领域>.harness.ts即可,Jest 会按__tests__/**/*.harness.{ts,tsx}自动拾取。
写用例时,apps/simple-camera/__tests__/README.md是硬约定,核心几条:测试必须直接读起来像用户代码,不抽createSession()之类的辅助函数;设备不支持某能力时用context.skip('原因')上报为"跳过",不要用console.log加return掩盖;等待用监听器(如addOnStartedListener)而不是sleep轮询;Photo、Frame持有大块原生内存,用完立即dispose()。
失败怎么读?本地跑挂了一般直接看断言输出的实际值与期望值。CI 挂掉时,下载失败运行里的harness output log产物——里面是每条测试的完整 JS 日志;再看 JUnit 摘要区分"失败"和"因设备能力缺失跳过",跳过的原因字段会告诉你这台测试机缺什么。定位缺口后回到对应的分片文件补断言,这就是闭环。
文档站首页的截图基线:像素差异超过maxDiffPixels阈值即判定 UI 回归
交给流水线:两条 Harness 工作流自动盯真机
你不需要手动触发任何 CI:只要 PR 改到相机库各packages/目录或apps/simple-camera/__tests__/,两条工作流会自动起跑。
.github/workflows/harness-aws-device.yml把用例跑到 AWS Device Farm 的真机 Android/iOS 上,这是权威结果——真手机、真 SoC、真相机管线;.github/workflows/harness-android-emulator.yml在 Android 模拟器上跑,属于尽力而为,硬件相关测试可能被跳过。
两条工作流都用concurrency取消了同分支旧运行,避免排队。想本地复现 CI 行为,直接跑apps/simple-camera/scripts/run-harness-android-ci.sh的对应命令即可,它就是工作流里script字段调用的那份脚本。
高频坑位:写用例前先看这四条
问题:重装 APK 后第一条用例就挂在权限断言上。原因:pm grant授予的权限只绑定一次安装,adb install -r重装后权限被重置。 解法:重装后把CAMERA、RECORD_AUDIO等授权命令重跑一遍,或干脆用真机首次安装。
问题:用例时过时不过,典型 flaky。原因:用sleep(500)"等相机稳定",本质是在赌时序。 解法:只等待你真正依赖的事件——addOnStartedListener、onRecordingFinished这类回调;README 明确规定sleep只允许出现在"录制时长本身是测试对象"的场景(如maxDuration自动停录)。
问题:给跨平台差异加Platform.OS分支后,测试变绿了。原因:守卫只写在一个平台上,等于主动隐藏了另一平台的回归。 解法:平台守卫只留给静态确定的单平台能力(如 iOS 独有的CameraObjectOutput);该双端一致的行为写成一条共享测试,宁可让 CI 红着直到差异修好。
问题:断言typeof x === 'number'这种类型检查。原因:Nitrogen 和桥接层在编译期、运行时已经强制类型,这类断言是噪音——如果数字真的变成了字符串,桥接早抛错了。 解法:断言语义值(照片width > 0、控制器的length等于 connections 数)和跨字段不变量(hasFlash为 false 时开闪光灯拍照必须 reject)。
下一步
打开apps/simple-camera/__tests__/README.md,挑最近一个你修过的线上问题,用现有用例当模板把它翻译成一条it(...)。CI 的完整配置可以从 .github/workflows/harness-aws-device.yml 顺藤摸瓜。
【免费下载链接】react-native-vision-camera📸 A powerful, high-performance React Native Camera library.项目地址: https://gitcode.com/GitHub_Trending/re/react-native-vision-camera
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考