专家级js单元测试的核心是让测试成为代码演进的可信依据:聚焦业务契约、反向建模用户路径、断言具体行为、真实依赖与精准mock结合、严格治理脆弱测试、将测试作为活文档持续演进。

JS 单元测试做到专家级,核心不是堆工具或写更多用例,而是让测试真正成为代码演进的“可信依据”——它得能回答:这段逻辑改了,会不会影响登录流程?这个工具函数在空值、超长字符串、Promise 拒绝时是否依然健壮?边界场景有没有被遗漏?
聚焦可验证的业务契约,而非“覆盖行数”
覆盖率数字容易刷高,但没意义。专家级做法是反向建模:从关键用户路径(如“注册→邮箱验证→跳转控制台”)出发,拆解每一步依赖的 JS 函数/模块,明确它们的输入约束、输出承诺和失败边界。
- 比如一个
formatCurrency(amount, locale)函数,测试重点不是“跑过 10 个数字”,而是覆盖:负数、NaN、Infinity、空字符串、locale 不存在、amount 是 Promise 等真实易错点 - 对 API 工具类(如封装 axios 的
apiClient.post()),测试必须包含:网络超时、401 响应触发登出、503 重试逻辑、取消请求后不执行回调 - 避免写
expect(result).toBeDefined()这类弱断言;换成expect(result.status).toBe('success')或expect(error.code).toBe('VALIDATION_FAILED')—— 断言具体契约,而非存在性
用真实依赖替代过度 mock,分层隔离才可靠
很多项目 mock 掉一切,结果测试通过,上线却因 localStorage 权限变更或 fetch polyfill 行为差异崩掉。专家级策略是“该真则真,该控则控”:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
浏览器环境 API 尽量不 mock:用 jsdom 模拟 DOM,但保留
localStorage、fetch、setTimeout等原生行为;只对不可控外部服务(如第三方 SDK、支付网关)做精准 mock -
状态管理模块走真实流程:测试 Vuex/Pinia action 时,不 mock store,而是调用
store.dispatch('login', credentials),再断言store.state.user.token和store.getters.isAuthenticated—— 验证的是整个状态流转,不是单个函数 -
异步逻辑必须显式等待:不用
setTimeout(() => { ... }, 0),而用await waitFor(() => expect(...).toBeInTheDocument())(React Testing Library)或await flushPromises()(Vue Test Utils),确保事件循环真实推进
CI 中自动识别脆弱测试,不让“flaky test”污染信任
一个随机失败的测试比没有测试更危险——它会让人习惯性忽略红灯。专家级 CI 流水线必须主动治理:
- 在
test:ci脚本中启用--runInBand --maxWorkers=1,排除并发干扰;加上--detectOpenHandles抓住未清理的定时器或 WebSocket - 对历史失败率 >5% 的用例,自动标记为
it.skip.fragile()并通知负责人;Jest 支持自定义 reporter 输出“不稳定用例TOP10”报告 - 把测试耗时纳入质量门禁:单个用例超过 300ms 自动告警;全量测试总时长增长超 20% 时阻断合并,倒逼性能优化(如用
jest.mock('./heavy-module', () => ({ init: jest.fn() }))替代实际加载)
让测试资产持续可读、可追溯、可演进
专家级团队的测试代码不是一次性脚本,而是活文档:
- 每个
describe块开头加注释说明“这个测试集验证哪条业务规则”,例如:// 验证:用户未登录时,所有 /admin/* 路由应重定向至 /login - 用
test.each统一数据驱动场景,避免复制粘贴用例;表格第一列写明业务含义(如['空邮箱', '', 'EMAIL_REQUIRED']),而非仅技术值 - 把测试覆盖率报告(如 c8)接入 CI,但**不设覆盖率阈值强制达标**;改为生成 diff 报告:本次 PR 新增代码的测试覆盖率为 100%,但修改的旧逻辑有 2 行未覆盖 → 精准定位缺口










