测试专家 test-specialist

测试专家技能专注于JavaScript/TypeScript应用程序的全面测试解决方案,提供系统化的测试方法、缺陷分析框架和自动化工具。涵盖单元测试、集成测试、端到端测试编写,系统性缺陷分析与调试,安全漏洞与性能问题识别,测试覆盖率分析与优化。适用于软件质量保障、代码可靠性提升、自动化测试开发等场景。关键词:软件测试、JavaScript测试、TypeScript测试、单元测试、集成测试、端到端测试、缺陷分析、测试覆盖率、自动化测试、代码质量。

测试 0 次安装 0 次浏览 更新于 2/28/2026

name: test-specialist description: 该技能应用于编写测试用例、修复缺陷、分析代码潜在问题或提升JavaScript/TypeScript应用程序的测试覆盖率。适用于单元测试、集成测试、端到端测试、调试运行时错误、逻辑缺陷、性能问题、安全漏洞以及系统性代码分析。

测试专家

概述

为JavaScript/TypeScript应用程序应用系统化的测试方法和调试技术。本技能提供全面的测试策略、缺陷分析框架以及用于识别覆盖率差距和未测试代码的自动化工具。

核心能力

1. 编写测试用例

编写涵盖单元、集成和端到端场景的全面测试。

单元测试方法

使用AAA模式(Arrange-Act-Assert)构建测试:

describe('ExpenseCalculator', () => {
  describe('calculateTotal', () => {
    test('正确汇总支出金额', () => {
      // 准备
      const expenses = [
        { amount: 100, category: 'food' },
        { amount: 50, category: 'transport' },
        { amount: 25, category: 'entertainment' }
      ];

      // 执行
      const total = calculateTotal(expenses);

      // 断言
      expect(total).toBe(175);
    });

    test('处理空支出列表', () => {
      expect(calculateTotal([])).toBe(0);
    });

    test('处理负金额', () => {
      const expenses = [
        { amount: 100, category: 'food' },
        { amount: -50, category: 'refund' }
      ];
      expect(calculateTotal(expenses)).toBe(50);
    });
  });
});

关键原则:

  • 每个测试只测试一个行为
  • 覆盖正常路径、边界情况和错误条件
  • 使用描述性测试名称解释场景
  • 保持测试独立和隔离

集成测试方法

测试组件如何协同工作,包括数据库、API和服务交互:

describe('ExpenseAPI 集成测试', () => {
  beforeAll(async () => {
    await database.connect(TEST_DB_URL);
  });

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

  beforeEach(async () => {
    await database.clear();
    await seedTestData();
  });

  test('POST /expenses 创建支出并更新总额', async () => {
    const response = await request(app)
      .post('/api/expenses')
      .send({
        amount: 50,
        category: 'food',
        description: '午餐'
      })
      .expect(201);

    expect(response.body).toMatchObject({
      id: expect.any(Number),
      amount: 50,
      category: 'food'
    });

    // 验证数据库状态
    const total = await getTotalExpenses();
    expect(total).toBe(50);
  });
});

端到端测试方法

使用Playwright或Cypress等工具测试完整的用户工作流:

test('用户可以从头到尾跟踪支出', async ({ page }) => {
  // 导航到应用
  await page.goto('/');

  // 添加新支出
  await page.click('[data-testid="add-expense-btn"]');
  await page.fill('[data-testid="amount"]', '50.00');
  await page.selectOption('[data-testid="category"]', 'food');
  await page.fill('[data-testid="description"]', '午餐');
  await page.click('[data-testid="submit"]');

  // 验证支出出现在列表中
  await expect(page.locator('[data-testid="expense-item"]')).toContainText('午餐');
  await expect(page.locator('[data-testid="total"]')).toContainText('$50.00');
});

2. 系统性缺陷分析

应用结构化调试方法识别和修复问题。

五步分析流程

  1. 复现:可靠地复现缺陷

    • 记录触发缺陷的确切步骤
    • 识别所需环境/状态
    • 记录预期与实际行为
  2. 隔离:缩小问题范围

    • 通过代码路径进行二分查找
    • 创建最小复现案例
    • 移除无关依赖
  3. 根本原因分析:确定根本原因

    • 跟踪执行流程
    • 检查假设和前置条件
    • 审查最近更改(git blame)
  4. 修复实现:实施解决方案

    • 先编写失败测试(TDD)
    • 实施修复
    • 验证测试通过
  5. 验证:确保完整性

    • 运行完整测试套件
    • 测试边界情况
    • 验证无回归

