前端测试完全指南:从单元测试到E2E测试

前端测试完全指南:从单元测试到E2E测试

大家好,我是蔓蔓。在大厂工作时,我们团队非常注重测试,这让我们的代码更加可靠。今天我来和大家分享前端测试的完整指南。

单元测试

Jest基础

javascript 复制代码
// sum.js
export function sum(a, b) {
  return a + b;
}

// sum.test.js
import { sum } from './sum';

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

test('adds negative numbers', () => {
  expect(sum(-1, -2)).toBe(-3);
});

test('adds zero', () => {
  expect(sum(0, 0)).toBe(0);
});

Mock函数

javascript 复制代码
// fetchUser.js
export async function fetchUser(id) {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}

// fetchUser.test.js
import { fetchUser } from './fetchUser';

jest.mock('node-fetch');
import fetch from 'node-fetch';

test('fetchUser returns user data', async () => {
  const mockUser = { id: 1, name: '蔓蔓' };
  fetch.mockResolvedValue({
    json: () => Promise.resolve(mockUser)
  });

  const user = await fetchUser(1);
  expect(user).toEqual(mockUser);
  expect(fetch).toHaveBeenCalledWith('/api/users/1');
});

测试覆盖率

javascript 复制代码
// jest.config.js
module.exports = {
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    }
  },
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.test.{js,jsx,ts,tsx}'
  ]
};

集成测试

React组件测试

jsx 复制代码
// Button.jsx
function Button({ onClick, children }) {
  return (
    <button onClick={onClick} className="btn">
      {children}
    </button>
  );
}

// Button.test.jsx
import { render, screen, fireEvent } from '@testing-library/react';
import Button from './Button';

test('renders button with text', () => {
  render(<Button>Click me</Button>);
  expect(screen.getByText('Click me')).toBeInTheDocument();
});

test('calls onClick when clicked', () => {
  const handleClick = jest.fn();
  render(<Button onClick={handleClick}>Click me</Button>);
  
  fireEvent.click(screen.getByText('Click me'));
  expect(handleClick).toHaveBeenCalledTimes(1);
});

Vue组件测试

javascript 复制代码
// Button.vue
<template>
  <button @click="handleClick">{{ text }}</button>
</template>

<script>
export default {
  props: ['text'],
  methods: {
    handleClick() {
      this.$emit('click');
    }
  }
};
</script>

// Button.spec.js
import { mount } from '@vue/test-utils';
import Button from './Button.vue';

test('renders button', () => {
  const wrapper = mount(Button, {
    props: { text: 'Click me' }
  });
  
  expect(wrapper.text()).toBe('Click me');
});

test('emits click event', () => {
  const wrapper = mount(Button, {
    props: { text: 'Click me' }
  });
  
  wrapper.trigger('click');
  expect(wrapper.emitted('click')).toHaveLength(1);
});

E2E测试

Cypress基础

javascript 复制代码
// app.spec.js
describe('App', () => {
  beforeEach(() => {
    cy.visit('/');
  });

  it('displays welcome message', () => {
    cy.contains('Welcome');
  });

  it('logs in successfully', () => {
    cy.get('input[name="email"]').type('test@example.com');
    cy.get('input[name="password"]').type('password');
    cy.get('button[type="submit"]').click();
    
    cy.contains('Dashboard').should('be.visible');
  });

  it('shows error for invalid login', () => {
    cy.get('input[name="email"]').type('invalid@example.com');
    cy.get('input[name="password"]').type('wrong');
    cy.get('button[type="submit"]').click();
    
    cy.contains('Invalid credentials').should('be.visible');
  });
});

Playwright基础

javascript 复制代码
// app.spec.js
import { test, expect } from '@playwright/test';

test('has title', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle('My App');
});

test('login flow', async ({ page }) => {
  await page.goto('/login');
  
  await page.fill('input[name="email"]', 'test@example.com');
  await page.fill('input[name="password"]', 'password');
  await page.click('button[type="submit"]');
  
  await expect(page.locator('text=Dashboard')).toBeVisible();
});

测试策略

javascript 复制代码
const testStrategy = {
  unit: {
    coverage: 80,
    focus: 'individual functions and components'
  },
  integration: {
    focus: 'interactions between components'
  },
  e2e: {
    focus: 'end-to-end user flows',
    criticalPaths: ['login', 'checkout', 'search']
  }
};

总结

前端测试能提升代码质量和可靠性:

  1. 单元测试验证单个功能
  2. 集成测试验证组件交互
  3. E2E测试验证用户流程
  4. 合理设置测试覆盖率目标

技术应当有温度,可靠的测试能让用户使用更安心。

相关推荐
wuxinyan1232 小时前
工业级大模型学习之路018:LangChain零基础入门教程(第一篇):LangChain架构与生态介绍
人工智能·python·学习·langchain
Angel3 小时前
Dify系列课程 - 4.Dify实战(本地部署-源码下载与部署)
ai·dify·dify实战·dify实战指南·dify docker 部署·ai实战 应用
qcx233 小时前
【AI Daily】每日Arxiv论文研读Top5 | 2026-05-19(周2)
人工智能·llm·agi·arxiv
hudawei9963 小时前
RK R87 Pro AI键盘,AI功能设置与连接教程
人工智能·计算机外设·使用说明·rk r87 ai键盘
Agent手记3 小时前
委外加工成本智能核算与利润分析方案:基于LLM+超自动化的端到端实践
运维·人工智能·ai·自动化
Yingjun Mo3 小时前
2. AI 智能体工作流的自动化自主设计(ADAS)
运维·人工智能·自动化
前端白袍3 小时前
AI+:AI编程工具对比分析:OpenClaw、Codex、Trae与Claude Code
人工智能·ai编程
海上彼尚3 小时前
Nodejs也能写Agent - 2.基础篇 - Prompt
前端·javascript·人工智能·node.js·prompt
yumgpkpm3 小时前
【华为昇腾910B】在AI大模型推理速度与GPU显卡选择中地位
大数据·人工智能·华为