mcpField
T
test-automation

test-automation

github.com/vladm3105测试与质量1757 次安装1 天前更新
代码仓库

关于 test-automation

test-automation 是将 SDD 文档转换为可执行测试并跟踪覆盖率的测试技能,面向需要把实现与需求、场景及契约对应起来的团队。它支持从 BDD、需求和契约等生成多类测试,并提供追溯与覆盖差距分析。

主要功能

  1. 01从 BDD 场景生成测试
  2. 02从需求生成单元测试
  3. 03生成集成与契约测试
  4. 04分析代码及需求覆盖率
  5. 05生成测试数据与覆盖报告

适用场景

  1. 01将 Given-When-Then 场景转为测试套件
  2. 02按需求文档创建单元测试
  3. 03验证 API 契约并检测破坏性变更
  4. 04定位未覆盖的需求、场景或代码路径

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vladm3105/aidoc-flow-framework --skill test-automation

安装后在 Claude Code 中输入/test-automation确认已加载。

详细介绍

test-automation

描述:自动生成测试、执行 BDD、分析覆盖率和进行契约测试

类别:质量保证与测试

复杂度:高(多框架集成 + 覆盖率分析)


用途

将 SDD 工件(BDD 场景、需求、契约)转换为可执行的测试套件,并全面跟踪覆盖率。确保代码实现符合规范和契约。


功能

1. BDD 场景生成
  • 解析 BDD 文档(Given-When-Then 格式)
  • 生成 pytest-bdd 测试文件
  • 将场景映射到测试函数
  • 处理带有示例的场景大纲
  • 根据 Given 子句生成测试固件
2. 单元测试生成
  • 根据需求(REQ 文档)生成单元测试
  • 根据 SPEC 文档创建测试模板
  • 为依赖项生成模拟对象
  • 生成参数化测试
  • 根据需求识别边缘情况
3. 集成测试生成
  • 根据 CTR 契约生成 API 集成测试
  • 根据数据规范生成数据库集成测试
  • 服务交互测试
  • 根据 IMPL 文档生成端到端工作流测试
4. 契约测试
  • 根据 CTR YAML 生成消费者驱动的契约测试
  • 架构验证测试
  • API 契约合规性验证
  • 检测破坏性变更
  • 根据契约生成模拟服务
5. 测试覆盖率分析
  • 行覆盖率、分支覆盖率、路径覆盖率
  • 需求覆盖率映射(REQ → 测试)
  • 场景覆盖率跟踪(BDD → 测试)
  • 契约覆盖率验证(CTR → 测试)
  • 识别覆盖率缺口
6. 性能测试生成
  • 根据性能需求生成负载测试场景
  • 压力测试配置
  • 生成基准测试
  • SLA 验证测试
7. 测试数据生成
  • 根据规范生成逼真的测试数据
  • 生成边缘情况数据
  • 边界值分析
  • 为负向测试生成无效输入

测试生成工作流

graph TD
    A[SDD Artifacts] --> B{Artifact Type}
    B -->|BDD| C[Generate BDD Tests]
    B -->|REQ| D[Generate Unit Tests]
    B -->|CTR| E[Generate Contract Tests]
    B -->|SPEC| F[Generate Integration Tests]

    C --> G[pytest-bdd Test Suite]
    D --> H[pytest Unit Test Suite]
    E --> I[Contract Test Suite]
    F --> J[Integration Test Suite]

    G --> K[Execute Tests]
    H --> K
    I --> K
    J --> K

    K --> L[Coverage Analysis]
    L --> M{Coverage Goals Met?}
    M -->|No| N[Identify Gaps]
    M -->|Yes| O[Generate Report]

    N --> P[Generate Additional Tests]
    P --> K

    O --> Q[Update Traceability Matrix]

使用说明

根据 BDD 场景生成测试
# Input: BDD/authentication_scenarios.md
# Output: tests/bdd/test_authentication.py

test-automation generate-bdd \
  --input BDD/authentication_scenarios.md \
  --output tests/bdd/test_authentication.py \
  --framework pytest-bdd

生成的测试结构:

import pytest
from pytest_bdd import scenarios, given, when, then, parsers

scenarios('{project_root}/BDD/authentication_scenarios.md')

@given('a user with valid credentials')
def user_with_valid_credentials(context):
    context.user = create_test_user(
        username='testuser',
        password='ValidP@ssw0rd'
    )

@when('the user attempts to login')
def user_attempts_login(context):
    context.response = login_api(
        username=context.user.username,
        password=context.user.password
    )

@then('the login should succeed')
def login_succeeds(context):
    assert context.response.status_code == 200
    assert 'access_token' in context.response.json()
根据需求生成单元测试
# Input: reqs/requirements.md (REQ-AUTH-01)
# Output: tests/unit/test_auth_requirements.py

test-automation generate-unit \
  --input reqs/requirements.md \
  --filter REQ-AUTH-* \
  --output tests/unit/test_auth_requirements.py

生成的测试结构:

import pytest
from auth.service import AuthService

class TestREQ_AUTH_001:
    """Test REQ-AUTH-01: Password must be 8-20 characters"""

    def test_password_minimum_length(self):
        """Verify password < 8 characters is rejected"""
        result = AuthService.validate_password('Short1!')
        assert not result.valid
        assert 'minimum 8 characters' in result.error

    def test_password_maximum_length(self):
        """Verify password > 20 characters is rejected"""
        result = AuthService.validate_password('VeryLongPassword123456789!')
        assert not result.valid
        assert 'maximum 20 characters' in result.error

    def test_password_valid_length(self):
        """Verify password 8-20 characters is accepted"""
        result = AuthService.validate_password('ValidP@ss1')
        assert result.valid
生成契约测试
# Input: ctrs/CTR-USER-V1.yaml
# Output: tests/contract/test_user_contract.py

test-automation generate-contract \
  --input ctrs/CTR-USER-V1.yaml \
  --output tests/contract/test_user_contract.py \
  --provider user-service

生成的测试结构:

import pytest
from pact import Consumer, Provider, Like, EachLike

@pytest.fixture
def pact():
    return Consumer('user-client').has_pact_with(
        Provider('user-service')
    )

def test_create_user_contract(pact):
    expected = {
        'user_id': Like('123e4567-e89b-12d3-a456-426614174000'),
        'username': Like('testuser'),
        'email': Like('[email protected]'),
        'created_at': Like('2025-01-01T00:00:00Z')
    }

    (pact
     .given('user database is empty')
     .upon_receiving('a request to create a user')
     .with_request('POST', '/api/users')
     .will_respond_with(201, body=expected))

    with pact:
        result = user_api.create_user({
            'username': 'testuser',
            'email': '[email protected]',
            'password': 'SecureP@ss123'
        })
        assert result.status_code == 201
执行测试套件并统计覆盖率
# Run all tests with coverage
test-automation run \
  --coverage \
  --coverage-report html \
  --traceability

# Run specific test category
test-automation run --category bdd
test-automation run --category unit
test-automation run --category contract

# Run tests for specific requirement
test-automation run --requirement REQ-AUTH-01
生成覆盖率报告
test-automation coverage-report \
  --format html \
  --output reports/coverage \
  --include-traceability

生成的报告包括:

  • 总体覆盖率百分比
  • 按需求统计的覆盖率(REQ → 测试映射)
  • 按 BDD 场景统计的覆盖率
  • 按契约端点统计的覆盖率
  • 未测试的代码路径
  • 可追溯性矩阵

测试模板

BDD 测试模板(pytest-bdd)
"""
BDD Tests for {feature_name}
Generated from: {bdd_document_path}
Traceability: {requirement_ids}
"""

import pytest
from pytest_bdd import scenarios, given, when, then, parsers

# Load all scenarios from BDD document
scenarios('{bdd_document_path}')

# Fixtures
@pytest.fixture
def context():
    """Test context for sharing state between steps"""
    return {}

# Given steps
@given(parsers.parse('{step_description}'))
def step_given(context, {parameters}):
    # Setup preconditions
    pass

# When steps
@when(parsers.parse('{step_description}'))
def step_when(context, {parameters}):
    # Execute action
    pass

# Then steps
@then(parsers.parse('{step_description}'))
def step_then(context, {parameters}):
    # Verify outcome
    pass
单元测试模板(pytest)
"""
Unit Tests for {requirement_id}
Requirement: {requirement_description}
Source: {requirement_document}
"""

