Skip to content
Development
Skill

/integration-testing

集成测试方法论,验证模块间协作、数据库交互、服务间调用,参考 Testcontainers、Testing Library、WireMock 等开源实践

From plugin
boss
54438 skills16 agents10 commands

Claude Code

$ npx -y skills add echoVic/boss-skill --skill integration-testing --agent claude-code

SKILL.md

integration-testing.SKILL.md
name: qa/integration-testing
description: 集成测试方法论,验证模块间协作、数据库交互、服务间调用,参考 Testcontainers、Testing Library、WireMock 等开源实践
version: 1.0.0
agent: qa
type: methodology
user-invocable: false
agent-invocable: true
dependencies:
- shared/tech-stack-detection
  triggers:
- 需要验证模块间协作时
- 需要测试数据库真实交互时
- 需要测试服务间调用时
- 需要验证前端组件与 API 集成时
  metadata:
  internal: true

集成测试方法论

> 参考开源实践:Testcontainers、Testing Library、WireMock、Testcontainers-go、Django Test Client

集成测试 vs 单元测试

| 维度 | 单元测试 | 集成测试 | | ---- | -------------- | -------------------- | | 范围 | 单个函数/组件 | 多个模块协作 | | 依赖 | Mock 外部依赖 | 真实依赖(DB、HTTP) | | 速度 | 快(ms) | 较慢(s) | | 目的 | 验证逻辑正确性 | 验证模块间协作 | | 数据 | Mock 数据 | 测试数据库/真实数据 |

1. 后端集成测试

1.1 数据库集成测试

使用真实数据库(Testcontainers 或测试数据库),不 mock Repository 层。

Node.js + Testcontainers (PostgreSQL)

// tests/integration/userRepository.test.ts
import { PostgreSqlContainer } from '@testcontainers/postgresql';
import { PrismaClient } from '@prisma/client';
import { UserRepository } from '../../src/repositories/userRepository';

describe('UserRepository (integration)', () => {
  let container: StartedPostgreSqlContainer;
  let prisma: PrismaClient;
  let repo: UserRepository;

  beforeAll(async () => {
    container = await new PostgreSqlContainer().start();
    prisma = new PrismaClient({ datasources: { db: { url: container.getConnectionUri() } } });
    await prisma.$executeRawUnsafe('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"');
    repo = new UserRepository(prisma);
  }, 60000);

  afterAll(async () => {
    await prisma.$disconnect();
    await container.stop();
  }, 60000);

  beforeEach(async () => {
    await prisma.user.deleteMany();
  });

  it('creates and retrieves user', async () => {
    const user = await repo.create({ name: 'Alice', email: 'alice@example.com' });
    const found = await repo.findByEmail('alice@example.com');

    expect(found?.id).toBe(user.id);
    expect(found?.name).toBe('Alice');
  });

  it('returns null for non-existent email', async () => {
    const found = await repo.findByEmail('nonexistent@example.com');
    expect(found).toBeNull();
  });
});

Python + pytest (PostgreSQL)

# tests/integration/test_user_repository.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.models import Base
from app.repositories import UserRepository

@pytest.fixture(scope="module")
def db_session():
    engine = create_engine("postgresql://test:test@localhost:5432/test_db")
    Base.metadata.create_all(engine)
    Session = sessionmaker(bind=engine)
    session = Session()
    yield session
    session.close()
    Base.metadata.drop_all(engine)

def test_create_and_get_user(db_session):
    repo = UserRepository(db_session)
    user = repo.create(name="Alice", email="alice@example.com")
    found = repo.find_by_email("alice@example.com")
    assert found.id == user.id
    assert found.name == "Alice"

1.2 API + DB 端到端集成

// tests/integration/user-api.test.ts
import request from 'supertest';
import { app } from '../../src/app';
import { prisma } from '../../src/db';

describe('User API + DB integration', () => {
  beforeAll(async () => {
    await prisma.$connect();
  });

  afterAll(async () => {
    await prisma.$disconnect();
  });

  beforeEach(async () => {
    await prisma.user.deleteMany();
  });

  it('POST creates user in database', async () => {
    const res = await request(app)
      .post('/api/users')
      .send({ name: 'Alice', email: 'alice@example.com' })
      .expect(201);

    // 验证数据库中确实存在
    const dbUser = await prisma.user.findUnique({ where: { id: res.body.data.id } });
    expect(dbUser).not.toBeNull();
    expect(dbUser?.name).toBe('Alice');
  });

  it('GET returns persisted user', async () => {
    await prisma.user.create({ data: { name: 'Bob', email: 'bob@example.com' } });

    const res = await request(app).get('/api/users').expect(200);
    expect(res.body.data.items).toHaveLength(1);
    expect(res.body.data.items[0].name).toBe('Bob');
  });

  it('DELETE removes user from database', async () => {
    const user = await prisma.user.create({
      data: { name: 'Charlie', email: 'charlie@example.com' },
    });

    await request(app).delete(`/api/users/${user.id}`).expect(200);

    const dbUser = await prisma.user.findUnique({ where: { id: user.id } });
    expect(dbUser).toBeNull();
  });
});

1.3 服务间调用集成

使用 WireMock 或 Mock Service Worker 模拟外部服务:

// tests/integration/order-service.test.ts
import { WireMock } from 'wiremock-captain';

describe('OrderService integration with PaymentService', () => {
  let wiremock: WireMock;

  beforeAll(async () => {
    wiremock = new WireMock('http://localhost:8080');
  });

  it('marks order as paid when payment succeeds', async () => {
    // Mock 支付服务成功响应
    await wiremock.stubFor({
      request: { method: 'POST', url: '/payments' },
      response: { status: 200, jsonBody: { success: true, transactionId: 'tx-123' } },
    });

    const order = await orderService.create({ userId: '1', items: [] });
    const paid = await orderService.pay(order.id, { method: 'credit_card' });

    expect(paid.status).toBe('paid');
  });

  it('keeps order pending when payment fails', async () => {
    await wiremock.stubFor({
      request: { method: 'POST', url: '/payments' },
      response: { status: 402, jsonBody: { error: 'INSUFFICIENT_FUNDS' } },
    });

    const order = await orderService.create({ userId: '1', items: [] });
    await expect(orderService.pay(order.id, { method: 'credit_card' })).rejects.toThrow(
      'Payment failed',
    );

    const refreshed = await orderService.getById(order.id);
    expect(refreshed.status).toBe('pending');
  });
});

2. 前端集成测试

2.1 组件 + 状态管理 + API 集成

使用 Testing Library + MSW (Mock Service Worker):

// tests/integration/UserList.test.tsx
import { r
Read more
@echovic
Ships withboss

Languages / 语言 / 言語 / 언어 / Idiomas / Langues: English · 中文 · 日本語 · 한국어 · Español · Français · Português This project is part of the AtomGit G-Star Incubation Program.

54438 skills16 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
544
Star history of echoVic/boss-skill on GitHub, a chart by star-history.com

Other skills on boss.

brainstorming
Skill

brainstorming

你是 Boss 的前置环节。用户通常只会丢过来一句话——可能是"帮我做个 XX"或者"我想搞个 XX"。你的工作是把这句话**翻译成下游流水线能跑起来的需求**。

@echovic@echovicInstall Skill

More skills from other plugins.

brainstorming
Skill
Popular
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
accessibility
Skill
Popular
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc1d293k
@affaan-m@affaan-mInstall Skill
compiler-commit
Skill
Popular

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about integration-testing.

Which coding agents can use integration-testing?
integration-testing installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.