python-testing

Quick reference for Python testing with pytest, coverage, fixtures, and best practices.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "python-testing" with this command: npx skills add laurigates/claude-plugins/laurigates-claude-plugins-python-testing

Python Testing

Quick reference for Python testing with pytest, coverage, fixtures, and best practices.

When This Skill Applies

  • Writing unit tests and integration tests

  • Test-driven development (TDD)

  • Test fixtures and parametrization

  • Coverage analysis

  • Mocking and patching

  • Async testing

Quick Reference

Running Tests

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"

Test Coverage

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/

Fixtures

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"

Parametrize Tests

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

Markers

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"

Async Testing

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()

Mocking

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

Test Organization

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 Configuration

[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.:", ]

Common Testing Patterns

Test Exceptions

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()

Test Warnings

import pytest

def test_deprecation_warning(): with pytest.warns(DeprecationWarning): deprecated_function()

Temporary Files

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 Workflow

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

See Also

  • uv-project-management

  • Adding pytest to projects

  • python-code-quality

  • Combining tests with linting

  • python-development

  • Core Python development patterns

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

python-code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

clippy-advanced

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rust-development

No summary provided by upstream source.

Repository SourceNeeds Review