python-testing について
Python 開発者向けの pytest 基本リファレンスです。テスト作成、フィクスチャ、パラメーター化、カバレッジ、モック、非同期テストを扱い、単一モジュールの TDD にも対応します。
主な機能
- 01pytest の実行とテスト選択
- 02フィクスチャとパラメーター化
- 03カバレッジレポート
- 04unittest.mock によるモック
- 05非同期テストと TDD
活用シーン
- 01モジュールの単体テスト作成
- 02フィクスチャによるテストデータ準備
- 03テストカバレッジの確認
- 04外部依存のモックと非同期コードのテスト
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ laurigates/ claude-plugins --skill python-testingインストール後、Claude Code で/python-testingを入力して読み込まれたか確認します。
同梱ファイルREFERENCE.md
詳細
Python テスト
pytest、カバレッジ、フィクスチャ、ベストプラクティスを使った Python テストのクイックリファレンスです。
このスキルを使う場面
| 次のような場合はこのスキルを使います… | 次のような場合は pytest-advanced を使います… |
|---|---|
| 初めて pytest のテストを書く場合、フィクスチャやパラメータ化の基本を学ぶ場合 | 再利用可能な conftest.py のフィクスチャ階層や、並列実行用のマーカーを設計する場合 |
カバレッジレポートを設定し、unittest.mock を使った基本的なモックを行う場合 | pytest-xdist、カスタムマーカー、または hookimpl プラグインを調整する場合 |
| 単一モジュールで TDD のレッド・グリーン・リファクターサイクルを実践する場合 | 複数パッケージのテストスイート全体で共有するフィクスチャライブラリを構築する場合 |
このスキルが適用される場面
- 単体テストと統合テストの作成
- テスト駆動開発(TDD)
- テストフィクスチャとパラメータ化
- カバレッジ分析
- モックとパッチ適用
- 非同期テスト
クイックリファレンス
テストの実行
# Basic test run
uv run pytest
# Verbose output
uv run pytest -v
# Show print statements
uv run pytest -s
# Stop at first failure
uv run pytest -x
# Run specific test
uv run pytest tests/test_module.py::test_function
# Run by keyword
uv run pytest -k "test_user"
テストカバレッジ
# Run with coverage
uv run pytest --cov
# HTML report
uv run pytest --cov --cov-report=html
# Show missing lines
uv run pytest --cov --cov-report=term-missing
# Coverage for specific module
uv run pytest --cov=mymodule tests/
フィクスチャ
import pytest
@pytest.fixture
def sample_data():
return {"key": "value"}
@pytest.fixture(scope="module")
def db_connection():
conn = create_connection()
yield conn
conn.close()
def test_with_fixture(sample_data):
assert sample_data["key"] == "value"
テストのパラメータ化
import pytest
@pytest.mark.parametrize("input,expected", [
("hello", "HELLO"),
("world", "WORLD"),
("test", "TEST"),
])
def test_uppercase(input: str, expected: str):
assert input.upper() == expected
@pytest.mark.parametrize("value,is_valid", [
(1, True),
(0, False),
(-1, False),
])
def test_validation(value, is_valid):
assert validate(value) == is_valid
マーカー
import pytest
@pytest.mark.slow
def test_slow_operation():
# Long-running test
pass
@pytest.mark.skip(reason="Not implemented yet")
def test_future_feature():
pass
@pytest.mark.skipif(sys.platform == "win32", reason="Unix only")
def test_unix_specific():
pass
@pytest.mark.xfail
def test_known_issue():
# Expected to fail
pass
# Run only marked tests
uv run pytest -m slow
uv run pytest -m "not slow"
非同期テスト
import pytest
@pytest.mark.asyncio
async def test_async_function():
result = await async_operation()
assert result == expected_value
@pytest.fixture
async def async_client():
client = AsyncClient()
await client.connect()
yield client
await client.disconnect()
モック
from unittest.mock import Mock, patch, MagicMock
def test_with_mock():
mock_obj = Mock()
mock_obj.method.return_value = "mocked"
assert mock_obj.method() == "mocked"
@patch('module.external_api')
def test_with_patch(mock_api):
mock_api.return_value = {"status": "success"}
result = call_external_api()
assert result["status"] == "success"
# pytest-mock (cleaner)
def test_with_mocker(mocker):
mock = mocker.patch('module.function')
mock.return_value = 42
assert function() == 42
テストの構成
project/
├── src/
│ └── myproject/
│ ├── __init__.py
│ └── module.py
└── tests/
├── __init__.py
├── conftest.py # Shared fixtures
├── test_module.py
└── integration/
└── test_api.py
conftest.py
# tests/conftest.py
import pytest
@pytest.fixture(scope="session")
def app_config():
return {"debug": True, "testing": True}
@pytest.fixture(autouse=True)
def reset_db():
setup_database()
yield
teardown_database()
pyproject.toml の設定
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"-v",
"--strict-markers",
"--cov=src",
"--cov-report=term-missing",
]
markers = [
"slow: marks tests as slow",
"integration: marks tests as integration tests",
]
[tool.coverage.run]
source = ["src"]
omit = ["*/tests/*", "*/test_*.py"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
]
よく使われるテストパターン
例外のテスト
import pytest
def test_raises_exception():
with pytest.raises(ValueError):
function_that_raises()
def test_raises_with_message():
with pytest.raises(ValueError, match="Invalid input"):
function_that_raises()
警告のテスト
import pytest
def test_deprecation_warning():
with pytest.warns(DeprecationWarning):
deprecated_function()
一時ファイル
def test_with_tmp_path(tmp_path):
file_path = tmp_path / "test.txt"
file_path.write_text("content")
assert file_path.read_text() == "content"
TDD ワークフロー
# 1. RED: Write failing test
uv run pytest tests/test_new_feature.py
# FAILED
# 2. GREEN: Implement minimal code
uv run pytest tests/test_new_feature.py
# PASSED
# 3. REFACTOR: Improve code
uv run pytest # All tests pass
関連項目
uv-project-management- プロジェクトへの pytest の追加python-code-quality- テストとリンティングの組み合わせpython-development- Python 開発の基本パターン
参考資料
- 公式ドキュメント:https://docs.pytest.org/
- 詳細ガイド:このスキルディレクトリの REFERENCE.md を参照
コメント
Markdown 対応