소스 정보
- 저장소
- lebiraja/skills4agents
- 최근 소스 활동
- 2026년 4월 4일 12:48
- 감지된 SKILL.md 언어
- 영어
- 스타
- 1
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/lebiraja/skills4agents --skill agent-module-testing-strategy-and-coverage명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | agent-module-testing-strategy-and-coverage |
| description | Module: Testing Strategy and Coverage Standard |
agent.module.testing-strategy-and-coverage1.0.0productionUse this module to establish a production-grade testing discipline for backend services, frontend applications, and AI integration points.
Apply when:
Do not apply directly when:
All projects adopt this canonical pyramid (bottom = fastest and most, top = slowest and least):
E2E Tests (5–10% of test count)
/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\
/ Contract Tests \
/ (Integration) \
/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\
/ Service/Unit Tests \
/ (60–70% of test count) \
/________________________________\
Test layer definitions:
Scope: Individual functions, classes, and modules in isolation. Mocking: Mock all external dependencies (DB, services, APIs). Speed: < 100 ms per test; thousands run in seconds. Count: 60–70% of all tests.
Coverage: Business logic, algorithms, edge cases, error paths.
Example domains:
Scope: Multiple components working together (e.g., service + in-process DB, service + mock external API). Mocking: Mock external services; use real or test containers for databases. Speed: 100 ms–2 s per test; hundreds run in seconds to minutes. Count: 20–30% of all tests.
Coverage: Happy paths, failure paths, error handling, contract fulfillment.
Example domains:
Scope: Service API contracts between independent services. Mocking: Mock other services; verify request/response shape and semantics. Speed: 100 ms–1 s per test; tens to hundreds. Count: 5–10% of all tests.
Coverage: Request/response schema, error handling, versioning.
Example domains:
Scope: Full system: frontend → BFF → backend → database → external services. Mocking: Minimize mocking; use real or stubbed external services (with careful handling). Speed: 1–10 s per test; tens run in minutes. Count: 5–10% of all tests.
Coverage: Critical user journeys, cross-service workflows, rollback scenarios.
Example domains:
>= 90% of cyclomatic complexity>= 80% of lines>= 70% of lines>= 50% of linesCalculation: Use coverage tools; configure to fail CI if targets not met.
Use factory libraries (e.g., FactoryBoy in Python, factory_bot in Ruby) to generate realistic, deterministic test data.
import factory
from users.models import User
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = User
email = factory.Sequence(lambda n: f"user{n}@example.com")
phone = factory.Sequence(lambda n: f"+1234567890{n % 10}")
first_name = factory.Faker('first_name')
last_name = factory.Faker('last_name')
is_active = True
# Usage:
user = UserFactory()
users = UserFactory.create_batch(10)
Keep fixtures minimal; prefer factories for dynamic generation.
# Good: Small, reusable fixture
@pytest.fixture
def base_user():
return UserFactory(email="base@example.com")
# Avoid: Large fixture databases
@pytest.fixture(scope="session")
def all_test_data():
# Creates 10k records – slow, hard to reason about
...
Ensure all tests are deterministic:
now().import random
from datetime import datetime, timedelta
@pytest.fixture(autouse=True)
def seed_rng():
random.seed(42)
def test_user_created_at():
now = datetime(2026, 4, 4, 12, 0, 0)
user = UserFactory(created_at=now)
assert user.created_at == now
tests/unit/<domain>/test_<module>.pytest_<function>_<scenario>_<expected_result>Example structure:
src/
users/
models.py
validators.py
service.py
tests/
unit/
users/
test_validators.py
test_service.py
Example test:
# tests/unit/users/test_validators.py
import pytest
from users.validators import validate_email
class TestValidateEmail:
def test_valid_gmail_address(self):
# Arrange
email = "user@gmail.com"
# Act & Assert
assert validate_email(email) is True
def test_non_gmail_rejected(self):
# Arrange
email = "user@hotmail.com"
# Act & Assert
with pytest.raises(ValidationError) as exc_info:
validate_email(email)
assert exc_info.value.error_code == "VALIDATION_EMAIL_DOMAIN"
def test_invalid_format_rejected(self):
email = "invalid-email"
with pytest.raises(ValidationError) as exc_info:
validate_email(email)
assert exc_info.value.error_code == "VALIDATION_EMAIL_FORMAT"
Exit criteria:
>= 70% line coverage.tests/integration/test_<endpoint>.pyExample:
# tests/integration/test_user_signup.py
import pytest
from django.test import Client
from users.models import User
@pytest.fixture
def client():
return Client()
@pytest.fixture
def db():
# Use real test database
pass
class TestUserSignupFlow:
def test_signup_success_creates_user(self, client, db):
# Arrange
payload = {
"email": "newuser@gmail.com",
"first_name": "John",
"last_name": "Doe"
}
# Act
response = client.post("/api/v1/users/signup", json=payload)
# Assert
assert response.status_code == 201
assert response.json()["user_id"]
user = User.objects.get(email="newuser@gmail.com")
assert user.first_name == "John"
def test_signup_duplicate_email_rejected(self, client, db):
# Arrange
UserFactory(email="existing@gmail.com")
payload = {"email": "existing@gmail.com", "first_name": }
response = client.post(, json=payload)
response.status_code ==
response.json()[][] ==
():
payload = {: , : }
response = client.post(, json=payload)
response.status_code ==
response.json()[][] ==
Exit criteria:
Example (using Pydantic):
# tests/integration/test_user_api_contract.py
from pydantic import BaseModel, Field, validator
import pytest
class UserSignupRequest(BaseModel):
email: str = Field(..., regex=r"^[a-z0-9]+@gmail\.com$")
first_name: str = Field(..., min_length=1, max_length=100)
last_name: str = Field(..., min_length=1, max_length=100)
class UserResponse(BaseModel):
user_id: str
email: str
created_at: str # ISO 8601
def test_signup_response_matches_schema():
payload = {"email": "user@gmail.com", "first_name": "John", "last_name": "Doe"}
response = client.post("/api/v1/users/signup", json=payload)
# This raises if response doesn't match schema
user_response = UserResponse(**response.json()["user"])
assert user_response.user_id
Exit criteria:
Example:
# tests/e2e/test_user_signup_and_login.py
import pytest
from selenium import webdriver
@pytest.fixture
def browser():
driver = webdriver.Chrome()
yield driver
driver.quit()
def test_signup_and_login_workflow(browser):
# Step 1: Navigate to signup
browser.get("https://test.example.com/signup")
# Step 2: Fill signup form
browser.find_element("email").send_keys("newuser@gmail.com")
browser.find_element("first_name").send_keys("John")
browser.find_element("last_name").send_keys("Doe")
browser.find_element("submit").click()
# Step 3: Verify success
assert browser.find_element("success_message")
# Step 4: Login
browser.get("https://test.example.com/login")
browser.find_element("email").send_keys("newuser@gmail.com")
browser.find_element("password").send_keys("password123")
browser.find_element("submit").click()
# Step 5: Verify dashboard loaded
assert browser.find_element("dashboard")
Exit criteria:
Example:
# tests/integration/test_error_paths.py
import pytest
from unittest.mock import patch
class TestErrorHandling:
def test_external_service_timeout_handled_gracefully(self):
with patch('external_api.call') as mock_call:
mock_call.side_effect = TimeoutError("Service timeout")
response = client.post("/api/v1/enrichment", json={"text": "hello"})
assert response.status_code == 504
assert response.json()["error"]["code"] == "EXTERNAL_SERVICE_TIMEOUT"
assert response.json()["error"]["retryable"] is True
def test_rate_limit_returns_429(self):
with patch('rate_limiter.allow_request', return_value=False):
response = client.post("/api/v1/enrichment", json={"text": "hello"})
assert response.status_code == 429
assert "Retry-After" in response.headers
Exit criteria:
Example (using Locust or k6):
# load_tests/users_api.py
from locust import HttpUser, task, between
class UsersAPIUser(HttpUser):
wait_time = between(1, 3)
@task(2)
def list_users(self):
self.client.get("/api/v1/users")
@task(1)
def create_user(self):
self.client.post("/api/v1/users", json={
"email": "user@gmail.com",
"first_name": "John"
})
Exit criteria:
Example CI configuration:
# .github/workflows/test.yml
name: Test Suite
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: pytest tests/unit/ -v --cov=src --cov-fail-under=70
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: password
steps:
- uses: actions/checkout@v3
- run: pytest tests/integration/ -v
e2e-tests:
runs-on:
Exit criteria:
@pytest.fixture
def db_session(db):
# db fixture from pytest-django provides isolated DB
yield db
@pytest.fixture(autouse=True)
def cleanup_after_test(db):
yield
db.session.rollback() # Auto-cleanup
import responses
@responses.activate
def test_payment_processing():
responses.add(
responses.POST,
"https://payment-api.example.com/charge",
json={"charge_id": "ch_123"},
status=200
)
result = payment_service.charge(amount=100)
assert result.charge_id == "ch_123"
| Decision Area | Preferred Option | Alternative | Selection Rule |
|---|---|---|---|
| Test organization | By domain/feature | By test type | Use domain-based organization for discoverability. |
| DB for integration tests | Real test DB | In-memory/SQLite | Use real DB to catch SQL/transaction bugs. |
| External API mocking | Recorded responses (VCR) | Full mock library | Use VCR to maintain realistic payloads. |
| Coverage enforcement | CI gate (fail build if below target) | Advisory-only | Use CI gate for critical paths; advisory for others. |
| E2E framework | Browser-based (Selenium/Playwright) | API-only | Use browser-based for UX-heavy flows. |
| Test data generation | Factories (FactoryBoy) | Fixed fixtures | Use factories for flexibility and realism. |
<= 30 seconds for entire suite<= 5 minutes for entire suite<= 15 minutes for critical journeys>= 90%>= 80%>= 70%<= 0.5% (re-run pass rate >= 99.5%)100% for regressions<= 2 hoursThis module is reusable across all backend and frontend projects. Adapt only: