🚀 Next.js 全栈 E2E 测试:Playwright vs Cypress

写 Next.js 项目的人,最终都会走上这样一条路:
写前端 → 写 API → 写数据库 → 写测试 → 坐牢(调试半天测试不通过)。

为了不让自己凌晨三点还在盯着 npm test 发呆,我们需要掌握 E2E(End-to-End)测试

今天的主角是两位测试界的明星:

  • 🎭 Playwright ------ 来自微软,擅长潜入浏览器底层搞事情。
  • 🌲 Cypress ------ UI 界的老牌网红,界面友好,生态丰富。

接下来我们用 Next.js 做个全栈小例子,边写边比较。


🏗️ 1. 为什么要做 E2E 测试?

很多人觉得单元测试已经够了。

  • 单元测试:就像检查螺丝钉是不是拧紧。
  • E2E 测试:直接开上车,踩油门,看车会不会解体。

在全栈应用里,前端、后端、数据库之间任何一个环节崩了,用户体验就直接爆炸。E2E 测试帮我们模拟真实用户的操作,比如:

  1. 打开页面
  2. 填写表单
  3. 点击提交
  4. 检查后端是否真的保存成功

⚙️ 2. Next.js 项目准备

bash 复制代码
# 创建一个 Next.js 项目
npx create-next-app e2e-demo
cd e2e-demo

我们加一个简单的 Todo 功能:

pages/api/todos.js

ini 复制代码
let todos = [];

export default function handler(req, res) {
  if (req.method === "POST") {
    const todo = { id: Date.now(), text: req.body.text };
    todos.push(todo);
    return res.status(201).json(todo);
  }
  if (req.method === "GET") {
    return res.status(200).json(todos);
  }
}

pages/index.js

javascript 复制代码
import { useState } from "react";

export default function Home() {
  const [todos, setTodos] = useState([]);
  const [text, setText] = useState("");

  async function addTodo() {
    const res = await fetch("/api/todos", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ text })
    });
    const newTodo = await res.json();
    setTodos([...todos, newTodo]);
    setText("");
  }

  return (
    <div>
      <h1>📝 Todo List</h1>
      <input
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Write something..."
      />
      <button onClick={addTodo}>Add</button>
      <ul>
        {todos.map((t) => (
          <li key={t.id}>{t.text}</li>
        ))}
      </ul>
    </div>
  );
}

到这里,我们有了一个最小可测的全栈应用。


🎭 3. 用 Playwright 写 E2E 测试

安装:

bash 复制代码
npm install -D @playwright/test
npx playwright install

配置一个测试:

tests/todo.spec.js

erlang 复制代码
import { test, expect } from "@playwright/test";

test("用户可以添加一个 Todo", async ({ page }) => {
  await page.goto("http://localhost:3000");

  await page.fill("input", "买一杯咖啡");
  await page.click("button");

  const todo = await page.locator("li").last().innerText();
  expect(todo).toBe("买一杯咖啡");
});

运行:

bash 复制代码
npx playwright test

Playwright 的优势:

  • 多浏览器支持(Chromium、WebKit、Firefox)
  • 速度快,底层用浏览器协议直连
  • 内置截图、视频录制,调试时一目了然

🌲 4. 用 Cypress 写 E2E 测试

安装:

arduino 复制代码
npm install -D cypress
npx cypress open

配置一个测试:

cypress/e2e/todo.cy.js

erlang 复制代码
describe("Todo App", () => {
  it("用户可以添加一个 Todo", () => {
    cy.visit("http://localhost:3000");

    cy.get("input").type("写测试代码");
    cy.contains("Add").click();

    cy.get("li").last().should("have.text", "写测试代码");
  });
});

运行:

arduino 复制代码
npx cypress open

Cypress 的优势:

  • 界面化调试,像玩小游戏一样点点点
  • 社区插件丰富
  • 断言语法自然(cy.get().should(...) 看起来比 expect 更口语化)

🥊 5. Playwright vs Cypress 对比

特性 Playwright 🎭 Cypress 🌲
浏览器支持 Chromium / Firefox / WebKit Chromium 系
速度 ⚡ 更快 稍慢
调试体验 截图 & 视频 可视化界面强
API 风格 类似 Jest 链式操作,更口语化
CI/CD 适配 强大 成熟

一句话总结:

  • 如果你爱折腾底层,想要跨浏览器测试 → Playwright
  • 如果你想要上手快、调试方便 → Cypress

🌌 6. 收尾

测试不是"写完交差"的工作,它本质上是 给自己未来省头发

E2E 测试就像一台自动驾驶仪:

  • 让你放心上线
  • 让你半夜睡得更香
  • 让你的代码少点"玄学 Bug"

写代码的人和写测试的人,往往是同一个倒霉蛋。

但是相信我:测试写得好,未来的你会给现在的自己磕个头 🙇。


📌 作业

  • 用 Playwright 写一个"用户登录"E2E 测试。
  • 用 Cypress 写一个"数据持久化"测试(刷新后还能看到 Todo)。
相关推荐
你怎么知道我是队长4 分钟前
JavaScript的自适应效果
开发语言·javascript·ecmascript
其实防守也摸鱼22 分钟前
前端应用的离线暂停更新策略:构建稳定可靠的渐进式部署方案
服务器·前端·数据库·学习·ai·命令行·linux系统
太平洋月光30 分钟前
Antv G2中自定义技巧📊
前端·数据可视化
shmily麻瓜小菜鸡41 分钟前
前端“伪防盗链”方案
前端·javascript·vue.js·bootstrap·echarts
mayaairi42 分钟前
JS数组完全指南(含十大操作详解)
开发语言·前端·javascript
Damai42 分钟前
流式文件响应 `Controller is already closed` 崩溃复盘
next.js
IT_陈寒1 小时前
Python的线程池把我CPU跑满了,原来少传了个参数
前端·人工智能·后端
喜欢的名字被抢了1 小时前
写-Chrome-扩展时踩过的那些-MV3-的坑
前端·chrome
网安老伯1 小时前
网络安全基础要点知识介绍(非常详细),零基础入门到精通,看这一篇就够了
运维·前端·网络协议·web安全·网络安全·职场和发展
AndyHeee1 小时前
Linux 内核底层机制:设备树(Device Tree)的数据结构与内存组织
linux·前端·数据结构