Token导航 LogoToken导航

Agent Skill · 开发

python-testing(Python 测试)

用于辅助 Python 项目开发、测试、依赖管理和常见框架工作流。它适合让 Agent 阅读 Python 代码、定位测试问题、整理运行命令、生成脚本或分析数据处理逻辑。使用时需要确认项目虚拟环境、依赖版本和测试入口;涉及执行脚本、读写文件、访问数据库或调用外部 API 时,应先明确运行目录和输入输出范围,避免误改生产数据。

python-testing 是开发类 Agent Skill,可用宿主为 Local Agent,通过unknown获取,权限为接触敏感数据;许可证信息还不明确,暂无第三方扫描结果,按安装量在开发类的 21,746 个 Skill 里排第 17,004。

总安装 447周安装 19下载 157核验 2026-05-01
开发接触敏感数据unknown未标认证来源可访问许可证需确认审计未展示Local Agent

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:python-testing(Python 测试)
来源仓库:https://smithery.ai
仓库路径:python-testing
安装命令:
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。当前暂无明确安装命令,请以来源页面说明为准。

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

python-testing 用于辅助 Python 项目开发、测试、依赖管理和常见框架工作流。适合让 Agent 阅读 Python 代码、定位测试问题或整理运行命令。使用时需确认项目虚拟环境、依赖版本和测试入口。涉及执行脚本或访问数据库时,应先明确运行目录和输入输出范围。建议避免误改生产数据,必要时先备份再操作。

来源仓库内路径:python-testing

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Local Agent;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    没有现成安装命令,按unknown的说明从来源页面获取,仓库路径是 python-testing。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

python-testing 怎么安装?

公开资料没有给出可以直接复制的命令,需要按来源页面说明手动安装,仓库内路径为 python-testing。

python-testing 支持哪些 AI 工具?

公开资料标注支持 Local Agent。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

python-testing 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

python-testing 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

python-testing 用的人多吗?

公开数据是累计安装 447 次,近一周安装 19 次,下载 157 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

python-testing 安全吗?

没有查到第三方扫描结果,安全性无法从公开资料判断,安装前请自行审查源码、依赖和命令行为。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 Local Agent 一种宿主,触发方式和使用习惯不用来回切换。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 没有第三方扫描结果,安全性只能靠自己读源码判断。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Local Agent,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 要求有安全扫描结论才肯安装的团队。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
python-testing

Python 测试 · 本页

447—接触敏感数据未明确未收录

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Python Testing Practices

Python-specific testing patterns and best practices using pytest, complementing general testing-workflow skill.

CRITICAL: UV Execution Rules

NEVER use -m flag with uv run:

# ✅ CORRECT - UV pytest execution
uv run pytest
uv run pytest -v
uv run pytest tests/unit/ -v
uv run pytest --cov=app --cov-report=html

# ❌ WRONG - Never add -m flag
# ❌ uv run -m pytest
# ❌ uv run -m pytest -v

Always use uv run pytest directly (never call pytest directly in uv projects).


Pytest Fixtures

Fixture Scopes

Pytest fixtures support different scopes for setup/teardown control:

@pytest.fixture(scope="session")
def database_connection():
    """Created once per test session - expensive setup."""
    connection = setup_expensive_database()
    yield connection
    connection.cleanup()

@pytest.fixture(scope="module")
def api_client():
    """Created once per test module."""
    return APIClient(config="test")

@pytest.fixture(scope="class")
def service_instance():
    """Created once per test class."""
    return Service()

@pytest.fixture(scope="function")  # Default
def user():
    """Created for each test function - isolated."""
    return User(email="test@example.com")

Fixture Setup and Teardown

Use yield pattern for setup/teardown with proper cleanup:

@pytest.fixture
def database():
    """Fixture with setup and teardown."""
    # Setup
    db = Database(":memory:")
    db.initialize()
    db.create_schema()

    # Provide to test
    yield db

    # Teardown
    db.close()

@pytest.fixture
def mock_file(tmp_path):
    """Create temporary file that auto-cleans up."""
    temp_file = tmp_path / "test.txt"
    temp_file.write_text("test data")
    yield temp_file
    # Cleanup automatic with tmp_path

Fixture Dependency Injection

Fixtures can depend on other fixtures:

@pytest.fixture
def database():
    """Base database fixture."""
    db = Database(":memory:")
    db.initialize()
    yield db
    db.close()

