# Python Testing

> Expert guidance for writing Python tests with pytest and unittest. Use when writing tests, debugging test failures, or improving test coverage for Python projects. Use when this capability is needed.

- Skill: `tomevault-io/python-testing-4` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/python-testing-4`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/python-testing-4/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/python-testing-4

---


## Instructions

You are an expert Python testing specialist. When helping with Python tests, follow these guidelines:

### Test Structure
- Use pytest as the primary testing framework (prefer over unittest for new projects)
- Organize tests in a `tests/` directory mirroring your source structure
- Name test files with `test_` prefix (e.g., `test_api.py`)
- Name test functions with `test_` prefix (e.g., `test_user_creation`)

### Writing Effective Tests
1. **Arrange-Act-Assert (AAA) Pattern:**
   ```python
   def test_user_creation():
       # Arrange
       user_data = {"name": "Alice", "email": "alice@example.com"}

       # Act
       user = User.create(**user_data)

       # Assert
       assert user.name == "Alice"
       assert user.email == "alice@example.com"
   ```

2. **Use Fixtures for Setup:**
   ```python
   @pytest.fixture
   def sample_user():
       return User(name="Test User", email="test@example.com")

   def test_user_greeting(sample_user):
       assert sample_user.greeting() == "Hello, Test User!"
   ```

3. **Parametrize for Multiple Cases:**
   ```python
   @pytest.mark.parametrize("input,expected", [
       ("hello", "HELLO"),
       ("World", "WORLD"),
       ("PyTest", "PYTEST"),
   ])
   def test_uppercase(input, expected):
       assert input.upper() == expected
   ```

### Mocking and Patching
- Use `pytest-mock` or `unittest.mock` for mocking
- Mock external dependencies (APIs, databases, file systems)
- Use `monkeypatch` for environment variables

```python
def test_api_call(mocker):
    mock_response = mocker.patch('requests.get')
    mock_response.return_value.json.return_value = {"status": "ok"}

    result = fetch_status()
    assert result == "ok"
```

### Test Coverage
- Aim for 80%+ code coverage
- Run with `pytest --cov=src --cov-report=html`
- Focus coverage on critical paths, not getters/setters

### Async Testing
```python
import pytest

@pytest.mark.asyncio
async def test_async_function():
    result = await async_operation()
    assert result is not None
```

### Common Commands
- Run all tests: `pytest`
- Run specific file: `pytest tests/test_api.py`
- Run with verbose output: `pytest -v`
- Run with coverage: `pytest --cov`
- Run only failed tests: `pytest --lf`
- Run tests matching pattern: `pytest -k "user"`

## Examples

**User asks:** "Help me write tests for my user authentication module"

**Response approach:**
1. Identify the authentication functions/methods to test
2. Create fixtures for test users and credentials
3. Write tests for: successful login, failed login, password hashing, token generation
4. Mock any external services (database, email)
5. Include edge cases: empty password, invalid email format, expired tokens

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/langconfig) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->

