Skip to content

测试 API

本文档描述了 Trae 测试功能的 API 接口。

概述

测试 API 提供了单元测试、集成测试、端到端测试的运行、管理和报告功能,帮助开发者确保代码质量。

端点

运行测试

http
POST /api/testing/run

请求参数

参数类型必需描述
project_idstring项目 ID
test_typestring测试类型 (unit/integration/e2e/all)
test_filesarray指定测试文件
test_patternstring测试文件匹配模式
environmentstring测试环境 (development/staging/production)
parallelboolean是否并行运行
coverageboolean是否生成覆盖率报告
watchboolean是否监听文件变化

请求示例

json
{
  "project_id": "proj_123",
  "test_type": "unit",
  "test_pattern": "**/*.test.js",
  "environment": "development",
  "parallel": true,
  "coverage": true,
  "watch": false
}

响应

json
{
  "test_run_id": "run_456",
  "status": "running",
  "started_at": "2024-01-01T12:00:00Z",
  "estimated_duration": 120,
  "test_count": {
    "total": 156,
    "unit": 120,
    "integration": 30,
    "e2e": 6
  },
  "progress": {
    "completed": 0,
    "running": 5,
    "pending": 151
  }
}

获取测试运行状态

http
GET /api/testing/runs/{test_run_id}

响应

json
{
  "test_run_id": "run_456",
  "project_id": "proj_123",
  "status": "completed",
  "started_at": "2024-01-01T12:00:00Z",
  "completed_at": "2024-01-01T12:02:30Z",
  "duration": 150,
  "summary": {
    "total": 156,
    "passed": 148,
    "failed": 6,
    "skipped": 2,
    "success_rate": 94.87
  },
  "coverage": {
    "lines": 85.6,
    "functions": 92.3,
    "branches": 78.9,
    "statements": 86.2
  },
  "performance": {
    "average_duration": 0.96,
    "slowest_test": {
      "name": "integration test for user authentication",
      "duration": 5.2,
      "file": "tests/auth.integration.test.js"
    },
    "fastest_test": {
      "name": "utility function validation",
      "duration": 0.02,
      "file": "tests/utils.test.js"
    }
  }
}

获取测试结果详情

http
GET /api/testing/runs/{test_run_id}/results?status={status}&limit={limit}&offset={offset}

查询参数

参数类型必需描述
statusstring过滤状态 (passed/failed/skipped)
limitnumber返回数量限制
offsetnumber偏移量
filestring过滤文件
suitestring过滤测试套件

响应

json
{
  "test_run_id": "run_456",
  "total": 156,
  "results": [
    {
      "test_id": "test_789",
      "name": "should authenticate user with valid credentials",
      "suite": "Authentication",
      "file": "tests/auth.test.js",
      "status": "passed",
      "duration": 1.2,
      "started_at": "2024-01-01T12:00:05Z",
      "completed_at": "2024-01-01T12:00:06Z",
      "assertions": {
        "total": 5,
        "passed": 5,
        "failed": 0
      }
    },
    {
      "test_id": "test_790",
      "name": "should reject invalid password",
      "suite": "Authentication",
      "file": "tests/auth.test.js",
      "status": "failed",
      "duration": 0.8,
      "started_at": "2024-01-01T12:00:07Z",
      "completed_at": "2024-01-01T12:00:08Z",
      "error": {
        "message": "Expected status code 401 but received 500",
        "stack": "AssertionError: Expected status code 401 but received 500\n    at test (/tests/auth.test.js:45:12)",
        "type": "AssertionError"
      },
      "assertions": {
        "total": 3,
        "passed": 2,
        "failed": 1
      }
    }
  ]
}

停止测试运行

http
POST /api/testing/runs/{test_run_id}/stop

响应

json
{
  "test_run_id": "run_456",
  "status": "stopped",
  "stopped_at": "2024-01-01T12:01:30Z",
  "reason": "user_requested",
  "partial_results": {
    "completed": 45,
    "running": 3,
    "pending": 108
  }
}

获取测试覆盖率报告

http
GET /api/testing/runs/{test_run_id}/coverage

响应

json
{
  "test_run_id": "run_456",
  "overall": {
    "lines": 85.6,
    "functions": 92.3,
    "branches": 78.9,
    "statements": 86.2
  },
  "files": [
    {
      "file_path": "src/auth/authentication.js",
      "lines": {
        "total": 120,
        "covered": 108,
        "percentage": 90.0
      },
      "functions": {
        "total": 15,
        "covered": 14,
        "percentage": 93.3
      },
      "branches": {
        "total": 24,
        "covered": 20,
        "percentage": 83.3
      },
      "uncovered_lines": [45, 67, 89, 102, 115, 118],
      "uncovered_functions": ["handleEdgeCase"],
      "uncovered_branches": [
        {
          "line": 45,
          "branch": "else",
          "condition": "user.isActive === false"
        }
      ]
    }
  ],
  "directories": [
    {
      "path": "src/auth/",
      "lines": 88.5,
      "functions": 91.2,
      "branches": 82.1,
      "statements": 89.3
    },
    {
      "path": "src/utils/",
      "lines": 95.2,
      "functions": 98.1,
      "branches": 89.7,
      "statements": 96.0
    }
  ]
}

获取测试历史

http
GET /api/testing/history?project_id={project_id}&limit={limit}&offset={offset}

查询参数

参数类型必需描述
project_idstring项目 ID
limitnumber返回数量限制
offsetnumber偏移量
date_fromstring开始日期
date_tostring结束日期
statusstring过滤状态

响应

json
{
  "project_id": "proj_123",
  "total": 45,
  "runs": [
    {
      "test_run_id": "run_456",
      "started_at": "2024-01-01T12:00:00Z",
      "completed_at": "2024-01-01T12:02:30Z",
      "duration": 150,
      "status": "completed",
      "trigger": "manual",
      "triggered_by": "user_123",
      "summary": {
        "total": 156,
        "passed": 148,
        "failed": 6,
        "skipped": 2,
        "success_rate": 94.87
      },
      "coverage": {
        "lines": 85.6,
        "change": "+2.3"
      }
    }
  ],
  "trends": {
    "success_rate": {
      "current": 94.87,
      "previous": 92.56,
      "trend": "improving"
    },
    "coverage": {
      "current": 85.6,
      "previous": 83.3,
      "trend": "improving"
    },
    "duration": {
      "current": 150,
      "previous": 165,
      "trend": "improving"
    }
  }
}

配置测试设置

http
PUT /api/testing/projects/{project_id}/settings

请求参数

json
{
  "frameworks": {
    "unit": "jest",
    "integration": "jest",
    "e2e": "playwright"
  },
  "patterns": {
    "unit": ["**/*.test.js", "**/*.spec.js"],
    "integration": ["**/*.integration.test.js"],
    "e2e": ["**/*.e2e.test.js"]
  },
  "coverage": {
    "enabled": true,
    "threshold": {
      "lines": 80,
      "functions": 85,
      "branches": 75,
      "statements": 80
    },
    "exclude": ["node_modules/**", "dist/**", "**/*.config.js"]
  },
  "parallel": {
    "enabled": true,
    "max_workers": 4
  },
  "timeout": {
    "unit": 5000,
    "integration": 30000,
    "e2e": 60000
  },
  "environment": {
    "NODE_ENV": "test",
    "API_URL": "http://localhost:3001",
    "DATABASE_URL": "sqlite://memory"
  },
  "notifications": {
    "on_failure": true,
    "on_success": false,
    "on_coverage_drop": true,
    "channels": ["email", "slack"]
  }
}

响应

json
{
  "project_id": "proj_123",
  "settings": {
    "frameworks": {
      "unit": "jest",
      "integration": "jest",
      "e2e": "playwright"
    },
    "patterns": {
      "unit": ["**/*.test.js", "**/*.spec.js"],
      "integration": ["**/*.integration.test.js"],
      "e2e": ["**/*.e2e.test.js"]
    },
    "coverage": {
      "enabled": true,
      "threshold": {
        "lines": 80,
        "functions": 85,
        "branches": 75,
        "statements": 80
      }
    }
  },
  "updated_at": "2024-01-01T12:00:00Z"
}

获取测试统计

http
GET /api/testing/projects/{project_id}/statistics?period={period}

查询参数

参数类型必需描述
periodstring统计周期 (day/week/month/quarter/year)

响应

json
{
  "project_id": "proj_123",
  "period": "month",
  "summary": {
    "total_runs": 45,
    "total_tests": 7020,
    "average_success_rate": 93.2,
    "average_coverage": 84.1,
    "average_duration": 142
  },
  "trends": {
    "success_rate": [
      { "date": "2024-01-01", "value": 91.5 },
      { "date": "2024-01-02", "value": 92.1 },
      { "date": "2024-01-03", "value": 93.8 }
    ],
    "coverage": [
      { "date": "2024-01-01", "value": 82.3 },
      { "date": "2024-01-02", "value": 83.1 },
      { "date": "2024-01-03", "value": 85.6 }
    ],
    "duration": [
      { "date": "2024-01-01", "value": 165 },
      { "date": "2024-01-02", "value": 158 },
      { "date": "2024-01-03", "value": 150 }
    ]
  },
  "test_types": {
    "unit": {
      "count": 5400,
      "success_rate": 95.2,
      "average_duration": 0.8
    },
    "integration": {
      "count": 1350,
      "success_rate": 89.6,
      "average_duration": 3.2
    },
    "e2e": {
      "count": 270,
      "success_rate": 85.1,
      "average_duration": 12.5
    }
  },
  "flaky_tests": [
    {
      "name": "user login flow",
      "file": "tests/auth.e2e.test.js",
      "failure_rate": 15.2,
      "last_failure": "2024-01-03T10:30:00Z"
    }
  ]
}

