AgentStack
SKILL verified MIT Self-run

Pytest Generator

skill-matteocervelli-llms-pytest-generator · by matteocervelli

Generate pytest-based unit tests for Python code. Creates test files

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-matteocervelli-llms-pytest-generator

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Pytest Generator? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Pytest Generator Skill

Purpose

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.

When to Use

  • Generate pytest tests for Python modules
  • Create test files for new Python features
  • Add missing test coverage to existing Python code
  • Need pytest-specific patterns (fixtures, markers, parametrize)

Test File Naming Convention

Source to Test Mapping:

  • Source: src/tools/feature/core.py
  • Test: tests/test_core.py
  • Pattern: test_.py

Examples:

  • src/utils/validator.pytests/test_validator.py
  • src/models/user.pytests/test_user.py
  • src/services/auth.pytests/test_auth.py

Pytest Test Generation Workflow

1. Analyze Python Source Code

Read the source file:

# Read the source to understand structure
cat src/tools/feature/core.py

Identify test targets:

  • Public functions to test
  • Classes and methods
  • Error conditions
  • Edge cases
  • Dependencies (imports, external calls)

Output: List of functions/classes requiring tests


2. Generate Test File Structure

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 .py`)
- [ ] All public functions/classes tested
- [ ] Happy path tests included
- [ ] Edge case tests included
- [ ] Error condition tests included
- [ ] External dependencies mocked
- [ ] Fixtures used for reusable setup
- [ ] Tests follow AAA pattern
- [ ] Test names are descriptive
- [ ] All tests pass
- [ ] Coverage ≥ 80%
- [ ] No flaky tests
- [ ] Tests run quickly

---

## Integration with Testing Workflow

**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

---

## Remember

- **Follow naming convention:** `test_.py`
- **Use pytest fixtures** for reusable setup
- **Parametrize** to reduce duplication
- **Mock external calls** to isolate tests
- **Test behavior, not implementation**
- **Aim for 80%+ coverage**
- **Keep tests fast and independent**

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [matteocervelli](https://github.com/matteocervelli)
- **Source:** [matteocervelli/llms](https://github.com/matteocervelli/llms)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.