Validate WCAG 2.1 Level AA compliance and accessibility best practices. Use when performing accessibility audits and WCAG certification.
日本語の概要は準備中です。原文の説明を表示しています。
Generate pytest-based unit tests for Python code. Creates test files following pytest conventions with proper fixtures, mocking, and parametrization.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
This skill generates pytest-based unit tests for Python code, following pytest conventions, best practices, and project standards. It creates comprehensive test suites with proper fixtures, mocking, parametrization, and coverage.
Source to Test Mapping:
src/tools/feature/core.pytests/test_core.pytest_<source_filename>.pyExamples:
src/utils/validator.py → tests/test_validator.pysrc/models/user.py → tests/test_user.pysrc/services/auth.py → tests/test_auth.pyRead the source file:
# Read the source to understand structure
cat src/tools/feature/core.py
Identify test targets:
Output: List of functions/classes requiring tests
Create test file with proper naming:
"""
Unit tests for [module name].
This module tests:
- [Functionality 1]
- [Functionality 2]
- Error handling and edge cases
"""
import pytest
from unittest.mock import Mock, MagicMock, patch, call
from typing import Any, Dict, List, Optional
from pathlib import Path
# Import functions/classes to test
from src.tools.feature.core import (
function_to_test,
ClassToTest,
CustomException,
)
# ============================================================================
# Fixtures
# ============================================================================
@pytest.fixture
def sample_data() -> Dict[str, Any]:
"""
Sample data for testing.
Returns:
Dictionary with test data
"""
return {
"id": 1,
"name": "test",
"value": 123,
}
@pytest.fixture
def mock_dependency() -> Mock:
"""
Mock external dependency.
Returns:
Configured mock object
"""
mock = Mock()
mock.method.return_value = {"status": "success"}
mock.validate.return_value = True
return mock
@pytest.fixture
def temp_directory(tmp_path: Path) -> Path:
"""
Temporary directory for test files.
Args:
tmp_path: pytest temporary directory fixture
Returns:
Path to test directory
"""
test_dir = tmp_path / "test_data"
test_dir.mkdir()
return test_dir
# ============================================================================
# Test Classes (for testing classes)
# ============================================================================
class TestClassName:
"""Tests for ClassName."""
def test_init_valid_params_creates_instance(self):
"""Test initialization with valid parameters."""
# Arrange & Act
instance = ClassToTest(param="value")
# Assert
assert instance.param == "value"
assert instance.initialized is True
def test_method_valid_input_returns_expected(self, sample_data):
"""Test method with valid input."""
# Arrange
instance = ClassToTest()
# Act
result = instance.method(sample_data)
# Assert
assert result["processed"] is True
assert result["id"] == sample_data["id"]
def test_method_invalid_input_raises_error(self):
"""Test method with invalid input raises error."""
# Arrange
instance = ClassToTest()
invalid_data = None
# Act & Assert
with pytest.raises(ValueError, match="Invalid input"):
instance.method(invalid_data)
# ============================================================================
# Test Functions
# ============================================================================
def test_function_valid_input_returns_expected(sample_data):
"""Test function with valid input returns expected result."""
# Arrange
expected = "processed"
# Act
result = function_to_test(sample_data)
# Assert
assert result == expected
def test_function_empty_input_returns_empty():
"""Test function with empty input returns empty result."""
# Arrange
empty_input = {}
# Act
result = function_to_test(empty_input)
# Assert
assert result == {}
def test_function_none_input_raises_error():
"""Test function with None input raises ValueError."""
# Arrange
invalid_input = None
# Act & Assert
with pytest.raises(ValueError, match="Input cannot be None"):
function_to_test(invalid_input)
def test_function_with_mock_dependency(mock_dependency):
"""Test function with mocked external dependency."""
# Arrange
input_data = {"key": "value"}
# Act
result = function_using_dependency(input_data, mock_dependency)
# Assert
assert result["status"] == "success"
mock_dependency.method.assert_called_once_with(input_data)
@patch('src.tools.feature.core.external_api_call')
def test_function_with_patched_external(mock_api):
"""Test function with patched external API call."""
# Arrange
mock_api.return_value = {"data": "test"}
input_data = {"key": "value"}
# Act
result = function_with_api(input_data)
# Assert
assert result["data"] == "test"
mock_api.assert_called_once()
# ============================================================================
# Parametrized Tests
# ============================================================================
@pytest.mark.parametrize("input_value,expected", [
("valid@email.com", True),
("invalid.email", False),
("", False),
(None, False),
("no@domain", False),
("@no-user.com", False),
])
def test_validation_multiple_inputs(input_value, expected):
"""Test validation with multiple input scenarios."""
# Act
result = validate_input(input_value)
# Assert
assert result == expected
@pytest.mark.parametrize("user_type,permission", [
("admin", "all"),
("moderator", "edit"),
("user", "read"),
("guest", "none"),
])
def test_permissions_by_user_type(user_type, permission):
"""Test permissions based on user type."""
# Arrange
user = {"type": user_type}
# Act
result = get_permissions(user)
# Assert
assert result == permission
# ============================================================================
# Async Tests
# ============================================================================
@pytest.mark.asyncio
async def test_async_function_success():
"""Test async function with successful execution."""
# Arrange
input_data = {"key": "value"}
# Act
result = await async_function(input_data)
# Assert
assert result.success is True
assert result.data == input_data
@pytest.mark.asyncio
async def test_async_function_with_mock():
"""Test async function with mocked dependency."""
# Arrange
mock_service = Mock()
mock_service.fetch = AsyncMock(return_value={"data": "test"})
input_data = {"key": "value"}
# Act
result = await async_function_with_service(input_data, mock_service)
# Assert
assert result["data"] == "test"
mock_service.fetch.assert_awaited_once()
# ============================================================================
# Exception Tests
# ============================================================================
def test_custom_exception_raised():
"""Test that custom exception is raised."""
# Arrange
invalid_input = "invalid"
# Act & Assert
with pytest.raises(CustomException):
function_that_raises(invalid_input)
def test_exception_message_content():
"""Test exception message contains expected content."""
# Arrange
invalid_input = "invalid"
# Act & Assert
with pytest.raises(CustomException, match="Expected error message"):
function_that_raises(invalid_input)
def test_exception_attributes():
"""Test exception has expected attributes."""
# Arrange
invalid_input = "invalid"
# Act & Assert
with pytest.raises(CustomException) as exc_info:
function_that_raises(invalid_input)
assert exc_info.value.code == 400
assert "field" in exc_info.value.details
# ============================================================================
# File Operation Tests
# ============================================================================
def test_save_file(temp_directory):
"""Test file saving functionality."""
# Arrange
file_path = temp_directory / "test_file.txt"
content = "test content"
# Act
save_file(file_path, content)
# Assert
assert file_path.exists()
assert file_path.read_text() == content
def test_read_file(temp_directory):
"""Test file reading functionality."""
# Arrange
file_path = temp_directory / "test_file.txt"
expected_content = "test content"
file_path.write_text(expected_content)
# Act
content = read_file(file_path)
# Assert
assert content == expected_content
def test_file_not_found_raises_error(temp_directory):
"""Test reading non-existent file raises error."""
# Arrange
missing_file = temp_directory / "missing.txt"
# Act & Assert
with pytest.raises(FileNotFoundError):
read_file(missing_file)
# ============================================================================
# Marker Examples
# ============================================================================
@pytest.mark.slow
def test_slow_operation():
"""Test slow operation (marked as slow)."""
# This test can be skipped with: pytest -m "not slow"
pass
@pytest.mark.integration
def test_integration_scenario():
"""Test integration scenario (marked as integration)."""
# Run only integration tests: pytest -m integration
pass
@pytest.mark.skipif(sys.version_info < (3, 9), reason="Requires Python 3.9+")
def test_python39_feature():
"""Test feature that requires Python 3.9+."""
pass
# ============================================================================
# Fixture Scope Examples
# ============================================================================
@pytest.fixture(scope="module")
def expensive_setup():
"""
Expensive setup that runs once per module.
Returns:
Setup result
"""
# Setup runs once for entire test module
result = perform_expensive_setup()
yield result
# Teardown runs once after all tests
cleanup(result)
@pytest.fixture(scope="function")
def per_test_setup():
"""
Setup that runs before each test function.
Returns:
Setup result
"""
# Setup runs before each test
result = setup()
yield result
# Teardown runs after each test
teardown(result)
Deliverable: Complete pytest test file
Basic fixture:
@pytest.fixture
def sample_user():
"""Create sample user for testing."""
return User(name="Test User", email="test@example.com")
Fixture with setup and teardown:
@pytest.fixture
def database_connection():
"""Database connection with cleanup."""
# Setup
conn = connect_to_database()
yield conn # Test uses connection here
# Teardown
conn.close()
Fixture with parameters:
@pytest.fixture(params=["sqlite", "postgres", "mysql"])
def database_type(request):
"""Parametrized database fixture."""
return request.param
def test_with_all_databases(database_type):
"""Test runs 3 times, once per database."""
db = connect(database_type)
assert db.connected
Fixture scopes:
@pytest.fixture(scope="function") # Default: runs per test
def per_test():
pass
@pytest.fixture(scope="class") # Runs once per test class
def per_class():
pass
@pytest.fixture(scope="module") # Runs once per module
def per_module():
pass
@pytest.fixture(scope="session") # Runs once per session
def per_session():
pass
Basic parametrization:
@pytest.mark.parametrize("input,expected", [
(2, 4),
(3, 9),
(4, 16),
])
def test_square(input, expected):
assert square(input) == expected
Multiple parameters:
@pytest.mark.parametrize("a,b,expected", [
(1, 2, 3),
(2, 3, 5),
(10, 20, 30),
])
def test_add(a, b, expected):
assert add(a, b) == expected
Named parameters:
@pytest.mark.parametrize("test_input,expected", [
pytest.param("valid", True, id="valid_input"),
pytest.param("invalid", False, id="invalid_input"),
pytest.param("", False, id="empty_input"),
])
def test_validation(test_input, expected):
assert validate(test_input) == expected
Built-in markers:
@pytest.mark.skip(reason="Not implemented yet")
def test_future_feature():
pass
@pytest.mark.skipif(sys.platform == "win32", reason="Unix only")
def test_unix_feature():
pass
@pytest.mark.xfail(reason="Known bug #123")
def test_buggy_feature():
pass
@pytest.mark.slow
def test_slow_operation():
pass
Custom markers (in pytest.ini):
[pytest]
markers =
slow: marks tests as slow
integration: marks tests as integration tests
unit: marks tests as unit tests
smoke: marks tests as smoke tests
Mock with pytest-mock:
def test_with_mocker(mocker):
"""Test using pytest-mock plugin."""
mock_api = mocker.patch('module.api_call')
mock_api.return_value = {"status": "success"}
result = function_using_api()
assert result["status"] == "success"
mock_api.assert_called_once()
Mock attributes:
def test_mock_attributes(mocker):
"""Test with mocked object attributes."""
mock_obj = mocker.Mock()
mock_obj.property = "value"
mock_obj.method.return_value = 42
assert mock_obj.property == "value"
assert mock_obj.method() == 42
Async test:
@pytest.mark.asyncio
async def test_async_function():
"""Test async function."""
result = await async_function()
assert result.success
@pytest.mark.asyncio
async def test_async_with_mock(mocker):
"""Test async with mocked async call."""
mock_service = mocker.Mock()
mock_service.fetch = AsyncMock(return_value="data")
result = await function_with_async_call(mock_service)
assert result == "data"
mock_service.fetch.assert_awaited_once()
Basic commands:
# Run all tests
pytest
# Run specific file
pytest tests/test_module.py
# Run specific test
pytest tests/test_module.py::test_function
# Run with verbose output
pytest -v
# Run with coverage
pytest --cov=src --cov-report=html --cov-report=term-missing
# Run with markers
pytest -m "not slow"
pytest -m integration
# Run in parallel (with pytest-xdist)
pytest -n auto
# Run with output
pytest -s # Show print statements
pytest -v -s # Verbose + output
Coverage commands:
# Generate coverage report
pytest --cov=src --cov-report=html
# View HTML report
open htmlcov/index.html
# Check coverage threshold
pytest --cov=src --cov-fail-under=80
# Show missing lines
pytest --cov=src --cov-report=term-missing
test_function_condition_expected_resultBefore marking tests complete:
test_<module>.py)Input: Python source file to test Process: Analyze → Generate structure → Write tests → Run & verify Output: pytest test file with ≥ 80% coverage Next Step: Integration testing or code review
test_<source_file>.pyまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Validate WCAG 2.1 Level AA compliance and accessibility best practices. Use when performing accessibility audits and WCAG certification.
日本語の概要は準備中です。原文の説明を表示しています。
Analyze feature requirements, dependencies, and security considerations. Use when starting feature implementation from GitHub issues to understand scope, technical feasibility, and risks.
日本語の概要は準備中です。原文の説明を表示しています。
Run SQL queries against psql, BigQuery, or MySQL from the terminal, including natural-language-to-SQL and schema exploration. Use when analyzing data, inspecting DB state, or debugging tables. Trigger on "query the database", "SQL", "show me data from", "explore table".
日本語の概要は準備中です。原文の説明を表示しています。
Design REST APIs or function contracts with clear request/response specifications, error handling patterns, authentication strategies, and comprehensive documentation.
日本語の概要は準備中です。原文の説明を表示しています。
Generate comprehensive API endpoint tests for REST and GraphQL APIs. Creates tests for all HTTP methods, status codes, authentication, and validation.
日本語の概要は準備中です。原文の説明を表示しています。
Design component architecture and module structure using established architectural patterns for clean, maintainable, and scalable systems.
日本語の概要は準備中です。原文の説明を表示しています。