import pytest
from {module} import {class_or_function}

class Test_{requirement_id}:
    """Test suite for {requirement_id}"""

    @pytest.fixture
    def setup(self):
        """Setup test fixtures"""
        return {class_or_function}()

    def test_positive_case(self, setup):
        """Test expected behavior"""
        result = setup.method({valid_input})
        assert result == {expected_output}

    def test_boundary_case_min(self, setup):
        """Test minimum boundary value"""
        result = setup.method({min_value})
        assert {assertion}

    def test_boundary_case_max(self, setup):
        """Test maximum boundary value"""
        result = setup.method({max_value})
        assert {assertion}

    def test_invalid_input(self, setup):
        """Test error handling"""
        with pytest.raises({expected_exception}):
            setup.method({invalid_input})
集成测试模板
"""
Integration Tests for {component_name}
Specification: {spec_document}
Contracts: {contract_ids}
"""

import pytest
from {test_client} import TestClient
from {app} import app

@pytest.fixture
def client():
    """Test client for API integration tests"""
    return TestClient(app)

class Test_{component_name}_Integration:
    """Integration test suite for {component_name}"""

    def test_api_endpoint_{operation}(self, client):
        """Test {operation} operation"""
        # Arrange
        test_data = {test_payload}

        # Act
        response = client.{http_method}(
            '{endpoint_path}',
            json=test_data
        )

        # Assert
        assert response.status_code == {expected_status}
        assert response.json() == {expected_response}
契约测试模板(Pact)
"""
Contract Tests for {service_name}
Contract: {contract_id}
Provider: {provider_service}
Consumer: {consumer_service}
"""

import pytest
from pact import Consumer, Provider, Like, EachLike, Term

@pytest.fixture
def pact():
    return Consumer('{consumer_service}').has_pact_with(
        Provider('{provider_service}'),
        host_name='localhost',
        port=1234
    )

class Test_{contract_id}:
    """Contract test suite for {contract_id}"""

    def test_{operation}_contract(self, pact):
        """Test {operation} contract"""
        # Define expected interaction
        expected = {expected_schema}

        # Setup pact
        (pact
         .given('{provider_state}')
         .upon_receiving('{interaction_description}')
         .with_request('{method}', '{path}')
         .will_respond_with({status}, body=expected))

        # Execute and verify
        with pact:
            result = {client_call}
            assert result == expected

覆盖率分析

需求覆盖率
# Map requirements to tests
REQ-AUTH-01 → [
    test_password_minimum_length,
    test_password_maximum_length,
    test_password_valid_length
] (100% covered)

REQ-AUTH-002 → [
    test_password_uppercase_required,
    test_password_lowercase_required
] (50% covered - missing number requirement test)
BDD 场景覆盖率
# Map BDD scenarios to test execution
BDD-LOGIN-001: User Login Success → PASS (covered)
BDD-LOGIN-002: User Login Failure → PASS (covered)
BDD-LOGIN-003: Account Lockout → NOT TESTED (0% covered)
契约覆盖率
# Map contract endpoints to tests
POST /api/users → test_create_user_contract (100% covered)
GET /api/users/{id} → test_get_user_contract (100% covered)
PUT /api/users/{id} → NOT TESTED (0% covered)
DELETE /api/users/{id} → NOT TESTED (0% covered)
覆盖率目标
  • 单元测试覆盖率:行覆盖率 ≥90%,分支覆盖率 ≥80%
  • 需求覆盖率:100% 的 MUST 需求均已测试
  • BDD 场景覆盖率:100% 的场景均已执行
  • 契约覆盖率:100% 的契约操作均已测试
  • 集成覆盖率:≥85% 的集成路径均已测试

测试数据生成

根据需求生成
# REQ-USER-001: Username must be 3-20 alphanumeric characters

test_data = {
    'valid': ['abc', 'user123', 'JohnDoe2025', 'a'.repeat(20)],
    'boundary_min': 'ab',  # Too short
    'boundary_max': 'a'.repeat(21),  # Too long
    'invalid': ['ab', 'user@123', 'John Doe', '123', ''],
    'edge_cases': ['aaa', 'zzz', '000', '999']
}
根据契约生成
# CTR-USER-V1: User schema