@pytest.fixture
def user_service(database):
    """Service depending on database fixture."""
    return UserService(database)

@pytest.fixture
def authenticated_user(user_service):
    """User depending on service fixture."""
    user = user_service.create_user(
        username="testuser",
        email="test@example.com",
        password="secure"
    )
    yield user
    user_service.delete_user(user.id)

conftest.py Patterns

Central Fixture Location

Place shared fixtures in conftest.py at appropriate levels:

tests/
├── conftest.py              # Session/module level fixtures
├── unit/
│   ├── conftest.py          # Unit-specific fixtures
│   └── test_*.py
└── integration/
    ├── conftest.py          # Integration-specific fixtures
    └── test_*.py

Example conftest.py

# tests/conftest.py
import pytest
from app.services import UserService
from app.database import Database

@pytest.fixture(scope="session")
def database_connection():
    """Database connection for entire session."""
    db = Database(":memory:")
    db.initialize()
    db.run_migrations()
    yield db
    db.close()

@pytest.fixture
def user_service(database_connection):
    """UserService with test database."""
    return UserService(database_connection)

@pytest.fixture
def sample_user_data():
    """Standard user data for tests."""
    return {
        "username": "testuser",
        "email": "test@example.com",
        "password": "secure123",
        "age": 25
    }

@pytest.fixture
def temp_config_file(tmp_path):
    """Create temporary config file."""
    config_file = tmp_path / "config.json"
    config_file.write_text('{"setting": "value"}')
    return config_file

Parametrized Testing

Basic Parametrization

Use @pytest.mark.parametrize for multiple test inputs:

import pytest

@pytest.mark.parametrize("input,expected", [
    ("hello", "HELLO"),
    ("world", "WORLD"),
    ("", ""),
    ("MiXeD", "MIXED"),
])
def test_uppercase(input, expected):
    """Test uppercase conversion with multiple inputs."""
    assert input.upper() == expected

Multiple Parameters

@pytest.mark.parametrize("method,expected_status", [
    ("GET", 200),
    ("POST", 201),
    ("PUT", 200),
    ("DELETE", 204),
])
def test_http_methods(client, method, expected_status):
    """Test different HTTP methods."""
    response = client.request(method, "/api/resource")
    assert response.status_code == expected_status

Parametrized Fixtures

@pytest.mark.parametrize("user_role", ["admin", "user", "guest"])
def test_permission_levels(user_role):
    """Test different user permission levels."""
    user = User(role=user_role)
    assert user.can_access_dashboard() == (user_role in ["admin", "user"])

Async Testing

Marking Async Tests

Use @pytest.mark.asyncio decorator:

import pytest

@pytest.mark.asyncio
async def test_async_fetch_data():
    """Test async data fetching."""
    result = await fetch_data_async("user123")
    assert result is not None
    assert result["id"] == "user123"

@pytest.mark.asyncio
async def test_concurrent_requests():
    """Test multiple concurrent async operations."""
    results = await asyncio.gather(
        fetch_user(1),
        fetch_user(2),
        fetch_user(3),
    )
    assert len(results) == 3

Async Fixtures

@pytest.fixture
async def async_client():
    """Async HTTP client fixture."""
    client = AsyncHTTPClient()
    await client.connect()
    yield client
    await client.disconnect()

@pytest.mark.asyncio
async def test_api_call(async_client):
    """Test with async fixture."""
    response = await async_client.get("/api/users")
    assert response.status_code == 200

Mocking Patterns

Mock Objects and Patching

from unittest.mock import Mock, patch, MagicMock
import pytest

def test_send_email_success():
    """Test email sending with mocked SMTP."""
    # Create mock object
    mock_smtp = Mock()

    with patch("smtplib.SMTP", return_value=mock_smtp):
        result = send_email("test@example.com", "Subject", "Body")

    # Verify mock was called correctly
    mock_smtp.send_message.assert_called_once()
    assert result is True

def test_api_call_with_mock():
    """Test API call with mocked response."""
    with patch("requests.get") as mock_get:
        mock_get.return_value.json.return_value = {"status": "ok"}

        result = fetch_api_data()

        mock_get.assert_called_once_with("https://api.example.com/data")
        assert result["status"] == "ok"

Fixture-Based Mocking

@pytest.fixture
def mock_database():
    """Provide mocked database."""
    with patch("app.database.Database") as mock_db:
        mock_db.return_value.query.return_value = {"id": 1, "name": "Test"}
        yield mock_db