WebSocket 实时更新

javascript
// 连接 WebSocket 获取实时测试更新
const ws = new WebSocket('wss://api.trae.ai/testing/ws');

ws.onopen = () => {
  // 订阅测试运行更新
  ws.send(JSON.stringify({
    type: 'subscribe',
    channel: 'test_run',
    test_run_id: 'run_456'
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  
  switch (data.type) {
    case 'test_started':
      console.log(`测试开始: ${data.test_name}`);
      break;
      
    case 'test_completed':
      console.log(`测试完成: ${data.test_name} - ${data.status}`);
      if (data.status === 'failed') {
        console.error(`错误: ${data.error.message}`);
      }
      break;
      
    case 'run_progress':
      console.log(`进度: ${data.completed}/${data.total} (${data.percentage}%)`);
      break;
      
    case 'run_completed':
      console.log(`测试运行完成: ${data.summary.passed}/${data.summary.total} 通过`);
      break;
  }
};

示例

运行单元测试

javascript
// 运行项目的所有单元测试
const runTests = async (projectId) => {
  const response = await fetch('/api/testing/run', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer your-token'
    },
    body: JSON.stringify({
      project_id: projectId,
      test_type: 'unit',
      parallel: true,
      coverage: true
    })
  });
  
  const testRun = await response.json();
  console.log(`测试运行已启动: ${testRun.test_run_id}`);
  
  // 轮询测试状态
  const checkStatus = async () => {
    const statusResponse = await fetch(`/api/testing/runs/${testRun.test_run_id}`);
    const status = await statusResponse.json();
    
    console.log(`状态: ${status.status}, 进度: ${status.progress?.completed || 0}/${status.test_count?.total || 0}`);
    
    if (status.status === 'completed') {
      console.log('测试完成!');
      console.log(`成功率: ${status.summary.success_rate}%`);
      console.log(`覆盖率: ${status.coverage.lines}%`);
      return status;
    } else if (status.status === 'failed') {
      console.error('测试运行失败');
      return status;
    }
    
    // 继续轮询
    setTimeout(checkStatus, 2000);
  };
  
  return checkStatus();
};

// 使用示例
runTests('proj_123');

获取失败测试详情

javascript
// 获取失败的测试详情
const getFailedTests = async (testRunId) => {
  const response = await fetch(`/api/testing/runs/${testRunId}/results?status=failed`);
  const results = await response.json();
  
  console.log(`找到 ${results.results.length} 个失败的测试:`);
  
  results.results.forEach(test => {
    console.log(`\n❌ ${test.name}`);
    console.log(`   文件: ${test.file}`);
    console.log(`   套件: ${test.suite}`);
    console.log(`   错误: ${test.error.message}`);
    
    if (test.error.stack) {
      console.log(`   堆栈:\n${test.error.stack}`);
    }
  });
};

// 使用示例
getFailedTests('run_456');

生成测试报告

javascript
// 生成详细的测试报告
const generateTestReport = async (testRunId) => {
  // 获取测试运行详情
  const runResponse = await fetch(`/api/testing/runs/${testRunId}`);
  const run = await runResponse.json();
  
  // 获取覆盖率报告
  const coverageResponse = await fetch(`/api/testing/runs/${testRunId}/coverage`);
  const coverage = await coverageResponse.json();
  
  // 获取所有测试结果
  const resultsResponse = await fetch(`/api/testing/runs/${testRunId}/results?limit=1000`);
  const results = await resultsResponse.json();
  
  // 生成报告
  const report = {
    summary: {
      run_id: testRunId,
      duration: run.duration,
      started_at: run.started_at,
      completed_at: run.completed_at,
      total_tests: run.summary.total,
      passed: run.summary.passed,
      failed: run.summary.failed,
      skipped: run.summary.skipped,
      success_rate: run.summary.success_rate
    },
    coverage: {
      overall: coverage.overall,
      by_directory: coverage.directories
    },
    failed_tests: results.results.filter(test => test.status === 'failed'),
    slow_tests: results.results
      .filter(test => test.duration > 2)
      .sort((a, b) => b.duration - a.duration)
      .slice(0, 10),
    performance: {
      average_duration: run.performance.average_duration,
      slowest_test: run.performance.slowest_test,
      fastest_test: run.performance.fastest_test
    }
  };
  
  console.log('📊 测试报告');
  console.log('='.repeat(50));
  console.log(`运行时间: ${report.summary.duration}s`);
  console.log(`总测试数: ${report.summary.total_tests}`);
  console.log(`✅ 通过: ${report.summary.passed}`);
  console.log(`❌ 失败: ${report.summary.failed}`);
  console.log(`⏭️  跳过: ${report.summary.skipped}`);
  console.log(`📈 成功率: ${report.summary.success_rate}%`);
  console.log(`📊 代码覆盖率: ${report.coverage.overall.lines}%`);
  
  if (report.failed_tests.length > 0) {
    console.log('\n❌ 失败的测试:');
    report.failed_tests.forEach(test => {
      console.log(`  - ${test.name} (${test.file})`);
    });
  }
  
  if (report.slow_tests.length > 0) {
    console.log('\n🐌 最慢的测试:');
    report.slow_tests.forEach(test => {
      console.log(`  - ${test.name}: ${test.duration}s`);
    });
  }
  
  return report;
};

// 使用示例
generateTestReport('run_456');

配置持续集成

javascript
// 配置 CI/CD 测试流水线
const setupCITesting = async (projectId) => {
  const settings = {
    frameworks: {
      unit: 'jest',
      integration: 'jest',
      e2e: 'playwright'
    },
    patterns: {
      unit: ['src/**/*.test.js', 'src/**/*.spec.js'],
      integration: ['tests/integration/**/*.test.js'],
      e2e: ['tests/e2e/**/*.test.js']
    },
    coverage: {
      enabled: true,
      threshold: {
        lines: 80,
        functions: 85,
        branches: 75,
        statements: 80
      },
      exclude: [
        'node_modules/**',
        'dist/**',
        'coverage/**',
        '**/*.config.js',
        'tests/fixtures/**'
      ]
    },
    parallel: {
      enabled: true,
      max_workers: 4
    },
    timeout: {
      unit: 5000,
      integration: 30000,
      e2e: 60000
    },
    environment: {
      NODE_ENV: 'test',
      CI: 'true',
      API_URL: 'http://localhost:3001',
      DATABASE_URL: 'sqlite://memory'
    },
    notifications: {
      on_failure: true,
      on_success: false,
      on_coverage_drop: true,
      channels: ['email', 'slack']
    }
  };
  
  const response = await fetch(`/api/testing/projects/${projectId}/settings`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer your-token'
    },
    body: JSON.stringify(settings)
  });
  
  const result = await response.json();
  console.log('CI 测试配置已更新:', result.updated_at);
  
  return result;
};

