mcpField
T
test-automation

test-automation

github.com/vladm3105テスト・品質1757 回インストール1 日前に更新
リポジトリ

test-automation について

test-automationは、SDD成果物から実行可能なテストを生成し、カバレッジを追跡するテスト向けスキルです。実装と要件、シナリオ、契約を対応づけたいチーム向けに、複数種のテスト生成とトレーサビリティ、ギャップ分析を提供します。

主な機能

  1. 01BDDシナリオからのテスト生成
  2. 02要件からのユニットテスト生成
  3. 03統合テストと契約テストの作成
  4. 04コードと要件のカバレッジ分析
  5. 05テストデータとカバレッジレポートの生成

活用シーン

  1. 01Given-When-Thenシナリオのテストスイート化
  2. 02要件文書からのユニットテスト作成
  3. 03API契約の検証と破壊的変更の検出
  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 → Test)
  • シナリオカバレッジの追跡(BDD → Test)
  • コントラクトカバレッジの検証(CTR → Test)
  • カバレッジの不足箇所を特定
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 → Test のマッピング)
  • 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%
  • 要件カバレッジ:MUST 要件の 100%をテスト
  • 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/ に保存されます
  • トレーサビリティマトリクスは各テスト実行後に更新されます

コメント