# Python Testing Patterns > Implementa estrategias de testing completas con pytest, fixtures, mocking y desarrollo guiado por pruebas (TDD) en Python. Fuente: https://skillsagentes.com/skills/wshobson/agents/python-testing-patterns Markdown: https://skillsagentes.com/skills/wshobson/agents/python-testing-patterns.md Repositorio: https://github.com/wshobson/agents Autor: wshobson Licencia: MIT Actualizado: hace 4 meses Coste de contexto: 50 tok instalada, 1.8k tok al activarse, 6.5k tok con todos los archivos del bundle Bundle: 3 archivos, 25 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add wshobson/agents --skill python-testing-patterns --agent claude-code # Cursor npx -y skills add wshobson/agents --skill python-testing-patterns --agent cursor # Codex npx -y skills add wshobson/agents --skill python-testing-patterns --agent codex # Gemini CLI npx -y skills add wshobson/agents --skill python-testing-patterns --agent gemini # Windsurf npx -y skills add wshobson/agents --skill python-testing-patterns --agent windsurf # Cline npx -y skills add wshobson/agents --skill python-testing-patterns --agent cline ``` ## Qué hace - Aplica patrones de pytest: fixtures, mocking, parametrización y estructura AAA - Define convenciones de organización y nombrado de tests - Muestra cómo simular reintentos y controlar el tiempo con freezegun - Configura marcadores de pytest y reporting de cobertura con pytest-cov ## Cuándo usarla - Escribir tests unitarios para código Python - Configurar suites de tests e infraestructura de testing - Implementar TDD - Crear tests de integración para APIs y servicios ## Qué la activa - "Ayúdame a escribir tests con pytest para este módulo" - "Configura fixtures y mocks para probar esta función con reintentos" - "Cómo mido la cobertura de mis tests con pytest-cov" ## Antes de instalar - Requiere pytest y, para ejemplos avanzados, pytest-cov y freezegun instalados. - Necesita en el PATH: pip, pytest ## Archivos - SKILL.md — 7 KB - references/advanced-patterns.md — 9 KB - references/details.md — 9 KB ## SKILL.md Reproducido tal cual desde wshobson/agents bajo MIT. Esta sección es el documento original y está en inglés. # Python Testing Patterns Comprehensive guide to implementing robust testing strategies in Python using pytest, fixtures, mocking, parameterization, and test-driven development practices. ## When to Use This Skill - Writing unit tests for Python code - Setting up test suites and test infrastructure - Implementing test-driven development (TDD) - Creating integration tests for APIs and services - Mocking external dependencies and services - Testing async code and concurrent operations - Setting up continuous testing in CI/CD - Implementing property-based testing - Testing database operations - Debugging failing tests ## Core Concepts ### 1. Test Types - **Unit Tests**: Test individual functions/classes in isolation - **Integration Tests**: Test interaction between components - **Functional Tests**: Test complete features end-to-end - **Performance Tests**: Measure speed and resource usage ### 2. Test Structure (AAA Pattern) - **Arrange**: Set up test data and preconditions - **Act**: Execute the code under test - **Assert**: Verify the results ### 3. Test Coverage - Measure what code is exercised by tests - Identify untested code paths - Aim for meaningful coverage, not just high percentages ### 4. Test Isolation - Tests should be independent - No shared state between tests - Each test should clean up after itself ## Quick Start ```python # test_example.py def add(a, b): return a + b def test_add(): """Basic test example.""" result = add(2, 3) assert result == 5 def test_add_negative(): """Test with negative numbers.""" assert add(-1, 1) == 0 # Run with: pytest test_example.py ``` ## Detailed patterns and worked examples Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient. ## Testing Best Practices ### Test Organization ```python # tests/ # __init__.py # conftest.py # Shared fixtures # test_unit/ # Unit tests # test_models.py # test_utils.py # test_integration/ # Integration tests # test_api.py # test_database.py # test_e2e/ # End-to-end tests # test_workflows.py ``` ### Test Naming Convention A common pattern: `test___`. Adapt to your team's preferences. ```python # Pattern: test___ def test_create_user_with_valid_data_returns_user(): ... def test_create_user_with_duplicate_email_raises_conflict(): ... def test_get_user_with_unknown_id_returns_none(): ... # Good test names - clear and descriptive def test_user_creation_with_valid_data(): """Clear name describes what is being tested.""" pass def test_login_fails_with_invalid_password(): """Name describes expected behavior.""" pass def test_api_returns_404_for_missing_resource(): """Specific about inputs and expected outcomes.""" pass # Bad test names - avoid these def test_1(): # Not descriptive pass def test_user(): # Too vague pass def test_function(): # Doesn't explain what's tested pass ``` ### Testing Retry Behavior Verify that retry logic works correctly using mock side effects. ```python from unittest.mock import Mock def test_retries_on_transient_error(): """Test that service retries on transient failures.""" client = Mock() # Fail twice, then succeed client.request.side_effect = [ ConnectionError("Failed"), ConnectionError("Failed"), {"status": "ok"}, ] service = ServiceWithRetry(client, max_retries=3) result = service.fetch() assert result == {"status": "ok"} assert client.request.call_count == 3 def test_gives_up_after_max_retries(): """Test that service stops retrying after max attempts.""" client = Mock() client.request.side_effect = ConnectionError("Failed") service = ServiceWithRetry(client, max_retries=3) with pytest.raises(ConnectionError): service.fetch() assert client.request.call_count == 3 def test_does_not_retry_on_permanent_error(): """Test that permanent errors are not retried.""" client = Mock() client.request.side_effect = ValueError("Invalid input") service = ServiceWithRetry(client, max_retries=3) with pytest.raises(ValueError): service.fetch() # Only called once - no retry for ValueError assert client.request.call_count == 1 ``` ### Mocking Time with Freezegun Use freezegun to control time in tests for predictable time-dependent behavior. ```python from freezegun import freeze_time from datetime import datetime, timedelta @freeze_time("2026-01-15 10:00:00") def test_token_expiry(): """Test token expires at correct time.""" token = create_token(expires_in_seconds=3600) assert token.expires_at == datetime(2026, 1, 15, 11, 0, 0) @freeze_time("2026-01-15 10:00:00") def test_is_expired_returns_false_before_expiry(): """Test token is not expired when within validity period.""" token = create_token(expires_in_seconds=3600) assert not token.is_expired() @freeze_time("2026-01-15 12:00:00") def test_is_expired_returns_true_after_expiry(): """Test token is expired after validity period.""" token = Token(expires_at=datetime(2026, 1, 15, 11, 30, 0)) assert token.is_expired() def test_with_time_travel(): """Test behavior across time using freeze_time context.""" with freeze_time("2026-01-01") as frozen_time: item = create_item() assert item.created_at == datetime(2026, 1, 1) # Move forward in time frozen_time.move_to("2026-01-15") assert item.age_days == 14 ``` ### Test Markers ```python # test_markers.py import pytest @pytest.mark.slow def test_slow_operation(): """Mark slow tests.""" import time time.sleep(2) @pytest.mark.integration def test_database_integration(): """Mark integration tests.""" pass @pytest.mark.skip(reason="Feature not implemented yet") def test_future_feature(): """Skip tests temporarily.""" pass @pytest.mark.skipif(os.name == "nt", reason="Unix only test") def test_unix_specific(): """Conditional skip.""" pass @pytest.mark.xfail(reason="Known bug #123") def test_known_bug(): """Mark expected failures.""" assert False # Run with: # pytest -m slow # Run only slow tests # pytest -m "not slow" # Skip slow tests # pytest -m integration # Run integration tests ``` ### Coverage Reporting ```bash # Install coverage pip install pytest-cov # Run tests with coverage pytest --cov=myapp tests/ # Generate HTML report pytest --cov=myapp --cov-report=html tests/ # Fail if coverage below threshold pytest --cov=myapp --cov-fail-under=80 tests/ # Show missing lines pytest --cov=myapp --cov-report=term-missing tests/ ``` For advanced patterns (async testing, monkeypatching, property-based testing, database testing, CI/CD integration, and configuration), see [references/advanced-patterns.md](references/advanced-patterns.md) ## Dónde encaja - Categoría: [Testing y QA](https://skillsagentes.com/categorias/testing-qa.md) — Flujos de testing unitario, de integración y end-to-end. - Creador: [wshobson](https://skillsagentes.com/creators/wshobson.md) — 183 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [Hermes Tweet](https://skillsagentes.com/skills/wshobson/agents/hermes-tweet.md): Instala y opera Hermes Tweet, un plugin de Hermes Agent para investigar X/Twitter, leer timelines, analizar tweets y ejecutar operaciones privadas o de cambio de estado con aprobación previa. - [Superself](https://skillsagentes.com/skills/wshobson/agents/superself.md): Úsalo cuando un proyecto guarda su estado en Superself: lee `self context` al iniciar sesión, vincula el trabajo a una work unit, reporta con evidencia y registra decisiones confirmadas. - [Grounded Vault](https://skillsagentes.com/skills/wshobson/agents/grounded-vault.md): Úsalo para mantener un almacén Markdown de conocimiento donde cada afirmación compilada se rastrea hasta una fuente inmutable y el drift se detecta con git diff sin gastar tokens. - [Postgresql Table Design](https://skillsagentes.com/skills/wshobson/agents/postgresql-table-design.md): Úsalo al diseñar o revisar un esquema específico de PostgreSQL: buenas prácticas, tipos de datos, indexación, restricciones, patrones de rendimiento y funciones avanzadas. - [Prompt Engineering Patterns](https://skillsagentes.com/skills/wshobson/agents/prompt-engineering-patterns.md): Úsalo cuando pidan optimizar un prompt, mejorar su rendimiento, diseñar una plantilla, aplicar chain-of-thought, few-shot prompting o técnicas avanzadas de prompt engineering para producción. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)