Skip to content

test: add E2E integration tests for the core user journey - #65

Merged
higagan merged 2 commits into
mainfrom
test/e2e-user-journey
Aug 4, 2026
Merged

test: add E2E integration tests for the core user journey#65
higagan merged 2 commits into
mainfrom
test/e2e-user-journey

Conversation

@higagan

@higagan higagan commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Two paths matter to a user: wrapping a tool with @shield_tool and running modelfuzz scan. These tests exercise both end-to-end so development never silently breaks either.

Test 1 — The Shield Journey

  • A safe call executes and returns the correct value
  • A malicious call (containing "secret") raises ModelFuzzBlockError
  • The function body never runs when a violation is caught

Test 2 — The Scanner Journey

  • Invokes the CLI via typer.testing.CliRunner against a stubbed OpenAI client (no network calls, no API keys)
  • The stub returns a response containing a tool_call
  • Asserts the CLI exits 0 and the output contains VULNERABLE
  • Asserts the stub client was actually used (probe_count > 0)

Picked up by the existing pytest configuration — runs in CI alongside the unit tests. 110 tests pass, ruff + mypy --strict clean.

higagan added 2 commits August 4, 2026 21:30
The package has full type hints but shipped no PEP 561 marker, so
consumers (and AI coding assistants reading type info) saw Any
everywhere. decorator.py invests in ParamSpec, TypeVar, and two
@overload declarations to preserve tool signatures — all of it was
discarded without the marker.

Add src/modelfuzz/py.typed to the wheel and sdist, add the
Typing :: Typed classifier, and add mypy --strict src/modelfuzz as
a CI step so type regressions fail the workflow.

Fix the 10 existing mypy --strict errors:
- decorator.py: annotate shield_tool, _enforce, _wrap; fix list
  variance on the default engine; annotate async wrappers
- cli.py: annotate _make_client, _probe, _next_attack; tighten
  HTTP_POST_TOOL to list[dict[str, object]]

Closes #56.
Two paths matter to a user: wrapping a tool with @shield_tool and
running modelfuzz scan. These tests exercise both end-to-end so
development never silently breaks either.

Shield journey:
- A safe call executes and returns the correct value
- A malicious call (containing 'secret') raises ModelFuzzBlockError
- The function body never runs when a violation is caught

Scanner journey:
- Invokes the CLI via typer.testing.CliRunner against a stubbed
  OpenAI client (no network calls, no API keys)
- Asserts the CLI exits 0 and the output contains VULNERABLE
- Asserts the stub client was actually used (probe_count > 0)

Picked up by the existing pytest config and runs in CI alongside
the unit tests.
@higagan
higagan merged commit 87c434b into main Aug 4, 2026
5 checks passed
@higagan
higagan deleted the test/e2e-user-journey branch August 4, 2026 16:06
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