4.4 调试、测试与代码质量
本章目标: 建立可以重复执行的检查过程,避免只凭页面“看起来正常”判断成功。
按数据流排查
页面没显示任务时,依次检查:Network 是否发请求、状态码是什么、Response 数据结构是否匹配、组件状态有没有更新、模板条件是否隐藏内容。
| 工具 | 优先看什么 |
|---|---|
| 浏览器 Console | 运行时错误和 Vue 警告 |
| Network | URL、method、status、payload、response |
| Vue DevTools | 组件树、props、响应式状态、Pinia |
| VS Code + Vue - Official | 脚本与模板类型错误 |
| 生产预览 | 构建后的资源路径和路由行为 |
API 在 Swagger 能调用,但页面不能调用时,优先看浏览器 Network,不能仅根据 Swagger 推断代理、CORS 或 Cookie 配置正确。
先做类型检查与构建
Vue CLI 工具链常用 vue-tsc 检查 .vue。Vite 主要转译和构建代码,不应把单独的 vite build 当作完整类型检查。
npm run build
检查 package.json 的 build 是否包含类型检查。附带实战项目的 build 脚本先执行 vue-tsc --noEmit,再执行 vite build。
文档站则执行 npm run typecheck 和 npm run build,它使用的是 React/MDX 工具链。
给规则写一个有价值的单元测试
在 vue-lab 安装:
npm install -D vitest
export function validateTitle(title: string): string | null {
const value = title.trim();
if (!value) return '请输入任务名称';
if (value.length > 100) return '任务名称不能超过 100 个字符';
return null;
}
import { describe, expect, it } from 'vitest';
import { validateTitle } from './validateTitle';
describe('任务标题规则', () => {
it('拒绝只有空白的标题', () => {
expect(validateTitle(' ')).toBe('请输入任务名称');
});
it('允许 100 个字符,拒绝 101 个字符', () => {
expect(validateTitle('a'.repeat(100))).toBeNull();
expect(validateTitle('a'.repeat(101))).not.toBeNull();
});
});
npx vitest run
这个测试覆盖输入边界。相比“变量是否等于刚设置的值”,它能防止用户可感知的规则回归。
组件测试与端到端测试
组件测试可使用 Vue Test Utils 配合 Vitest,验证提交输入、事件 payload、禁用和错误提示。端到端测试可使用 Playwright,验证浏览器与 API 的真实组合。
任务管理至少验证以下行为:空标题不新增;合法标题新增成功;筛选结果正确;完成与删除成功;请求失败保留输入;重复点击受到控制;移动端能操作。
纯函数测试类似业务规则单元测试;组件测试类似 UI 交互测试;E2E 类似经过真实 HTTP 和浏览器的系统测试。无需让每层重复验证同一份细节。
调试时常见误区
浏览器缓存可能保留旧脚本,但先确认访问地址和实际构建版本,不要一上来清空全部依赖。控制台打印 Proxy 不代表返回数据损坏;Vue 响应式对象本来就可能是代理。
不要把 access token、密码或完整个人数据打印到日志。错误日志用于定位问题,页面消息用于让用户知道下一步能做什么。
练习
在上面的校验中加入“标题不能包含换行”。先写能触发失败的测试,再修改函数,确认新测试和原有测试都通过。
参考答案
用 validateTitle('第一行\n第二行') 验证规则。在 trim 前检查 /[\r\n]/.test(title),防止边缘换行被 trim 隐藏。注意返回顺序会影响同时触发多个规则时的错误消息。