nextjs 单元测试 编写

Category:

单元测试

Tags:

vitest
playwright

最近在写国际化适配阿拉伯语时,发现在跑翻译的时候,有一些json解析翻译出来有些引号被替换,导致JSON.parse 报错,其中几个页面会直接error但是并没有发现,所以打算写一个测试,测试所有页面是否加载正常。

组件单元测试(vitest)

  1. 准备工作

    1. vitest.config.mts
    typescript
    import react from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths"; import { defineConfig } from "vitest/config"; export default defineConfig({ plugins: [tsconfigPaths(), react()], test: { globals: true, environment: "jsdom", setupFiles: ["./vitest.setup.ts"], include: ["**/*.test.{js,jsx,ts,tsx}"], exclude: ["**/node_modules/**", "**/dist/**"] } });

    b. vitest.setup.ts

    typescript
    import { cleanup } from "@testing-library/react"; import { afterEach, vi } from "vitest"; afterEach(() => { cleanup(); vi.clearAllMocks(); });
  2. 基本使用

    1. 判断 渲染组件后关键DOM是否存在
    typescript
    import Footer from "@/components/Footer"; import { render, screen } from "@testing-library/react"; import { expect, test } from "vitest"; test("test", () => { render(<Footer />); expect(screen.getByText("[赣ICP备2022002397号]")).toBeDefined(); });

e2e测试(playwright)

  1. 准备工作

    1. playwright.config.ts
    typescript
    import { defineConfig, devices } from "@playwright/test"; import path from "path"; // Use process.env.PORT by default and fallback to port 3000 const PORT = process.env.PORT || 3000; // Set webServer.url and use.baseURL with the location of the WebServer respecting the correct set port const baseURL = `http://localhost:${PORT}`; // Reference: https://playwright.dev/docs/test-configuration export default defineConfig({ // Timeout per test timeout: 30 * 1000, // Test directory testDir: path.join(__dirname, "e2e"), // If a test fails, retry it additional 2 times retries: 0, // Artifacts folder where screenshots, videos, and traces are stored. outputDir: "test-results/", // Run your local dev server before starting the tests: // https://playwright.dev/docs/test-advanced#launching-a-development-web-server-during-the-tests webServer: { command: "pnpm run dev", url: baseURL, timeout: 120 * 1000, reuseExistingServer: !process.env.CI }, use: { // Use baseURL so to make navigations relative. // More information: https://playwright.dev/docs/api/class-testoptions#test-options-base-url baseURL, // Retry a test if its failing with enabled tracing. This allows you to analyze the DOM, console logs, network traffic etc. // More information: https://playwright.dev/docs/trace-viewer trace: "retry-with-trace" // All available context options: https://playwright.dev/docs/api/class-browser#browser-new-context // contextOptions: { // ignoreHTTPSErrors: true, // }, }, projects: [ { name: "Desktop Chrome", use: { ...devices["Desktop Chrome"] } } // { // name: 'Desktop Firefox', // use: { // ...devices['Desktop Firefox'], // }, // }, // { // name: 'Desktop Safari', // use: { // ...devices['Desktop Safari'], // }, // }, // Test against mobile viewports. // { // name: "Mobile Chrome", // use: { // ...devices["Pixel 5"] // } // }, // { // name: "Mobile Safari", // use: devices["iPhone 12"] // } ] });
    1. 基本使用

      1. 加载所有页面是否正常 svg 过渡变换 并且包含预览 codebox
      typescript
      import { RouteInfo, scanRoutes } from "@/scripts/scanRoutes"; import { expect, test } from "@playwright/test"; import { filter } from "lodash"; const routes = scanRoutes(); const isStaticRoute = filter(routes, (r: RouteInfo) => !r.isDynamic); const generatePageTestByRoute = (route: RouteInfo) => { test.describe(`<${route.path}> 加载测试`, () => { test(`<${route.path}> 加载成功`, async ({ page }) => { // 检查页面响应状态码 const response = await page.goto(route.path); expect(response?.status()).toBe(200); }); if (route.path.includes("svgTransform")) { test(`<${route.path}> svg 过渡变换 并且包含预览 codebox`, async ({ page }) => { const response = await page.goto(route.path); expect(response?.status()).toBe(200); const htmlContent = await page.content(); const bol = htmlContent.includes("IconTransformProps"); expect(bol).toBe(true); }); } }); }; isStaticRoute.forEach(generatePageTestByRoute);