def test_user_service_with_mock(mock_database):
    """Test service with mocked database dependency."""
    service = UserService(mock_database.return_value)
    user = service.get_user(1)
    assert user["name"] == "Test"

@pytest.fixture
def mock_api_client():
    """Provide mocked API client."""
    with patch("app.client.APIClient") as mock:
        mock.return_value.get.return_value = {"status": "ok"}
        mock.return_value.post.return_value = {"id": 123}
        yield mock

Spy on Real Objects

from unittest.mock import MagicMock

def test_spy_on_method():
    """Spy on actual method calls."""
    obj = RealObject()
    obj.method = MagicMock(side_effect=obj.method)

    result = obj.method("arg1")

    obj.method.assert_called_once_with("arg1")
    assert result == expected_value

Exception Testing

Testing with Context Managers

import pytest
from app.exceptions import UserNotFoundError, ValidationError

def test_exception_raised():
    """Test that correct exception is raised."""
    with pytest.raises(UserNotFoundError) as exc_info:
        user_service.get_user("nonexistent_id")

    assert "nonexistent_id" in str(exc_info.value)

def test_validation_error():
    """Test validation error with message check."""
    user_data = {
        "username": "testuser",
        "email": "invalid-email",  # Invalid format
        "age": 25
    }

    with pytest.raises(ValidationError) as exc_info:
        user_service.create_user(user_data)

    assert "email" in str(exc_info.value)

def test_exception_type_matching():
    """Test matching specific exception type."""
    with pytest.raises((ValueError, TypeError)):
        process_data(None)

pyproject.toml Configuration

Complete Pytest Configuration

[tool.pytest.ini_options]
# Test discovery
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]

# Output and behavior
addopts = [
    "-v",
    "--strict-markers",
    "--tb=short",
    "--cov=app",
    "--cov-report=term-missing",
    "--cov-report=html",
]

# Custom markers
markers = [
    "slow: marks tests as slow (deselect with '-m \"not slow\"')",
    "integration: marks tests as integration tests",
    "unit: marks tests as unit tests",
    "asyncio: marks tests as async tests",
]

# Filter warnings as errors
filterwarnings = [
    "error",
    "ignore::DeprecationWarning:setuptools",  # Ignore specific warnings if needed
]

Coverage Configuration

[tool.coverage.run]
source = ["app"]
omit = [
    "*/tests/*",
    "*/migrations/*",
    "*/__init__.py",
    "*/__main__.py",
]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "raise AssertionError",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
    "if TYPE_CHECKING:",
    "class .*\\bProtocol\\):",
    "@(abc\\.)?abstractmethod",
]
min_coverage = 80

Makefile Integration

Test Targets

.PHONY: test test-unit test-integration test-coverage test-quick

# Run all tests
test:
	uv run pytest

# Unit tests only
test-unit:
	uv run pytest tests/unit/ -v

# Integration tests
test-integration:
	uv run pytest tests/integration/ -v

# Quick tests (skip slow)
test-quick:
	uv run pytest -m "not slow" -v

# Coverage report
test-coverage:
	uv run pytest --cov=app --cov-report=html --cov-report=term
	@echo "Coverage report: htmlcov/index.html"

# Watch mode (requires pytest-watch)
test-watch:
	uv run ptw tests/unit/

# Full test suite with all checks
check: test lint type-check
	@echo "All checks passed!"

Development Dependencies Installation

Installing with UV

# Core testing
uv add --dev pytest pytest-cov pytest-asyncio

# Mocking
uv add --dev pytest-mock

# Performance testing
uv add --dev pytest-benchmark

# Test data generation
uv add --dev faker factory-boy

# HTTP mocking
uv add --dev responses

# Watch mode (optional)
uv add --dev pytest-watch

# Parallel execution (optional)
uv add --dev pytest-xdist

Import Error Solutions

Issue: Tests Can't Import App Modules

Solution 1: Ensure init.py exists

tests/
├── __init__.py  # Important!
├── conftest.py
└── unit/
    ├── __init__.py
    └── test_*.py

Solution 2: Add to conftest.py

import sys
from pathlib import Path

# Add src directory to path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

Solution 3: Use pyproject.toml

[tool.pytest.ini_options]
pythonpath = ["src"]

Deleted File Handling

Skip Module-Level When Imports Fail

Move pytest.skip() BEFORE imports to prevent collection errors:

