{"id":"1c6c3a73-42a0-441e-8a81-c7b9856cb716","entityType":"agent","slug":"clawhub-afine907-python-testing","name":"Python Testing","canonicalUrl":"https://www.xpersona.co/agent/clawhub-afine907-python-testing","canonicalPath":"/agent/clawhub-afine907-python-testing","generatedAt":"2026-10-11T14:12:50.773Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T11:05:49.680Z","emptyReason":null},"description":"Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。 Skill: Python Testing Owner: afine907 Summary: Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。 Tags: latest:1.0.0 Version history: v1.0.0 | 2026-05-15T04:11:51.231Z | user Initial release Archive index: Archive v1.0.0: 8 files, 6584 bytes Files: references/async.md (1091b), references/coverage.md (830b), references/fixtures.md (1651b), references/mocking.md (2434b), re","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s17fm1dbahvthhc4atzm70t6v585c74c:python-testing","sourceUrl":"https://clawhub.ai/afine907/python-testing","homepage":"https://clawhub.ai/afine907/skills/python-testing","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/afine907/python-testing","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/afine907/skills/python-testing","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。 Skill: Python Testing Owner: afine907 Summary: Python 测试速查。当需要："},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:05:49.680Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:05:49.680Z","emptyReason":null},"stars":null,"forks":null,"downloads":1081,"packageName":null,"latestVersion":"1.0.0","tractionLabel":"1.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:05:49.615Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T11:05:49.680Z","lastCrawledAt":"2026-10-11T11:05:49.615Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T11:05:49.615Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.0","createdAt":"2026-05-15T04:11:51.231Z","changelog":"Initial release","fileCount":8,"zipByteSize":6584}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17fm1dbahvthhc4atzm70t6v585c74c:python-testing","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T14:12:50.772Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-afine907-python-testing/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T11:05:49.680Z","emptyReason":null},"readme":"Skill: Python Testing\n\nOwner: afine907\n\nSummary: Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。\n\nTags: latest:1.0.0\n\nVersion history:\n\nv1.0.0 | 2026-05-15T04:11:51.231Z | user\n\nInitial release\n\nArchive index:\n\nArchive v1.0.0: 8 files, 6584 bytes\n\nFiles: references/async.md (1091b), references/coverage.md (830b), references/fixtures.md (1651b), references/mocking.md (2434b), references/pytest.md (2289b), skill-card.md (1792b), SKILL.md (2210b), _meta.json (133b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: python-testing\ndescription: Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。\n---\n\n# Python Testing\n\nPython 测试框架核心用法速查。\n\n## 快速参考\n\n### pytest 基础\n```bash\npytest                        # 运行所有测试\npytest -v                     # 详细输出\npytest test_module.py         # 指定文件\npytest -k \"login\"             # 匹配测试名\npytest -x                     # 失败时停止\npytest -n 4                   # 并行执行\n```\n\n### 测试示例\n```python\ndef test_addition():\n    assert 1 + 1 == 2\n\n@pytest.mark.parametrize(\"a,b,expected\", [(1,2,3), (2,3,5)])\ndef test_add(a, b, expected):\n    assert add(a, b) == expected\n```\n\n### Mock\n```python\nfrom unittest.mock import Mock, patch\n\nmock_db = Mock()\nmock_db.query.return_value = []\n\n@patch('module.function')\ndef test_with_mock(mock_func):\n    mock_func.return_value = 42\n```\n\n### Fixture\n```python\n@pytest.fixture\ndef database():\n    db = Database(\":memory:\")\n    yield db\n    db.close()\n\ndef test_query(database):\n    assert database.query(\"SELECT 1\")\n```\n\n### 覆盖率\n```bash\npytest --cov=myapp\npytest --cov=myapp --cov-report=html\n```\n\n## 详细参考\n\n- **pytest 详解**: [references/pytest.md](references/pytest.md) - 完整 pytest 用法\n- **Mock 和 Patch**: [references/mocking.md](references/mocking.md) - unittest.mock 详解\n- **Fixtures**: [references/fixtures.md](references/fixtures.md) - fixture 高级用法\n- **异步测试**: [references/async.md](references/async.md) - pytest-asyncio\n- **覆盖率**: [references/coverage.md](references/coverage.md) - pytest-cov 配置\n\n## 常用标记\n\n```python\n@pytest.mark.slow              # 标记慢测试\n@pytest.mark.integration       # 标记集成测试\n@pytest.mark.skip(reason=\"TODO\")\n@pytest.mark.skipif(sys.version_info < (3, 10))\n```\n\n## pytest.ini 配置\n\n```ini\n[pytest]\ntestpaths = tests\npython_files = test_*.py\nmarkers =\n    slow: marks tests as slow\n    integration: integration tests\naddopts = -v --tb=short\n```\n\n## 文档\n\n- pytest: https://docs.pytest.org/\n- pytest-cov: https://pytest-cov.readthedocs.io/\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7fvwdk59wp6nd02h869hrkkn85cv0p\",\n  \"slug\": \"python-testing\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1778818311231\n}\n\nFile v1.0.0:references/async.md\n\n# 异步测试\n\n## pytest-asyncio\n\n```bash\npip install pytest-asyncio\n```\n\n```python\nimport pytest\n\n@pytest.mark.asyncio\nasync def test_async_function():\n    result = await async_operation()\n    assert result == \"expected\"\n\n@pytest.mark.asyncio\nasync def test_async_with_mock():\n    with pytest.raises(ValueError):\n        await async_function_that_raises()\n```\n\n## 异步 Fixture\n\n```python\n@pytest.fixture\nasync def async_client():\n    client = await create_async_client()\n    yield client\n    await client.close()\n\n@pytest.mark.asyncio\nasync def test_with_async_fixture(async_client):\n    result = await async_client.get(\"/\")\n    assert result.status == 200\n```\n\n## httpx 异步测试\n\n```python\nimport pytest\nfrom httpx import AsyncClient, ASGITransport\nfrom myapp import app\n\n@pytest.fixture\nasync def client():\n    async with AsyncClient(\n        transport=ASGITransport(app=app),\n        base_url=\"http://test\"\n    ) as client:\n        yield client\n\n@pytest.mark.asyncio\nasync def test_api(client):\n    response = await client.get(\"/users\")\n    assert response.status_code == 200\n```\n\nFile v1.0.0:references/coverage.md\n\n# 覆盖率测试\n\n## pytest-cov\n\n```bash\npip install pytest-cov\n```\n\n## 运行覆盖率\n\n```bash\npytest --cov=myapp\npytest --cov=myapp --cov-report=term-missing\npytest --cov=myapp --cov-report=html\npytest --cov=myapp --cov-fail-under=80\npytest --cov=myapp --cov-branch\n```\n\n## .coveragerc 配置\n\n```ini\n[run]\nsource = myapp\nbranch = True\nomit =\n    */tests/*\n    */__init__.py\n\n[report]\nexclude_lines =\n    pragma: no cover\n    def __repr__\n    raise NotImplementedError\n    if TYPE_CHECKING:\n```\n\n## pyproject.toml 配置\n\n```toml\n[tool.coverage.run]\nsource = [\"myapp\"]\nbranch = true\nomit = [\"*/tests/*\"]\n\n[tool.coverage.report]\nexclude_lines = [\n    \"pragma: no cover\",\n    \"def __repr__\",\n    \"raise NotImplementedError\",\n]\n```\n\n## 查看 HTML 报告\n\n```bash\npytest --cov=myapp --cov-report=html\nopen htmlcov/index.html\n```\n\nFile v1.0.0:references/fixtures.md\n\n# Fixtures\n\n## 基本 Fixture\n\n```python\nimport pytest\n\n@pytest.fixture\ndef database():\n    db = Database(\":memory:\")\n    db.connect()\n    yield db\n    db.close()\n\ndef test_query(database):\n    result = database.query(\"SELECT 1\")\n    assert result is not None\n```\n\n## Fixture 依赖\n\n```python\n@pytest.fixture\ndef database():\n    return Database(\":memory:\")\n\n@pytest.fixture\ndef user(database):\n    return database.create_user(name=\"Alice\")\n\ndef test_user_name(user):\n    assert user.name == \"Alice\"\n```\n\n## 作用域\n\n```python\n# function: 每个测试调用一次 (默认)\n# class: 每个测试类调用一次\n# module: 每个模块调用一次\n# package: 每个包调用一次\n# session: 整个测试会话调用一次\n\n@pytest.fixture(scope=\"module\")\ndef app():\n    app = create_app()\n    app.start()\n    yield app\n    app.stop()\n\n@pytest.fixture(scope=\"session\")\ndef docker_client():\n    client = DockerClient()\n    yield client\n    client.close()\n```\n\n## autouse\n\n```python\n# 自动使用\n@pytest.fixture(autouse=True)\ndef setup_teardown():\n    print(\"Setup\")\n    yield\n    print(\"Teardown\")\n```\n\n## 参数化\n\n```python\n@pytest.fixture(params=[\"sqlite\", \"postgres\"])\ndef database(request):\n    db = create_database(request.param)\n    yield db\n    db.close()\n\ndef test_with_multiple_dbs(database):\n    # 会运行两次\n    pass\n```\n\n## conftest.py\n\n```python\n# tests/conftest.py - 共享 fixture\n\nimport pytest\n\n@pytest.fixture\ndef client():\n    app = create_app()\n    with app.test_client() as client:\n        yield client\n\n@pytest.fixture\ndef auth_header():\n    token = create_test_token()\n    return {\"Authorization\": f\"Bearer {token}\"}\n```\n\nFile v1.0.0:references/mocking.md\n\n# Mock 和 Patch\n\n## Mock 对象\n\n```python\nfrom unittest.mock import Mock, MagicMock\n\n# 创建 mock\nmock_db = Mock()\nmock_db.query.return_value = [{\"id\": 1}]\nmock_db.insert.return_value = 1\n\n# 使用\nresult = mock_db.query(\"SELECT *\")\nassert result == [{\"id\": 1}]\n\n# 验证调用\nmock_db.query.assert_called()\nmock_db.query.assert_called_once()\nmock_db.query.assert_called_with(\"SELECT *\")\n```\n\n## patch 装饰器\n\n```python\nfrom unittest.mock import patch\n\n@patch('module.Database')\ndef test_with_patch(MockDB):\n    mock_db = MockDB.return_value\n    mock_db.query.return_value = []\n\n    service = Service()\n    service.process()\n\n    mock_db.query.assert_called()\n\n# 多个 patch\n@patch('module.Database')\n@patch('module.Cache')\ndef test_multiple(MockCache, MockDB):\n    pass\n```\n\n## patch 上下文管理器\n\n```python\ndef test_with_context():\n    with patch('module.get_user') as mock_get_user:\n        mock_get_user.return_value = {\"id\": 1, \"name\": \"Alice\"}\n\n        result = process_user(1)\n        assert result == \"Alice\"\n```\n\n## patch 对象属性\n\n```python\n@patch.object(Config, 'DEBUG', True)\ndef test_debug_mode():\n    pass\n\n@patch.dict('os.environ', {'API_KEY': 'test-key'})\ndef test_with_env():\n    pass\n```\n\n## pytest-mock\n\n```python\n# pip install pytest-mock\n\ndef test_with_mocker(mocker):\n    # mock 函数\n    mock_func = mocker.patch('module.function')\n    mock_func.return_value = 42\n\n    # mock 对象方法\n    mock_method = mocker.patch.object(User, 'save')\n\n    # spy (保留原实现)\n    spy = mocker.spy(Calculator, 'add')\n\n    # mock 异步函数\n    async_mock = mocker.AsyncMock()\n    async_mock.return_value = \"result\"\n```\n\n## 常见场景\n\n```python\n# mock 环境变量\n@patch.dict('os.environ', {'API_KEY': 'test-key'})\ndef test_with_env():\n    pass\n\n# mock 时间\n@patch('time.time', return_value=1234567890)\ndef test_time(mock_time):\n    pass\n\n# mock 文件操作\n@patch('builtins.open', create=True)\ndef test_file(mock_open):\n    mock_open.return_value.__enter__.return_value.read.return_value = \"content\"\n\n# mock HTTP 请求\n@patch('requests.get')\ndef test_api(mock_get):\n    mock_get.return_value.json.return_value = {\"data\": []}\n    mock_get.return_value.status_code = 200\n\n# mock 异常\ndef test_exception(mocker):\n    mock_db = mocker.patch('module.Database')\n    mock_db.return_value.query.side_effect = ConnectionError()\n    with pytest.raises(ConnectionError):\n        service.query()\n```\n\nFile v1.0.0:references/pytest.md\n\n# pytest 详解\n\n## 运行测试\n\n```bash\npytest                        # 运行所有测试\npytest -v                     # 详细输出\npytest -vv                    # 更详细\npytest test_module.py         # 指定文件\npytest test_module.py::test_function  # 指定测试\npytest test_module.py::TestClass::test_method  # 指定方法\npytest -k \"login\"             # 匹配测试名\npytest -k \"login or logout\"\npytest -m slow                # 运行标记的测试\npytest -x                     # 失败时停止\npytest --maxfail=3            # 失败 3 次后停止\npytest -n auto                # 并行执行\npytest --lf                   # 只运行失败的测试\npytest --ff                   # 先运行失败，再运行其他\n```\n\n## 测试发现\n\n```bash\n# 默认规则\n# test_*.py 或 *_test.py\n# Test* 类 (无 __init__)\n# test_* 函数\n\npytest tests/\npytest --ignore=tests/integration\n```\n\n## 测试类\n\n```python\nclass TestUser:\n    def test_create(self):\n        user = User(name=\"Alice\")\n        assert user.name == \"Alice\"\n\n    def setup_method(self):\n        \"\"\"每个测试方法前执行\"\"\"\n        self.user = User()\n\n    def teardown_method(self):\n        \"\"\"每个测试方法后执行\"\"\"\n        pass\n```\n\n## 参数化\n\n```python\n@pytest.mark.parametrize(\"input,expected\", [\n    (1, 2),\n    (2, 4),\n    (3, 6),\n])\ndef test_double(input, expected):\n    assert double(input) == expected\n\n# 多参数\n@pytest.mark.parametrize(\"a,b,expected\", [\n    (1, 2, 3),\n    (5, 5, 10),\n])\n\n# 参数组合\n@pytest.mark.parametrize(\"x\", [1, 2, 3])\n@pytest.mark.parametrize(\"y\", [10, 20])\ndef test_multiply(x, y):\n    pass  # 6 个测试\n```\n\n## 异常测试\n\n```python\nimport pytest\n\ndef test_exception():\n    with pytest.raises(ValueError):\n        raise ValueError(\"error\")\n\ndef test_exception_message():\n    with pytest.raises(ValueError) as exc_info:\n        raise ValueError(\"specific error\")\n    assert str(exc_info.value) == \"specific error\"\n\ndef test_exception_match():\n    with pytest.raises(ValueError, match=\"specific.*error\"):\n        raise ValueError(\"specific error message\")\n```\n\n## 临时文件\n\n```python\ndef test_temp_file(tmp_path):\n    test_file = tmp_path / \"test.txt\"\n    test_file.write_text(\"content\")\n    assert test_file.read_text() == \"content\"\n```\n\nFile v1.0.0:skill-card.md\n\n## Description:\n\nPython testing quick reference for running pytest, using mock and patch, parameterizing tests, fixtures, async tests, and coverage checks.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[afine907](https://clawhub.ai/user/afine907)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use this skill as a compact Python testing reference for pytest commands, test patterns, mocks, fixtures, asynchronous tests, and coverage configuration.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Copied testing commands may install or run project dependencies in the user's environment.\n\nMitigation: Use a virtual environment and pin dependency versions for projects with stronger supply-chain requirements.\n\n## Reference(s):\n\n- [pytest](references/pytest.md)\n- [Mocking](references/mocking.md)\n- [Fixtures](references/fixtures.md)\n- [Async Testing](references/async.md)\n- [Coverage Testing](references/coverage.md)\n- [pytest documentation](https://docs.pytest.org/)\n- [pytest-cov documentation](https://pytest-cov.readthedocs.io/)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, markdown, code, shell commands, configuration]\n\n**Output Format:** [Markdown with inline bash, Python, INI, and TOML examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Concise reference material intended for an agent to adapt into testing guidance or commands.]\n\n## Skill Version(s):\n\n1.0.0 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.","readmeExcerpt":"Skill: Python Testing Owner: afine907 Summary: Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。 Tags: latest:1.0.0 Version history: v1.0.0 | 2026-05-15T04:11:51.231Z | user Initial release Archive index: Archive v1.0.0: 8 files, 6584 bytes Files: references/async.md (1091b), references/coverage.md (830b), references/fixtures.md (1651b), references/mocking.md (2434b), re","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"pytest                        # 运行所有测试\npytest -v                     # 详细输出\npytest test_module.py         # 指定文件\npytest -k \"login\"             # 匹配测试名\npytest -x                     # 失败时停止\npytest -n 4                   # 并行执行"},{"language":"python","snippet":"def test_addition():\n    assert 1 + 1 == 2\n\n@pytest.mark.parametrize(\"a,b,expected\", [(1,2,3), (2,3,5)])\ndef test_add(a, b, expected):\n    assert add(a, b) == expected"},{"language":"python","snippet":"from unittest.mock import Mock, patch\n\nmock_db = Mock()\nmock_db.query.return_value = []\n\n@patch('module.function')\ndef test_with_mock(mock_func):\n    mock_func.return_value = 42"},{"language":"python","snippet":"@pytest.fixture\ndef database():\n    db = Database(\":memory:\")\n    yield db\n    db.close()\n\ndef test_query(database):\n    assert database.query(\"SELECT 1\")"},{"language":"bash","snippet":"pytest --cov=myapp\npytest --cov=myapp --cov-report=html"},{"language":"python","snippet":"@pytest.mark.slow              # 标记慢测试\n@pytest.mark.integration       # 标记集成测试\n@pytest.mark.skip(reason=\"TODO\")\n@pytest.mark.skipif(sys.version_info < (3, 10))"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: python-testing\ndescription: Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。\n---\n\n# Python Testing\n\nPython 测试框架核心用法速查。\n\n## 快速参考\n\n### pytest 基础\n```bash\npytest                        # 运行所有测试\npytest -v                     # 详细输出\npytest test_module.py         # 指定文件\npytest -k \"login\"             # 匹配测试名\npytest -x                     # 失败时停止\npytest -n 4                   # 并行执行\n```\n\n### 测试示例\n```python\ndef test_addition():\n    assert 1 + 1 == 2\n\n@pytest.mark.parametrize(\"a,b,expected\", [(1,2,3), (2,3,5)])\ndef test_add(a, b, expected):\n    assert add(a, b) == expected\n```\n\n### Mock\n```python\nfrom unittest.mock import Mock, patch\n\nmock_db = Mock()\nmock_db.query.return_value = []\n\n@patch('module.function')\ndef test_with_mock(mock_func):\n    mock_func.return_value = 42\n```\n\n### Fixture\n```python\n@pytest.fixture\ndef database():\n    db = Database(\":memory:\")\n    yield db\n    db.close()\n\ndef test_query(database):\n    assert database.query(\"SELECT 1\")\n```\n\n### 覆盖率\n```bash\npytest --cov=myapp\npytest --cov=myapp --cov-report=html\n```\n\n## 详细参考\n\n- **pytest 详解**: [references/pytest.md](references/pytest.md) - 完整 pytest 用法\n- **Mock 和 Patch**: [references/mocking.md](references/mocking.md) - unittest.mock 详解\n- **Fixtures**: [references/fixtures.md](references/fixtures.md) - fixture 高级用法\n- **异步测试**: [references/async.md](references/async.md) - pytest-asyncio\n- **覆盖率**: [references/coverage.md](references/coverage.md) - pytest-cov 配置\n\n## 常用标记\n\n```python\n@pytest.mark.slow              # 标记慢测试\n@pytest.mark.integration       # 标记集成测试\n@pytest.mark.skip(reason=\"TODO\")\n@pytest.mark.skipif(sys.version_info < (3, 10))\n```\n\n## pytest.ini 配置\n\n```ini\n[pytest]\ntestpaths = tests\npython_files = test_*.py\nmarkers =\n    slow: marks tests as slow\n    integration: integration tests\naddopts = -v --tb=short\n```\n\n## 文档\n\n- pytest: https://docs.pytest.org/\n- pytest-cov: https://pytest-cov.readthedocs.io/"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7fvwdk59wp6nd02h869hrkkn85cv0p\",\n  \"slug\": \"python-testing\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1778818311231\n}"},{"path":"references/async.md","content":"# 异步测试\n\n## pytest-asyncio\n\n```bash\npip install pytest-asyncio\n```\n\n```python\nimport pytest\n\n@pytest.mark.asyncio\nasync def test_async_function():\n    result = await async_operation()\n    assert result == \"expected\"\n\n@pytest.mark.asyncio\nasync def test_async_with_mock():\n    with pytest.raises(ValueError):\n        await async_function_that_raises()\n```\n\n## 异步 Fixture\n\n```python\n@pytest.fixture\nasync def async_client():\n    client = await create_async_client()\n    yield client\n    await client.close()\n\n@pytest.mark.asyncio\nasync def test_with_async_fixture(async_client):\n    result = await async_client.get(\"/\")\n    assert result.status == 200\n```\n\n## httpx 异步测试\n\n```python\nimport pytest\nfrom httpx import AsyncClient, ASGITransport\nfrom myapp import app\n\n@pytest.fixture\nasync def client():\n    async with AsyncClient(\n        transport=ASGITransport(app=app),\n        base_url=\"http://test\"\n    ) as client:\n        yield client\n\n@pytest.mark.asyncio\nasync def test_api(client):\n    response = await client.get(\"/users\")\n    assert response.status_code == 200\n```"},{"path":"references/coverage.md","content":"# 覆盖率测试\n\n## pytest-cov\n\n```bash\npip install pytest-cov\n```\n\n## 运行覆盖率\n\n```bash\npytest --cov=myapp\npytest --cov=myapp --cov-report=term-missing\npytest --cov=myapp --cov-report=html\npytest --cov=myapp --cov-fail-under=80\npytest --cov=myapp --cov-branch\n```\n\n## .coveragerc 配置\n\n```ini\n[run]\nsource = myapp\nbranch = True\nomit =\n    */tests/*\n    */__init__.py\n\n[report]\nexclude_lines =\n    pragma: no cover\n    def __repr__\n    raise NotImplementedError\n    if TYPE_CHECKING:\n```\n\n## pyproject.toml 配置\n\n```toml\n[tool.coverage.run]\nsource = [\"myapp\"]\nbranch = true\nomit = [\"*/tests/*\"]\n\n[tool.coverage.report]\nexclude_lines = [\n    \"pragma: no cover\",\n    \"def __repr__\",\n    \"raise NotImplementedError\",\n]\n```\n\n## 查看 HTML 报告\n\n```bash\npytest --cov=myapp --cov-report=html\nopen htmlcov/index.html\n```"},{"path":"references/fixtures.md","content":"# Fixtures\n\n## 基本 Fixture\n\n```python\nimport pytest\n\n@pytest.fixture\ndef database():\n    db = Database(\":memory:\")\n    db.connect()\n    yield db\n    db.close()\n\ndef test_query(database):\n    result = database.query(\"SELECT 1\")\n    assert result is not None\n```\n\n## Fixture 依赖\n\n```python\n@pytest.fixture\ndef database():\n    return Database(\":memory:\")\n\n@pytest.fixture\ndef user(database):\n    return database.create_user(name=\"Alice\")\n\ndef test_user_name(user):\n    assert user.name == \"Alice\"\n```\n\n## 作用域\n\n```python\n# function: 每个测试调用一次 (默认)\n# class: 每个测试类调用一次\n# module: 每个模块调用一次\n# package: 每个包调用一次\n# session: 整个测试会话调用一次\n\n@pytest.fixture(scope=\"module\")\ndef app():\n    app = create_app()\n    app.start()\n    yield app\n    app.stop()\n\n@pytest.fixture(scope=\"session\")\ndef docker_client():\n    client = DockerClient()\n    yield client\n    client.close()\n```\n\n## autouse\n\n```python\n# 自动使用\n@pytest.fixture(autouse=True)\ndef setup_teardown():\n    print(\"Setup\")\n    yield\n    print(\"Teardown\")\n```\n\n## 参数化\n\n```python\n@pytest.fixture(params=[\"sqlite\", \"postgres\"])\ndef database(request):\n    db = create_database(request.param)\n    yield db\n    db.close()\n\ndef test_with_multiple_dbs(database):\n    # 会运行两次\n    pass\n```\n\n## conftest.py\n\n```python\n# tests/conftest.py - 共享 fixture\n\nimport pytest\n\n@pytest.fixture\ndef client():\n    app = create_app()\n    with app.test_client() as client:\n        yield client\n\n@pytest.fixture\ndef auth_header():\n    token = create_test_token()\n    return {\"Authorization\": f\"Bearer {token}\"}\n```"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。 Skill: Python Testing Owner: afine907 Summary: Python 测试速查。当需要：(1) 运行 pytest 测试 (2) 使用 mock/patch (3) 参数化测试 (4) fixtures (5) 异步测试 (6) 覆盖率测试时使用。 Tags: latest:1.0.0 Version history: v1.0.0 | 2026-05-15T04:11:51.231Z | user Initial release Archive index: Archive v1.0.0: 8 files, 6584 bytes Files: references/async.md (1091b), references/coverage.md (830b), references/fixtures.md (1651b), references/mocking.md (2434b), re","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":441,"uniquenessScore":64,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T11:05:49.680Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T11:05:49.680Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T14:12:50.773Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}