Python Testing
affaan-m/ECC
Python testing strategies using pytest, TDD methodology, fixtures, mocking, parametrization, and coverage requirements.
Pytest patterns for the agent-core codebase: a red-green-refactor workflow, conftest fixtures, custom marks, monkeypatch and patch mocking, and async tests.
$ npx skills add openJiuwen-ai/agent-core --skill python-testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install openJiuwen-ai/agent-core python-testing --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/openJiuwen-ai/agent-core.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/python-testing .claude/skills/python-testing && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "python-testing" agent skill from https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testing into .claude/skills/python-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-testing", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add openJiuwen-ai/agent-core --skill python-testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install openJiuwen-ai/agent-core python-testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/openJiuwen-ai/agent-core.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/python-testing .agents/skills/python-testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "python-testing" agent skill from https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testing into .agents/skills/python-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-testing", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add openJiuwen-ai/agent-core --skill python-testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install openJiuwen-ai/agent-core python-testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/openJiuwen-ai/agent-core.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/python-testing .cursor/skills/python-testing && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "python-testing" agent skill from https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testing into .cursor/skills/python-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-testing", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/openJiuwen-ai/agent-core.git --path .claude/skills/python-testing--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add openJiuwen-ai/agent-core --skill python-testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install openJiuwen-ai/agent-core python-testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/openJiuwen-ai/agent-core.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/python-testing .gemini/skills/python-testing && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "python-testing" agent skill from https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testing into .gemini/skills/python-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-testing", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install openJiuwen-ai/agent-core python-testingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add openJiuwen-ai/agent-core --skill python-testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/openJiuwen-ai/agent-core.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/python-testing .github/skills/python-testing && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "python-testing" agent skill from https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testing into .github/skills/python-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-testing", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add openJiuwen-ai/agent-core --skill python-testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install openJiuwen-ai/agent-core python-testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/openJiuwen-ai/agent-core.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/python-testing .opencode/skills/python-testing && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "python-testing" agent skill from https://github.com/openJiuwen-ai/agent-core/tree/develop/.claude/skills/python-testing into .opencode/skills/python-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-testing", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
python-testingPytest patterns for the agent-core codebase: a red-green-refactor workflow, conftest fixtures, custom marks, monkeypatch and patch mocking, and async tests.
Written for the openJiuwen agent-core repository, the guide has the agent write a failing test first, make the smallest change that passes and then refactor with the tests still green. It shows where fixtures belong, in a project-wide tests conftest file or a module-level one, and gives patterns for parametrized fixtures, factory fixtures and the sparing use of autouse for global resets.
Pytest marks are defined in pyproject.toml, for example a unit mark for fast tests with no I/O, so subsets can be picked with pytest -m. For mocking it prefers monkeypatch for simple cases, uses patch for class methods and recommends autospec so mocks match real signatures. Async tests use the pytest asyncio mark.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 8345a27. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pytestFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Agent-Core Python Testing loads about 2.3k tokens when it runs. Until then it costs about 25 tokens; SKILL.md has 199 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from openJiuwen-ai/agent-core at commit 8345a27, republished under its Apache-2.0 licence (© openJiuwen-ai). 199 words, ~2,268 tokens.
.claude/skills/python-testing/SKILL.md (or your agent's skills folder).Comprehensive pytest patterns for agent-core. This skill extends
.claude/rules/python/testing.md and .claude/rules/testing.md.
Write tests before implementation. Follow the red-green-refactor cycle:
For agent-core, this means:
# RED: Write the test first
class TestAbilityManager:
@pytest.mark.asyncio
async def test_registers_tool(self):
manager = AbilityManager()
card = ToolCard(name="echo", description="echo input", parameters={})
await manager.register_tool(card, echo_handler)
assert "echo" in manager.list_tools()
# GREEN: Minimal implementation
# ...
# REFACTOR: Clean up, add edge cases
@pytest.mark.asyncio
async def test_raises_on_duplicate_registration(self):
manager = AbilityManager()
card = ToolCard(name="echo", description="echo input", parameters={})
await manager.register_tool(card, echo_handler)
with pytest.raises(ConfigurationError, match="already registered"):
await manager.register_tool(card, echo_handler)Define fixtures in tests/conftest.py for project-wide fixtures, or in
tests/unit_tests/<module>/conftest.py for module-specific fixtures.
# tests/conftest.py
import pytest
from unittest import mock
@pytest.fixture
def mock_llm_client():
"""Provides a mocked LLM client for all tests."""
with mock.patch("openjiuwen.core.foundation.LLMClient") as cls:
instance = mock.MagicMock()
instance.call.return_value = '{"result": "ok"}'
cls.return_value = instance
yield instance
@pytest.fixture(scope="module")
def sample_agent_card():
"""Module-scoped: created once per test module."""
return AgentCard(id="test-agent", name="TestAgent", version="1.0")
@pytest.fixture
def temp_workspace(tmp_path):
"""Provides a clean temporary directory for each test."""
workspace = tmp_path / "workspace"
workspace.mkdir()
yield workspace
# Cleanup happens automatically via tmp_path@pytest.fixture(params=["haiku", "sonnet", "opus"])
def llm_model(request: pytest.FixtureRequest):
return request.param
async def test_llm_client(llm_model: str):
client = LLMClient(model=llm_model)
result = await client.call("hello")
assert result is not None@pytest.fixture
def make_tool_card():
"""Factory fixture: creates ToolCards with defaults."""
def _make(name: str = "test-tool", **kwargs) -> ToolCard:
defaults = {
"description": "a test tool",
"parameters": {},
"version": "1.0",
}
defaults.update(kwargs)
return ToolCard(name=name, **defaults)
return _make
async def test_registers_custom_tool(make_tool_card):
card = make_tool_card(name="custom")
manager = AbilityManager()
await manager.register_tool(card, handler)
assert "custom" in manager.list_tools()Use autouse sparingly — only for global setup that must happen for every
test in the scope:
@pytest.fixture(autouse=True)
def reset_global_state():
"""Reset global state before each test to ensure isolation."""
original = Runner.resource_mgr
Runner.resource_mgr = ResourceManager()
yield
Runner.resource_mgr = originalIn pyproject.toml:
[tool.pytest.ini_options]
markers = [
"unit: fast, deterministic tests with no I/O",
"integration: tests requiring external services",
"slow: long-running tests (skipped by default)",
"e2e: end-to-end workflow tests",
]# Run only fast unit tests (skip slow + integration)
pytest -m "unit"
# Run unit + integration, skip slow
pytest -m "not slow"
# Run everything including slow tests
pytest -m ""
# Run only e2e tests
pytest -m "e2e"Use monkeypatch for simple cases — prefer it over @patch decorators:
def test_reads_config(monkeypatch, tmp_path):
config_file = tmp_path / "config.json"
config_file.write_text('{"timeout": 30}')
monkeypatch.setattr(
"openjiuwen.core.config.CONFIG_PATH",
config_file
)
config = load_config()
assert config.timeout == 30Use @patch when mocking class methods or when the mock needs to be
accessed inside the test:
from unittest import mock
@mock.patch("openjiuwen.harness.DeepAgent._run_step", new_callable=mock.AsyncMock)
async def test_delegates_to_subagent(mock_run_step):
mock_run_step.return_value = StepResult(
status="success",
subagent_called=True,
)
agent = DeepAgent()
result = await agent.run("complex task")
assert result.subagent_called
mock_run_step.assert_called_once()Use autospec=True to automatically match the signature of the real method:
with mock.patch(
"openjiuwen.core.foundation.LLMClient.call",
autospec=True
) as mock_call:
mock_call.return_value = '{"choices": [{"message": {"content": "ok"}}]}'
# mock_call.assert_called_once_with("prompt") # Enforces correct signatureFor async methods:
from unittest import mock
with mock.patch(
"openjiuwen.harness.DeepAgent._run_step",
new_callable=mock.AsyncMock
) as mock_step:
mock_step.return_value = StepResult(status="success")
result = await agent.run("test")
assert result.status == "success"from unittest import mock
def test_sandbox_executes_within_scope():
with mock.patch(
"openjiuwen.core.sys_operation.sandbox.SandboxedRunner.run"
) as mock_run:
mock_run.return_value = CommandResult(stdout="ok", stderr="", code=0)
result = sandbox.run("echo hello")
assert result.stdout == "ok"
mock_run.assert_called_once_with("echo hello")In pyproject.toml:
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"@pytest.mark.asyncio
async def test_ability_manager_registers_tool():
manager = AbilityManager()
card = ToolCard(name="test", description="test tool", parameters={})
await manager.register_tool(card, handler)
tools = manager.list_tools()
assert "test" in toolsUse unittest.IsolatedAsyncioTestCase for test classes that need strict
per-test isolation:
from unittest import IsolatedAsyncioTestCase
class TestRunner(IsolatedAsyncioTestCase):
async def asyncSetUp(self) -> None:
self.runner = await create_runner()
self.runner.resource_mgr.clear()
async def asyncTearDown(self) -> None:
await self.runner.shutdown()
async def test_it_executes_task(self) -> None:
result = await self.runner.execute("test task")
self.assertEqual(result.status, "success")@pytest.mark.asyncio
async def test_saves_session(tmp_path):
session_dir = tmp_path / "sessions"
session_dir.mkdir()
manager = SessionManager(base_dir=session_dir)
await manager.save(SessionData(id="s1", turns=[]))
assert (session_dir / "s1.json").exists()Mirror the source path in test paths:
| Source | Test |
|---|---|
openjiuwen/harness/deep_agent.py | tests/unit_tests/harness/test_deep_agent.py |
openjiuwen/core/single_agent/react_agent.py | tests/unit_tests/core/single_agent/test_react_agent.py |
openjiuwen/core/workflow/engine.py | tests/unit_tests/core/workflow/test_engine.py |
# pytest.ini
[pytest]
asyncio_mode = auto
asyncio_default_fixture_loop_scope = function
testpaths = tests/unit_tests tests/system_tests
markers =
unit: fast deterministic tests, no I/O
integration: tests requiring external services
slow: long-running tests, skipped by default
e2e: end-to-end workflow tests# pyproject.toml additions
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
filterwarnings = [
"ignore::DeprecationWarning",
]
[tool.coverage.run]
source = ["openjiuwen/"]
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/migrations/*",
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
"raise NotImplementedError",
]
fail_under = 80© openJiuwen-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/python-testing of openJiuwen-ai/agent-core.
Open the folder on GitHubat commit 8345a27
Agent-Core Python Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Agent-Core Python Testing this skillopenJiuwen-ai/agent-core | 442 | — | ~2.3k | Automated safety check: Pass | Apache-2.0 | |
| Python Testingaffaan-m/ECC | 275k | 6 repos | ~4.7k | Automated safety check: Pass | MIT | |
| Python Testingaffaan-m/ECC | 275k | 3 repos | ~4.2k | Automated safety check: Pass | MIT | |
| Python Testing Patternsjh941213/my-cc-harness | 126 | 17 repos | ~5.4k | Automated safety check: Pass | None | |
| Python Testingaffaan-m/ECC | 275k | 2 repos | ~4.3k | Automated safety check: Pass | MIT | |
| Python Testingaffaan-m/ECC | 275k | 1 repos | ~4.9k | Automated safety check: Pass | MIT |
affaan-m/ECC
Python testing strategies using pytest, TDD methodology, fixtures, mocking, parametrization, and coverage requirements.
affaan-m/ECC
使用pytest的Python测试策略,包括TDD方法、夹具、模拟、参数化和覆盖率要求. An agent skill from affaan-m/ECC.
jh941213/my-cc-harness
Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development.
affaan-m/ECC
pytest、TDD手法、フィクスチャ、モック、パラメータ化、カバレッジ要件を使用したPythonテスト戦略. An agent skill from affaan-m/ECC.
affaan-m/ECC
pytest, TDD metodolojisi, fixture'lar, mocking, parametrizasyon ve coverage gereksinimleri kullanarak Python test stratejileri.
alirezarezvani/claude-skills
Test-driven development skill for writing unit tests, generating test fixtures and mocks, analyzing coverage gaps, and guiding red-green-refactor workflows across Jest, Pytest, JUnit, Vitest, and…
openJiuwen-ai/agent-core
Static safety audit of a SKILL.md that scores five dimensions and acts as a gate: skills below the pass line do not ship, whatever else they score.
openJiuwen-ai/agent-core
Runs a read-only assessment in one of two modes, a repository health check or a runtime extension gap review, and reports findings as a markdown table.
openJiuwen-ai/agent-core
Chinese-language rules for how an agent writes commit messages, PR descriptions, session journals, handoff issues and requests for help.
openJiuwen-ai/agent-core
Reference for idiomatic Python in the agent-core codebase: immutability, protocols, exception hierarchies, context managers and async patterns.
openJiuwen-ai/agent-core
A ten-category security checklist for the agent-core codebase, to run before any security-sensitive change or pull request: secrets, input validation, SQL, access control and prompt injection.
openJiuwen-ai/agent-core
Formalizes agent-core's make check/type-check/test/fix pipeline into a structured 6-phase verification skill.
Categories
Pytest patterns for the agent-core codebase: a red-green-refactor workflow, conftest fixtures, custom marks, monkeypatch and patch mocking, and async tests. Written for the openJiuwen agent-core repository, the guide has the agent write a failing test first, make the smallest change that passes and then refactor with the tests still green. It shows where fixtures belong, in a project-wide tests conftest file or a module-level one, and gives patterns for parametrized fixtures, factory fixtures and the sparing use of autouse for global resets.
Agent-Core Python Testing fits situations like: writing tests for agent-core code, starting with a failing test; organizing shared fixtures in conftest files; choosing between monkeypatch and patch when mocking; splitting fast unit tests from slow or integration tests with pytest marks.
Run `npx skills add openJiuwen-ai/agent-core --skill python-testing -a claude-code`. Or copy the skill folder (.claude/skills/python-testing in openJiuwen-ai/agent-core) into .claude/skills/python-testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add openJiuwen-ai/agent-core --skill python-testing -a codex`. Or copy the skill folder (.claude/skills/python-testing in openJiuwen-ai/agent-core) into .agents/skills/python-testing in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add openJiuwen-ai/agent-core --skill python-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/python-testing, .gemini/skills/python-testing, .github/skills/python-testing and .opencode/skills/python-testing in your project.
Going by SKILL.md and its folder, Agent-Core Python Testing needs the command-line tools its instructions call (pytest). Our summary lists: Python with pytest.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Agent-Core Python Testing is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.3k tokens (SKILL.md is roughly 9.1k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Agent-Core Python Testing: Python Testing (affaan-m/ECC, 275k stars), Python Testing (affaan-m/ECC, 275k stars), Python Testing Patterns (jh941213/my-cc-harness, 126 stars) and Python Testing (affaan-m/ECC, 275k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
openJiuwen-ai (a GitHub organization) maintains it in openJiuwen-ai/agent-core, which has 442 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 8, 2026.
Source: openJiuwen-ai/agent-core on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.