常见缺陷模式

竞态条件:

// 测试并发操作
test('正确处理并发更新', async () => {
  const promises = Array.from({ length: 100 }, () =>
    incrementExpenseCount()
  );

  await Promise.all(promises);
  expect(getExpenseCount()).toBe(100);
});

空值/未定义错误:

// 测试空值安全性
test.each([null, undefined, '', 0, false])
  ('处理无效输入:%p', (input) => {
    expect(() => processExpense(input)).toThrow('无效支出');
  });

差一错误:

// 显式测试边界
describe('分页', () => {
  test('处理空列表', () => {
    expect(paginate([], 1, 10)).toEqual([]);
  });

  test('处理单个项目', () => {
    expect(paginate([item], 1, 10)).toEqual([item]);
  });

  test('处理部分项目的最后一页', () => {
    const items = Array.from({ length: 25 }, (_, i) => i);
    expect(paginate(items, 3, 10)).toHaveLength(5);
  });
});

3. 识别潜在问题

主动识别问题,防止其成为缺陷。

安全漏洞

测试常见安全问题:

describe('安全性', () => {
  test('防止SQL注入', async () => {
    const malicious = "'; DROP TABLE expenses; --";
    await expect(
      searchExpenses(malicious)
    ).resolves.not.toThrow();
  });

  test('清理描述中的XSS', () => {
    const xss = '<script>alert("xss")</script>';
    const expense = createExpense({ description: xss });
    expect(expense.description).not.toContain('<script>');
  });

  test('支出操作需要身份验证', async () => {
    await request(app)
      .post('/api/expenses')
      .send({ amount: 50 })
      .expect(401);
  });
});

性能问题

测试性能问题:

test('高效处理大型支出列表', () => {
  const largeList = Array.from({ length: 10000 }, (_, i) => ({
    amount: i,
    category: 'test'
  }));

  const start = performance.now();
  const total = calculateTotal(largeList);
  const duration = performance.now() - start;

  expect(duration).toBeLessThan(100); // 应在<100ms内完成
  expect(total).toBe(49995000);
});

逻辑错误

使用参数化测试捕获边界情况:

test.each([
  // [输入, 预期, 描述]
  [[10, 20, 30], 60, '正常正值'],
  [[0, 0, 0], 0, '全零值'],
  [[-10, 20, -5], 5, '正负混合值'],
  [[0.1, 0.2], 0.3, '小数精度'],
  [[Number.MAX_SAFE_INTEGER], Number.MAX_SAFE_INTEGER, '大数字'],
])('calculateTotal(%p) = %p (%s)', (amounts, expected, description) => {
  const expenses = amounts.map(amount => ({ amount, category: 'test' }));
  expect(calculateTotal(expenses)).toBeCloseTo(expected);
});

4. 测试覆盖率分析

使用自动化工具识别测试覆盖率差距。

查找未测试代码

运行提供的脚本识别没有测试的源文件:

python3 scripts/find_untested_code.py src

脚本将:

  • 扫描源目录中的所有代码文件
  • 识别哪些文件缺少对应的测试文件
  • 按类型(组件、服务、工具等)分类未测试文件
  • 优先处理最需要测试的文件

解释:

  • API/服务:高优先级 - 测试业务逻辑和数据操作
  • 模型:高优先级 - 测试数据验证和转换
  • 钩子:中优先级 - 测试有状态行为
  • 组件:中优先级 - 测试复杂UI逻辑
  • 工具:低优先级 - 根据需要测试复杂函数

分析覆盖率报告

生成覆盖率后运行覆盖率分析脚本:

# 生成覆盖率(使用Jest示例)
npm test -- --coverage

# 分析覆盖率差距
python3 scripts/analyze_coverage.py coverage/coverage-final.json

脚本识别:

  • 低于覆盖率阈值(默认80%)的文件
  • 语句、分支和函数覆盖率百分比
  • 需要改进的优先文件

覆盖率目标:

  • 关键路径:90%+ 覆盖率
  • 业务逻辑:85%+ 覆盖率
  • UI组件:75%+ 覆盖率
  • 工具:70%+ 覆盖率

5. 测试维护与质量

确保测试保持价值且易于维护。

测试代码质量原则

DRY(不要重复自己):

// 提取通用设置
function createTestExpense(overrides = {}) {
  return {
    amount: 50,
    category: 'food',
    description: '测试支出',
    date: new Date('2024-01-01'),
    ...overrides
  };
}

test('按类别过滤', () => {
  const expenses = [
    createTestExpense({ category: 'food' }),
    createTestExpense({ category: 'transport' }),
  ];
  // ...
});

清晰的测试数据:

// 差:魔法数字
expect(calculateDiscount(100, 0.15)).toBe(85);

// 好:命名常量
const ORIGINAL_PRICE = 100;
const DISCOUNT_RATE = 0.15;
const EXPECTED_PRICE = 85;
expect(calculateDiscount(ORIGINAL_PRICE, DISCOUNT_RATE)).toBe(EXPECTED_PRICE);

避免测试相互依赖:

// 差:测试依赖执行顺序
let sharedState;
test('测试1', () => {
  sharedState = { value: 1 };
});
test('测试2', () => {
  expect(sharedState.value).toBe(1); // 依赖测试1
});

// 好:独立测试
test('测试1', () => {
  const state = { value: 1 };
  expect(state.value).toBe(1);
});
test('测试2', () => {
  const state = { value: 1 };
  expect(state.value).toBe(1);
});

工作流决策树

遵循此决策树确定测试方法:

  1. 添加新功能?

    • 是 → 先写测试(TDD)
      • 编写失败测试
      • 实现功能
      • 验证测试通过
      • 重构
    • 否 → 转到步骤2
  2. 修复缺陷?

    • 是 → 应用缺陷分析流程
      • 复现缺陷
      • 编写展示缺陷的失败测试
      • 修复实现
      • 验证测试通过
    • 否 → 转到步骤3
  3. 改进测试覆盖率?

    • 是 → 使用覆盖率工具
      • 运行 find_untested_code.py 识别差距
      • 在覆盖率报告上运行 analyze_coverage.py
      • 优先处理关键路径
      • 为未测试代码编写测试
    • 否 → 转到步骤4
  4. 分析代码质量?

    • 是 → 系统性审查
      • 检查安全漏洞
      • 测试边界情况和错误处理
      • 验证性能特征
      • 审查错误处理

测试框架和工具

推荐技术栈

单元/集成测试:

  • Jest或Vitest作为测试运行器
  • Testing Library用于React组件
  • Supertest用于API测试
  • MSW(Mock Service Worker)用于API模拟

端到端测试:

  • Playwright或Cypress
  • 页面对象模型模式

覆盖率:

  • Istanbul(内置在Jest/Vitest中)
  • JSON格式的覆盖率报告

运行测试

# 运行所有测试
npm test

# 运行覆盖率测试
npm test -- --coverage

# 运行特定测试文件
npm test -- ExpenseCalculator.test.ts

# 运行监视模式
npm test -- --watch

# 运行端到端测试
npm run test:e2e

参考文档

有关详细模式和技术的参考:

  • references/testing_patterns.md - 全面的测试模式、最佳实践和代码示例
  • references/bug_analysis.md - 深入的缺陷分析框架、常见缺陷模式和调试技术

这些参考包含大量示例和高级技术。在以下情况下加载它们:

  • 处理复杂测试场景
  • 需要特定模式实现
  • 调试异常问题
  • 寻求特定情况的最佳实践

脚本

analyze_coverage.py

分析Jest/Istanbul覆盖率报告以识别差距:

python3 scripts/analyze_coverage.py [coverage-file]

如果未指定,自动查找常见的覆盖率文件位置。

输出:

  • 低于覆盖率阈值的文件
  • 语句、分支和函数覆盖率百分比
  • 需要改进的优先文件

find_untested_code.py

查找没有对应测试文件的源文件:

python3 scripts/find_untested_code.py [src-dir] [--pattern test|spec]

输出:

  • 源文件和测试文件总数
  • 测试文件覆盖率百分比
  • 按类型(API、服务、组件等)分类的未测试文件
  • 优先级建议

最佳实践总结

  1. 先写测试(TDD)添加新功能时
  2. 测试行为,而非实现 - 测试应在重构后仍然有效
  3. 保持测试独立 - 测试间无共享状态
  4. 使用描述性名称 - 测试名称应解释场景
  5. 覆盖边界情况 - 空值、空集、边界值、错误条件
  6. 模拟外部依赖 - 测试应快速可靠
  7. 保持高覆盖率 - 关键代码80%+
  8. 立即修复失败测试 - 绝不提交损坏的测试
  9. 重构测试 - 应用与生产代码相同的质量标准
  10. 使用工具 - 自动化覆盖率分析和差距识别