// 使用示例
setupCITesting('proj_123');

监控测试趋势

javascript
// 监控测试质量趋势
const monitorTestTrends = async (projectId) => {
  const response = await fetch(`/api/testing/projects/${projectId}/statistics?period=month`);
  const stats = await response.json();
  
  console.log('📈 测试趋势分析 (最近一个月)');
  console.log('='.repeat(50));
  
  // 成功率趋势
  const successRateTrend = stats.trends.success_rate;
  const latestSuccessRate = successRateTrend[successRateTrend.length - 1].value;
  const firstSuccessRate = successRateTrend[0].value;
  const successRateChange = latestSuccessRate - firstSuccessRate;
  
  console.log(`平均成功率: ${stats.summary.average_success_rate}%`);
  console.log(`成功率变化: ${successRateChange > 0 ? '+' : ''}${successRateChange.toFixed(1)}%`);
  
  // 覆盖率趋势
  const coverageTrend = stats.trends.coverage;
  const latestCoverage = coverageTrend[coverageTrend.length - 1].value;
  const firstCoverage = coverageTrend[0].value;
  const coverageChange = latestCoverage - firstCoverage;
  
  console.log(`平均覆盖率: ${stats.summary.average_coverage}%`);
  console.log(`覆盖率变化: ${coverageChange > 0 ? '+' : ''}${coverageChange.toFixed(1)}%`);
  
  // 性能趋势
  const durationTrend = stats.trends.duration;
  const latestDuration = durationTrend[durationTrend.length - 1].value;
  const firstDuration = durationTrend[0].value;
  const durationChange = latestDuration - firstDuration;
  
  console.log(`平均运行时间: ${stats.summary.average_duration}s`);
  console.log(`运行时间变化: ${durationChange > 0 ? '+' : ''}${durationChange}s`);
  
  // 不稳定测试
  if (stats.flaky_tests.length > 0) {
    console.log('\n⚠️  不稳定的测试:');
    stats.flaky_tests.forEach(test => {
      console.log(`  - ${test.name}: ${test.failure_rate}% 失败率`);
    });
  }
  
  // 测试类型分析
  console.log('\n📊 测试类型分析:');
  Object.entries(stats.test_types).forEach(([type, data]) => {
    console.log(`  ${type}: ${data.count} 个测试, ${data.success_rate}% 成功率, 平均 ${data.average_duration}s`);
  });
  
  return stats;
};

// 使用示例
monitorTestTrends('proj_123');

您的终极 AI 驱动 IDE 学习指南