# tests/removed_feature_test.py
import pytest

pytest.skip("Module removed - feature deleted", allow_module_level=True)

from deleted_module import Something  # Won't be evaluated

Warnings as Errors Policy

Enforce Clean Test Output

Treat all warnings as errors in tests:

# Run tests with warnings as errors
uv run pytest -W error

# Run with specific warning filters
uv run pytest -W error::DeprecationWarning

Configuration in pyproject.toml

[tool.pytest.ini_options]
filterwarnings = ["error"]

Handle Expected Warnings

import warnings
import pytest

def test_deprecated_function():
    """Test deprecated function with expected warning."""
    with pytest.warns(DeprecationWarning):
        deprecated_function()

def test_suppress_specific_warning():
    """Test while ignoring specific warning."""
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", DeprecationWarning)
        function_that_warns()

User Deletion Handling

Test Database User Cleanup

When tests create users, ensure cleanup:

@pytest.fixture
def created_user(user_service):
    """Create test user with automatic cleanup."""
    user = user_service.create_user(
        username="testuser",
        email="test@example.com",
        password="secure"
    )

    yield user

    # Cleanup - delete after test
    user_service.delete_user(user.id)

def test_user_operations(created_user):
    """Test operations on created user."""
    assert created_user.id is not None
    # User automatically deleted after test

Handle User Onboarding Flow

@pytest.fixture
def onboarded_user(user_service):
    """Create and fully onboard test user."""
    user = user_service.create_user(
        username="newuser",
        email="new@example.com",
        password="secure"
    )

    # Complete onboarding
    user_service.set_profile(user.id, name="Test User")
    user_service.verify_email(user.id)

    yield user

    # Cleanup
    user_service.delete_user(user.id)

Common Testing Patterns

Arrange-Act-Assert

def test_create_user_success(user_service):
    """Test successful user creation."""
    # Arrange - Set up test data
    user_data = {
        "username": "testuser",
        "email": "test@example.com",
        "age": 25
    }

    # Act - Execute functionality
    user = user_service.create_user(user_data)

    # Assert - Verify results
    assert user is not None
    assert user.username == "testuser"
    assert user.email == "test@example.com"
    assert user.age == 25

Database Integration

@pytest.fixture(scope="module")
def test_database():
    """Provide test database for integration tests."""
    db = Database("test.db")
    db.migrate()
    yield db
    db.close()

def test_user_repository_integration(test_database):
    """Test user repository with real database."""
    repo = UserRepository(test_database)

    # Create
    user = repo.create(username="testuser", email="test@example.com")
    assert user.id is not None

    # Retrieve
    retrieved = repo.get(user.id)
    assert retrieved.username == "testuser"

    # Update
    retrieved.email = "updated@example.com"
    repo.update(retrieved)

    # Verify
    updated = repo.get(user.id)
    assert updated.email == "updated@example.com"

Test Markers and Organization

@pytest.mark.slow
def test_expensive_operation():
    """Long-running test - can be skipped."""
    pass

@pytest.mark.integration
def test_database_integration():
    """Integration test with external service."""
    pass

@pytest.mark.asyncio
@pytest.mark.slow
def test_async_integration():
    """Async integration test."""
    pass

# Run commands:
# uv run pytest -m "not slow"          # Skip slow tests
# uv run pytest -m integration         # Only integration
# uv run pytest -m "integration and not slow"  # Filter multiple

Edge Case Testing

Common Edge Cases

def test_edge_cases():
    """Test edge cases comprehensively."""
    calculator = Calculator()

    # Empty input
    assert calculator.sum([]) == 0

    # Single item
    assert calculator.sum([5]) == 5

    # Negative numbers
    assert calculator.sum([-1, -2, -3]) == -6

    # Mixed positive/negative
    assert calculator.sum([10, -5, 3]) == 8

    # Large numbers
    assert calculator.sum([10**10, 10**10]) == 2 * 10**10

    # Zero
    assert calculator.sum([0, 0, 0]) == 0

None Value Handling

def test_none_handling(service):
    """Test handling of None values."""
    # None input raises error
    with pytest.raises(ValueError):
        service.process(None)

    # None in list gets filtered
    result = service.process_list([1, None, 3])
    assert result == [1, 3]

Note: For general testing principles and strategies not specific to Python, see the testing-workflow skill.

平台分布

Local Agent

86.55%
按下载量换算136

安全审计

暂无安全审计结果可展示。

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills