Skip to content

feat(audit): add python-test-suite-audit skill - #2

Merged
azaharizaman merged 3 commits into
mainfrom
feat/python-test-suite-audit
Sep 30, 2026
Merged

azaharizaman merged 3 commits into
mainfrom
feat/python-test-suite-audit

Conversation

@azaharizaman

@azaharizaman azaharizaman commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Adds read-only python-test-suite-audit skill (installable via npx skills add nexusnv/python-agentic-skills --skill python-test-suite-audit).

  • 6 audit dimensions, Critical/Major/Minor severity with execution-confirmation gate
  • Quick static-only default; sampled mutation/order probes opt-in with budgets
  • Stdlib-only non-executing helpers: audit_assertions.py, plan_audit_scope.py
  • Severity scorecard template, eval fixtures (positive/near-miss/safety/evidence), baseline notes
  • Catalog, README, CI validators/discovery, quality-contract extensions, new tests/test_audit_scripts.py (32 tests)

Verification: pytest 457 passed, ruff check + format --check clean, agentskills validate passes, skills.sh discovery lists all 3 skills. Subagent review completed; load-bearing script-coverage gap fixed plus scanner FP refinements.

Summary by Sourcery

Add a read-only Python test-suite auditing skill with bounded static analysis, evidence-based severity scoring, and repository validation support.

New Features:

  • Add the read-only python-test-suite-audit skill for evaluating Python test-suite fault-detection strength across six audit dimensions.
  • Provide bounded, non-executing assertion scanning and deterministic audit-scope planning helpers.
  • Add audit scorecards, evidence-report guidance, evaluation fixtures, and safety controls for confirmation, redaction, and sensitive-data refusal.

Enhancements:

  • Extend repository quality contracts and skill-structure checks to cover the new audit workflow and its evidence requirements.
  • Document the new skill, installation command, and recommended use alongside the existing testing skills.

CI:

  • Validate the new skill with CI and include it in skills.sh discovery checks.

Documentation:

  • Update the README with the audit skill's purpose, installation instructions, and workflow guidance.

Tests:

  • Add comprehensive tests for the static audit helpers, including input validation, bounded output, deterministic sampling, pattern detection, and non-execution guarantees.
  • Extend quality-contract and skill-structure tests for the new skill, fixtures, safety scenarios, and report requirements.

…tic scanners

Read-only suite health audit: tautology, weak assertion, mock echo,
private coupling, error depth, isolation. Quick static-only default,
sampled deep probes opt-in. Bundles stdlib-only audit_assertions and
plan_audit_scope helpers, severity scorecard template, eval fixtures,
and audit script coverage. Updates catalog, docs, CI, and quality
contracts.
@sourcery-ai

sourcery-ai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Adds and fully integrates a read-only python-test-suite-audit skill: it combines six-dimensional, confirmation-gated suite analysis with safe bounded static helpers, mandatory severity/evidence reporting, evaluation fixtures, and repository-wide CI, discovery, documentation, and quality-contract coverage.

Flow diagram for the read-only Python test-suite audit

flowchart LR
    A[Existing Python test suite] --> B[Quick static audit]
    B --> C{Execution confirmation}
    C -->|No| D[Static findings]
    C -->|Yes| E[Bounded mutation or order probes]
    E --> F[Confirmed findings]
    D --> G[Critical Major Minor scorecard]
    F --> G
    G --> H[Evidence report]
Loading

Flow diagram for audit evidence and severity reporting

flowchart LR
    A[Audit six dimensions] --> B[Collect evidence]
    B --> C{Execution confirmed}
    C -->|No| D[Unconfirmed observation]
    C -->|Yes| E[Confirmed finding]
    D --> F[Assign Critical Major Minor]
    E --> F
    F --> G[Severity scorecard]
Loading

File-Level Changes

Change Details Files
Adds a read-only Python test-suite audit skill with explicit safety, execution, evidence, and severity rules.
  • Defines six audit dimensions and Critical/Major/Minor scoring with confirmation gates.
  • Makes quick static-only audits the default and gates sampled mutation/order probes behind explicit budgets.
  • Requires scorecards and reproducible evidence reports while documenting skipped, blocked, sampled, and not-run work.
  • Adds evaluation fixtures covering positive, near-miss, safety, redaction, and evidence scenarios.
.agents/skills/python-test-suite-audit/SKILL.md
.agents/skills/python-test-suite-audit/references/audit-dimensions.md
.agents/skills/python-test-suite-audit/references/heuristics-and-tools.md
.agents/skills/python-test-suite-audit/references/evidence-report.md
.agents/skills/python-test-suite-audit/evals/baseline.md
.agents/skills/python-test-suite-audit/evals/cases.yaml
Introduces bounded, standard-library-only static audit utilities that do not execute target code.
  • Scans supplied test source via AST for weak assertions, missing assertions, mock echoes, private coupling, broad exceptions, and isolation signals.
  • Plans deterministic sorted or seeded file scopes with strict input and budget validation.
  • Adds 32 tests covering detection behavior, malformed input, safety properties, import restrictions, non-execution, truncation, and deterministic sampling.
.agents/skills/python-test-suite-audit/scripts/audit_assertions.py
.agents/skills/python-test-suite-audit/scripts/plan_audit_scope.py
tests/test_audit_scripts.py
Integrates the new skill into repository documentation, discovery, CI, and quality contracts.
  • Registers the third skill in structure and validation checks, including skills.sh discovery.
  • Documents installation, scope, and selection guidance in the README.
  • Extends report-template, fixture-language, safety, helper-import, and expected-skill contracts.
  • Adds the skill to CI validation and discovery loops.
README.md
skills.sh.json
.github/workflows/ci.yml
tests/test_quality_contracts.py
tests/test_skill_structure.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".agents/skills/python-test-suite-audit/scripts/audit_assertions.py" line_range="69-71" />
<code_context>
+    return [
+        node
+        for node in ast.walk(tree)
+        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
+        and node.name.startswith("test")
+    ]
+
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The scanner traverses nested function bodies as if they belonged to the enclosing test. A nested `test_*` function that pytest will never collect is reported as a test, while an outer test whose unused nested helper contains the only `assert` is treated as assertion-bearing and its no-assertion finding is missed.

**Triggers:** When test modules contain nested helpers or nested functions named `test_*`.

**Suggested fix:** Limit test discovery to collected/top-level test functions and exclude nested function/class scopes when gathering assertions and calls for a test.
</issue_to_address>

### Comment 2
<location path=".agents/skills/python-test-suite-audit/scripts/audit_assertions.py" line_range="314-315" />
<code_context>
+            else:
+                truncated = True
+            continue
+        has_mock = _has_mock_import(tree)
+        for func in _test_functions(tree):
+            for item in _scan_function(func, path, has_mock):
+                counter += 1
</code_context>
<issue_to_address>
**nitpick (bug_risk):** `has_mock` is computed for the entire file and then passed to every test function, so importing a mock for one test enables mock-echo detection in unrelated tests. Any unrelated test in that file that uses a `return_value` or `side_effect` keyword and an assertion is reported as a mock echo even when the configured object is not a mock or the asserted value is transformed by the system under test.

**Triggers:** When one test in a file imports `unittest.mock` and another test uses `return_value` or `side_effect`.

**Suggested fix:** Track mock imports and mock configuration per function, or retain this as an explicitly file-level advisory with evidence tied to the actual mock object.
</issue_to_address>

### Comment 3
<location path=".agents/skills/python-test-suite-audit/scripts/audit_assertions.py" line_range="210-213" />
<code_context>
+            local_names.add(alias.asname or alias.name.split(".")[0])
+
+    for node in ast.walk(func):
+        if isinstance(node, ast.ExceptHandler):
+            if node.type is None or (
+                isinstance(node.type, ast.Name) and node.type.id == "Exception"
+            ):
+                findings.append(
+                    {
</code_context>
<issue_to_address>
**nitpick (bug_risk):** The broad-exception heuristic only recognizes a bare handler or a handler whose type is exactly the name `Exception`; it does not flag `except (Exception, ValueError):`, so a documented broad-except pattern is silently omitted from common tuple-form handlers.

**Triggers:** When a test uses a tuple-form exception handler containing `Exception`.

**Suggested fix:** Recognize `ast.Tuple` exception types recursively and flag handlers containing `Exception` or other configured broad base exceptions.
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: .agents/skills/python-test-suite-audit/scripts/audit_assertions.py:71


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread .agents/skills/python-test-suite-audit/scripts/audit_assertions.py Outdated
Comment thread .agents/skills/python-test-suite-audit/scripts/audit_assertions.py Outdated
Comment thread .agents/skills/python-test-suite-audit/scripts/audit_assertions.py Outdated
…e except

Addresses Sourcery review on PR #2:
- collect only top-level test functions and class methods; exclude
  nested scopes from assertion/call ownership
- tie mock-echo to a mock factory call in the same test, including
  mocker.patch; unrelated return_value kwargs no longer flag
- flag tuple-form broad handlers containing Exception/BaseException

Adds 8 regression tests and documents scanner scope in heuristics.
@azaharizaman

Copy link
Copy Markdown
Contributor Author

Addressed all 3 Sourcery comments in d847b69 (all fixed, none skipped or deferred):

  1. Nested test scope (blocking) — fixed. _test_functions now collects only top-level test_* functions and direct class methods; new _owned_nodes excludes nested def/class/lambda bodies from assertion/call ownership. Outer test with only a nested-helper assert now correctly gets no-assertion; nested test_* helpers are no longer reported.
  2. File-level mock flag (nitpick) — fixed per suggestion. Mock-echo now requires a return_value/side_effect keyword on a mock factory call (Mock, MagicMock, patch, mocker.patch, ...) in the same test. Unrelated return_value kwargs no longer flag; mocker.patch style now detected.
  3. Tuple-form except (nitpick) — fixed. Broad-except check recurses into tuple forms and covers BaseException; except (Exception, ValueError) now flags while except (ValueError, KeyError) does not.

Verification: 8 new regression tests (40 in test_audit_scripts.py, 465 full suite), ruff check/format --check clean, agentskills validate passes. Scanner scope documented in heuristics-and-tools.md.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

- exact len() equality no longer flagged as weak-length-assert
- pytest-only match= requirement; unittest assertRaises exempt
- unittest assert detection rejects assertion/failure lookalikes
- global-environ-access restricted to os.environ
- call-count set uses real mock attr called, drops called_once
- has_raises precedence made explicit and aligned
- heuristics doc updated for per-function mock-echo detection
@azaharizaman
azaharizaman merged commit dd8297e into main Sep 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant