前端转全栈 12:全栈测试——单元 / 集成 / E2E 三层防护

前端全栈tutorial测试vitestplaywrighte2e质量

系列目录:本文是「前端转全栈:Next.js + Supabase 实战」系列的第 12 篇。前端你可能写过组件测试,但「接口 + 数据库」这条链路怎么测?这一篇补齐全栈的质量观。


改一行代码,心里没底——这是没测试的典型症状。全栈测试分三层,各管一段:

E2E(端到端)   ▸  模拟真实用户点完整流程(登录→发帖→看到)
   │
集成(Integration) ▸  测 API + 数据库 联调是否正确
   │
单元(Unit)     ▸  测单个函数逻辑(校验、计算)

一、单元测试:最小可测单元

vitest(配置简单、和 Jest 兼容):

npm i -D vitest
// lib/validate.test.ts
import { describe, it, expect } from "vitest"
import { CommentSchema } from "@/lib/schema"

describe("CommentSchema", () => {
  it("拒绝空内容", () => {
    const r = CommentSchema.safeParse({ post_slug: "x", content: "" })
    expect(r.success).toBe(false)
  })
  it("接受合法输入", () => {
    const r = CommentSchema.safeParse({ post_slug: "x", content: "好" })
    expect(r.success).toBe(true)
  })
})

npx vitest,绿了就说明校验逻辑稳。把第 6 篇的 zod schema 直接拿来测,零额外成本


二、集成测试:API + 数据库一起测

单测不管「接口能不能真写进库」。集成测试用一个测试库(不影响生产数据)跑完整链路:

// tests/comments.test.ts
import { createClient } from "@/lib/supabase/admin" // 用测试专用库

it("未登录不能发评论", async () => {
  const res = await POST(new Request("http://localhost/api/comments", {
    method: "POST",
    body: JSON.stringify({ post_slug: "x", content: "hi" }),
  }))
  expect(res.status).toBe(401)
})

it("登录后能插入并查回", async () => {
  // 先造一个测试用户 session,再发请求,再查库确认存在
})

关键点:用独立的测试数据库 / Supabase 测试项目,测试前后清理数据(beforeEach 清空、afterAll 断开),绝不用生产库跑测试。


三、E2E:模拟真实用户

Playwright 驱动真实浏览器走完整流程:

// e2e/comment.spec.ts
import { test, expect } from "@playwright/test"

test("登录用户能发表评论并看到", async ({ page }) => {
  await page.goto("/login")
  await page.fill("#email", "test@example.com")
  await page.fill("#password", "123456")
  await page.click("button[type=submit]")
  await page.goto("/blog/some-post")
  await page.fill("textarea", "自动化测试评论")
  await page.click("提交")
  await expect(page.getByText("自动化测试评论")).toBeVisible()
})

E2E 最贴近真实,但慢且脆(UI 一改就可能挂),留给核心流程(登录、下单、发帖)即可,别什么都 E2E。


四、测试金字塔:别本末倒置

        /\
       /E2E\        ← 少而精(核心流程)
      /------\
     /集成测试 \     ← 中量(关键 API)
    /----------\
   /  单元测试   \    ← 大量(函数逻辑)
  /--------------\
  • 单元测试多写(快、稳、便宜)。
  • 集成测试针对关键链路
  • E2E 只覆盖核心路径

五、把测试接进 CI(预告下一篇)

测试的价值在「每次提交自动跑」。第 13 篇的 CI/CD 里,我们会让 vitest + playwright 在每次 git push 时自动执行——红了的测试直接拦住合并,比人工点靠谱一万倍。


总结

  • 三层防护:单元(函数)→ 集成(API+DB)→ E2E(真实用户)。
  • 单元测试用 vitest 测 zod schema、纯函数,量大价廉。
  • 集成测试用独立测试库测完整链路,绝不碰生产数据。
  • E2E(Playwright)只覆盖核心流程,慢而脆。
  • 测试金字塔:单元多、E2E 少。

下一篇进入阶段四——部署与运维:Docker / CI-CD / 监控,把应用真正送上生产。


练习:给第 6 篇的 CommentSchema 加一个 vitest 测试文件,覆盖「空内容拒绝 / 合法通过 / 超长拒绝」三个用例,跑通变绿。

Comments

Sign in to leave a comment.