test_data = {
    'valid_user': {
        'username': 'testuser',
        'email': '[email protected]',
        'age': 25
    },
    'missing_required_field': {
        'username': 'testuser'
        # Missing email
    },
    'invalid_type': {
        'username': 123,  # Should be string
        'email': '[email protected]',
        'age': 'twenty-five'  # Should be integer
    }
}

工具访问

所需工具:

  • Read:读取 SDD 工件(BDD、REQ、CTR、SPEC)
  • Write:生成测试文件
  • Edit:更新现有测试
  • Bash:执行测试框架(pytest、pact)
  • Glob:查找测试文件和工件
  • Grep:搜索需求和场景

所需库:

  • pytest
  • pytest-bdd
  • pytest-cov
  • pact-python(用于契约测试)
  • hypothesis(用于基于属性的测试)
  • faker(用于生成测试数据)

集成点

与 doc-flow 集成
  • 创建 BDD/REQ 文档时自动生成测试
  • 规范变更时更新测试
  • 验证测试的可追溯性
与 code-review 配合
  • 验证测试覆盖率是否达到最低阈值
  • 找出未测试的代码路径
  • 为新代码建议测试用例
与 contract-tester 配合
  • 执行契约验证测试
  • 验证 API 是否符合 CTR 文档
  • 检测破坏性变更
与 doc-validator 配合
  • 验证测试可追溯性引用
  • 确保所有需求都有对应测试
  • 检查测试文档质量

错误处理

BDD 场景解析错误
ACTION: Validate Given-When-Then format
SUGGEST: Correct scenario syntax
VERIFY: Scenario parseable by pytest-bdd
UPDATE: BDD document if needed
测试生成失败
ACTION: Identify missing dependencies or invalid specifications
SUGGEST: Fix specification or install required libraries
VERIFY: Generated test is syntactically correct
UPDATE: Test template if needed
检测到覆盖率缺口
ACTION: Identify untested requirements/scenarios
SUGGEST: Generate additional test cases
VERIFY: New tests increase coverage
UPDATE: Traceability matrix
契约测试失败
ACTION: Compare expected vs actual contract
SUGGEST: Update implementation or contract
VERIFY: Provider and consumer agree on contract
UPDATE: Contract version if breaking change

最佳实践

  1. 在实现之前生成测试(TDD 方法)
  2. 在需求与测试之间保持 1:1 映射
  3. 使用描述性测试名称,引用需求 ID
  4. 参数化测试,覆盖多种输入场景
  5. 在单元测试中模拟外部依赖
  6. 在集成测试中使用真实集成
  7. 保持测试相互独立(不共享状态)
  8. 在每次提交时于 CI/CD 中运行测试
  9. 长期跟踪覆盖率趋势
  10. 在规格变更时更新测试

限制

  1. 无法为未定义的需求生成测试
  2. 测试质量取决于规格的清晰度
  3. 生成的测试需要人工审查
  4. 性能测试的负载配置文件需要手动调整
  5. 复杂的业务逻辑可能需要自定义测试逻辑
  6. 契约测试需要服务提供方配合

未来增强

  1. 从自然语言生成测试用例的 AI 驱动功能
  2. 用于评估测试有效性的变异测试
  3. 可视化测试结果仪表板
  4. 自动修复测试(在代码变更时更新测试)
  5. 预测性覆盖率分析
  6. 根据风险确定测试优先级
  7. 持续优化测试

成功标准

  • 单元测试覆盖率 ≥90%
  • 需求测试覆盖率(MUST 要求)达到 100%
  • BDD 场景执行率达到 100%
  • 契约操作覆盖率达到 100%
  • 集成测试覆盖率 ≥85%
  • 关键路径无遗漏测试
  • 测试执行时间 < 10 分钟
  • 所有测试文档和可追溯性矩阵均包含文档控制部分,其中包括:
    • 项目元数据(名称、版本、日期、所有者、编制者、状态)
    • 用于跟踪测试计划变更的文档修订历史表

备注

  • 生成的测试需要人工审查和完善
  • 测试数据应按测试隔离(不共享测试固件)
  • 契约测试需要与服务提供方协调
  • 覆盖率报告保存在 reports/coverage/
  • 测试执行日志保存在 logs/test-runs/
  • 每次测试运行后更新可追溯性矩阵

评论

支持 Markdown