create-pytests — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited create-pytests (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generates pytest test files for a Python codebase (or a targeted scope) that:
test_*.py files, test_ prefix functions and methods, Test prefix classes).@pytest.mark.integration.pyproject.toml with the [tool.pytest.ini_options] block using --import-mode=importlib.src/ vs flat) and configure accordingly.tests/ directory and no pyproject.toml pytest configuration.Do NOT use this skill for:
test-strategy skill instead.| Layout | Indicator | testpaths | Import mode |
|---|---|---|---|
src/ layout | src/ directory at root | ["tests"] | importlib |
| Flat layout | Package at root, no src/ | ["tests"] | importlib |
| Inline tests | No tests/ dir — tests live next to source | auto-discovery | importlib |
Always prefer tests outside application code (tests/ at root). Do not create an init file in tests/ — it is not needed under importlib mode and causes import confusion.
Test in this order when 80% coverage is the target:
_name) — test indirectly through their public callers; mark skipped in the gap report.if __name__ == "__main__":) — note as manual test candidates; apply # pragma: no cover.@pytest.mark.integration; exclude from the 80% threshold.setup.py test or any pytest-runner invocation — deprecated and removed.mock.patch a real, in-process implementation — use the real class.tests/.Read the user's request:
For a large codebase, list the files to be created and ask for confirmation before generating.
Check for the presence of:
src/ directory at the project root → src/ layout.tests/ directory → confirm placement; use it.pyproject.toml → read [tool.pytest.ini_options] before updating.pyproject.tomlIf pyproject.toml does not exist, create it. If it exists but has no [tool.pytest.ini_options] section, add only that section. Never overwrite an existing [project] block.
Required minimum:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "PACKAGENAME"
version = "PACKAGEVERSION"
[tool.pytest.ini_options]
addopts = ["--import-mode=importlib"]
testpaths = ["tests"]
markers = [
"integration: tests that require live external services (deselect with '-m not integration')",
]Replace PACKAGENAME with the detected package name and PACKAGEVERSION with "0.1.0" if none exists.
For each module in scope:
tests/test_<module>.py file.@pytest.mark.integration._name), do NOT write direct tests — test them indirectly through their callers.@pytest.mark.parametrize when multiple inputs test the same logic.pytest.raises(ExceptionType, match="pattern") for all exception cases — never omit match=.Enforce these naming rules:
test_<module>.py (preferred) or <module>_test.pytest_<what_it_tests>TestClassName (PascalCase, Test prefix, no init method)tests/After the test files, always output a ## Coverage Gap Report section:
## Coverage Gap Report
### Covered
| Module | Items tested | Test file |
| --- | --- | --- |
| `src/mypkg/app.py` | `create_app`, all routes, 404 handler | `tests/test_app.py` |
| `src/mypkg/models.py` | `Item` init, `to_dict`, `from_dict` (valid + invalid), `save` | `tests/test_models.py` |
### Skipped
| Module | Item | Reason |
| --- | --- | --- |
| `src/mypkg/app.py` | `_configure_logging()` | Private helper — exercised indirectly via every `create_app()` call |
| `src/mypkg/app.py` | `if __name__ == "__main__":` | CLI entrypoint — `# pragma: no cover` applied |
### Estimated coverage
| Module | Estimated line coverage | At 80% target? |
| --- | --- | --- |
| `app.py` | ~87% | Yes |
| `models.py` | ~93% | Yes |For each run the skill produces:
[tool.pytest.ini_options].When generating for a whole codebase, list all files to be created before generating them.
Input: "Write pytest tests for my Flask API project."
Steps the skill takes:
src/flaskapi/ layout.pyproject.toml with hatchling backend and --import-mode=importlib.tests/test_app.py covering all public routes (happy path, 404, validation errors).tests/test_models.py covering all Item methods including save.@pytest.mark.integration._configure_logging skipped as a private helper.Input: "Write tests for the parse_date function in utils.py."
Steps the skill takes:
tests/test_utils.py covering: valid ISO date string, invalid format raises ValueError, empty string raises ValueError, timezone-aware input, leap year boundary.utils.py are out of scope.pyproject.toml, missing pytest configInput: "Add pytest config — I already have a pyproject.toml."
Steps the skill takes:
pyproject.toml.[tool.pytest.ini_options] block with addopts = ["--import-mode=importlib"].[project], [build-system], or any other existing section.--import-mode=importlib. It avoids sys.path manipulation and will become the default in a future pytest major version. See references/test-layout.md.tests/. Under importlib mode it is not needed, and adding one causes import confusion.@pytest.mark.integration tests go in the same test files as unit tests but are excluded from the default run with -m "not integration". Declare the marker in [tool.pytest.ini_options].test-strategy (define what to test before generating) and code-review (review generated tests for correctness and quality).references/project-setup.md, references/test-layout.md, references/pytest-config.md, references/discovery-conventions.md, references/coverage-and-quality.md.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.