Skip to content
Back to skills

Testforge

ASecurity

Generates runnable pytest test suites from Python source and reports coverage gaps with concrete fill-in suggestions. Use when the user asks to 生成测试, 写单测, testforge, 补测试, generate tests, 增加覆盖率, or 给这个函数写测试; best for AI-generated code that ships without tests or with low coverage.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
ai-agentspython

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 4 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add whaojie797-design/Novera-AI-skills --skill testforge --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Testforge?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Testforge
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/whaojie797-design-testforge/badge)](https://www.skillsdirectory.com/skills/whaojie797-design-testforge)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: testforge
description: Generates runnable pytest test suites from Python source and reports coverage gaps with concrete fill-in suggestions. Use when the user asks to 生成测试, 写单测, testforge, 补测试, generate tests, 增加覆盖率, or 给这个函数写测试; best for AI-generated code that ships without tests or with low coverage.
---

# testforge

A skill for the Novera-AI-skills suite that turns untested Python source into a
runnable pytest suite and then tells you exactly where the coverage is thin.

The problem it solves: AI-generated code often ships with no tests or with
tests that only assert `is not None`. `testforge` scaffolds the structure so
the agent spends its effort on *meaningful* assertions instead of boilerplate.

Both scripts are pure standard library - no `pip install` needed to run them.

---

## When to use

Trigger this skill when the user says any of:

- 生成测试 / 写单测 / 补测试 / 给这个函数写测试 / 增加覆盖率
- testforge / generate tests / add coverage

Also use it proactively after producing a Python module that has no tests.

---

## Workflow

Follow these steps in order. Each step names the script and its job.

### 1. Generate stubs

Run `gen_pytest.py` against the source file:

```
python scripts/gen_pytest.py <source.py>
```

It parses the file with the `ast` module and writes `test_<source>_gen.py`
next to it, with one skeleton test per top-level function and per class method.
Each stub imports the callable, calls it with `None` placeholders, and leaves a
single `# TODO` placeholder assertion. The script prints the number of stubs
and the output path.

What it covers:

- Top-level functions -> `def test_<name>()`.
- Class methods -> `def test_<Class>_<method>()` (instance, `@staticmethod`,
  and `@classmethod` are each handled; `__init__` is skipped).

### 2. Fill the assertions

Open the generated file and replace every `# TODO` with a real check. Use
`references/test-patterns.md` for copy-paste templates:

- Normal path: assert the return value for valid input.
- Boundary: empty / zero / None / negative / very large.
- Exception: `with pytest.raises(<ExpectedError>):` for bad input.
- Isolation: patch slow or external calls with `unittest.mock`.
- Prefer `@pytest.mark.parametrize` over copy-pasted tests.

A filled stub looks like this:

```python
def test_divide():
    assert divide(10, 2) == 5


def test_divide_by_zero():
    import pytest
    with pytest.raises(ValueError):
        divide(10, 0)
```

### 3. Run pytest

```
python -m pytest test_<source>_gen.py
```

`gen_pytest.py` does not require pytest, but running the suite does. Install it
with `pip install pytest` if missing.

### 4. Find the gaps

Point `coverage_hint.py` at the test directory:

```
python scripts/coverage_hint.py <test_dir>
```

It counts test files and test functions, flags any test that is still a stub or
asserts nothing, and prints concrete next steps (fill placeholders, add
exception tests, add boundary cases, use parametrize). If `pytest` is on the
PATH it also prints the exact command to run the suite.

Loop steps 2-4 until `coverage_hint` reports `0 stub(s)` and the suite is green.

---

## Scripts

### scripts/gen_pytest.py

- Input: a single `.py` source file.
- Output: `test_<source>_gen.py` in the same directory.
- Pure stdlib (`ast`). Deterministic. Errors are reported on stderr with a
  non-zero exit code (2 for bad args / missing file, 1 for parse failure).

```
python scripts/gen_pytest.py path/to/module.py
# -> generated 5 test stub(s) -> path/to/test_module_gen.py
```

### scripts/coverage_hint.py

- Input: a directory containing test files (`test_*.py` or `*_test.py`).
- Output: a scan summary plus suggestions. Does not need pytest installed.
- Pure stdlib. Detects the `pytest` executable and prints the run command when
  present.

```
python scripts/coverage_hint.py path/to/tests
```

---

## Reference material

- `references/test-patterns.md` - normal-path / boundary / exception / mock
  patterns with templates to paste into the generated stubs.

---

## Limitations

- `gen_pytest.py` generates structure, not intelligence. Placeholder arguments
  are `None`; the agent must supply real inputs or the call may raise at
  runtime. That failure is the signal to fill the stub.
- It does not compute line coverage percentages (that needs `pytest-cov`). It
  reports structural gaps: missing assertions, unfilled stubs, and missing
  exception/boundary/parametrize coverage.
- Nested functions and module-level lambdas are not scaffolded; only
  top-level functions and class methods are.

Files in this skill

  • SKILL.md4.5 KB
  • references/test-patterns.md3.7 KB
  • scripts/coverage_hint.py5.1 KB
  • scripts/gen_pytest.py5.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.