Skip to main content

TestSeal

TestSeal

CI PyPI Codecov Python 3.11+ License

Website | Documentation | Rule reference | Architecture | Contributing

Deterministic test-integrity checks for Python and pytest diffs.

TestSeal compares tests before and after a change and reports concrete weakening signals: removed assertions, newly disabled tests, weaker comparisons, wider tolerances, swallowed exceptions, snapshot regeneration, and suspicious mocks. It runs locally, needs no model or API key, and never imports or executes the repository it scans.

- assert total == Decimal("19.99")
+ assert total

After installing TestSeal, run the built-in example from any directory. It does not read Git, configuration, or the network:

testseal demo
[HIGH] TS003 tests/test_totals.py:10:1 - Assertion weakened
  A specific equality assertion was replaced by a truthy/non-null check
  Evidence: assert total == Decimal("19.99")  ->  assert total
  Fingerprint: 3c056c0da89673cd1a42eacc
  Fix: Assert the specific expected value, type, relationship, or exception.

TestSeal: 1 finding(s) in 1 changed file(s) (high 1, medium 0, low 0).

Why TestSeal

A green test suite is weak evidence when the same change made the suite easier to pass. Ordinary linters accept both sides of the example because both are valid Python. General code reviewers may notice the downgrade, but their output is probabilistic. TestSeal provides a narrow, reproducible signal dedicated to how the tests themselves changed.

  • Identical input and configuration produce identical output.
  • The Python package has no runtime dependencies, model calls, telemetry, or accounts.
  • Git-backed scans compare complete before/after syntax when both blobs are available.
  • Scans read source and Git data without importing the target project.
  • Findings are advisory unless a failure threshold is configured.
  • Reports are available as text, versioned JSON, and SARIF 2.1.0; integrations are provided for pre-commit and GitHub Actions.

Quick start

TestSeal requires Python 3.11 or newer and Git for repository-backed scans:

python -m pip install testseal
testseal demo

For an isolated CLI installation:

uv tool install testseal
# or: pipx install testseal

Then run it in a Git repository:

testseal scan

The default scan is advisory. Add --fail-on high when high-severity findings should return exit code 1.

Scan modes

Goal Command
Check working-tree and untracked changes testseal scan
Check staged changes testseal scan --staged
Compare a branch with its base testseal scan --base origin/main --head HEAD
Read a unified diff testseal scan --diff changes.patch
Block on high-severity findings testseal scan --fail-on high

Exit codes are 0 for a completed advisory scan, 1 when the selected finding threshold is met, and 2 for invalid configuration or an incomplete blocking scan.

Output

Text is the default. JSON and SARIF can be printed or written atomically:

testseal scan --base origin/main --format json --output testseal-report.json
testseal scan --base origin/main --format sarif --output testseal-report.sarif

Run testseal scan --help to list the available CLI options.

Configure policy

TestSeal discovers testseal.toml first, then [tool.testseal] in pyproject.toml. An explicit --config PATH takes precedence.

[testseal]
fail_on = "high"
test_patterns = ["test_*.py", "*_test.py", "tests/**/*.py"]
source_roots = ["src"]
disabled_rules = ["TS008"]

# Copy a fingerprint from text, JSON, SARIF, or the Action output after review.
ignore_fingerprints = ["3c056c0da89673cd1a42eacc"]

[testseal.rules.TS006]
severity = "low"

Configuration is strict: unknown keys, rule IDs, severities, and malformed fingerprints fail with exit code 2 instead of silently weakening policy. See the repository's default, strict, and monorepo examples.

Pre-commit

The hook installs TestSeal in its own environment and scans the staged diff:

repos:
  - repo: https://github.com/satwiksps/testseal
    rev: v1.0.0
    hooks:
      - id: testseal
        args: ["--fail-on", "high"] # omit to remain advisory

GitHub Actions

The Action installs the Python core bundled in the same release, derives pull request refs from the event payload, annotates changed lines, and exposes a normalized JSON result.

name: Test integrity

on: [pull_request]

permissions:
  contents: read

jobs:
  testseal:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          fetch-depth: 0
      - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
        with:
          python-version: "3.12"
      - id: testseal
        uses: satwiksps/testseal@e6bba7e933c37afc34e2836ac2b1baee7542bfe5 # v1.0.0
        with:
          fail-on: high

Omit fail-on to honor repository configuration. The default install: true uses only the source bundled with that Action commit. Set install: false only when the same TestSeal version is already installed in the selected Python environment.

For accepted CLI reports, Action outputs include finding-count, severity counts, files-scanned, suppressed-count, outcome, and the normalized result JSON. Input, installation, process, and rejected-report failures set only outcome.

Rules

Rule Signal Severity Confidence
TS001 An assertion was removed from a test High High
TS002 A pytest or unittest skip/xfail was added High High
TS003 An assertion was replaced with a weaker form High High
TS004 A comparison tolerance was widened High High
TS005 A broad exception is now swallowed High High
TS006 Snapshot update or regeneration behavior was added Low Low
TS007 The apparent subject under test is now mocked Medium Medium
TS008 Source and a configured guarding test changed together Low Low

The table is a summary. The rule reference defines supported syntax, intentional non-findings, and precision limits. Context-heavy rules should be baselined before enabling a blocking threshold.

Trust boundary and limitations

TestSeal invokes Git to obtain refs, diffs, and blobs, then parses Python source with the running interpreter. It does not run tests, import changed modules, or execute hooks from the target repository. Use pull_request, read-only permissions, and no repository secrets when scanning contributions from forks.

The analyzer reports specific transformations; it does not decide whether an author is honest, prove that tests are complete, or replace code review, coverage, linters, type checkers, and security analysis. A finding can describe a legitimate refactor, so blocking is explicit and reviewed exceptions use stable fingerprints rather than hidden heuristics.

The analyzer currently targets Python test files. It understands common pytest, unittest, and unittest.mock patterns. The TypeScript code in this repository implements the GitHub Action and website; it does not analyze JavaScript or TypeScript test suites.

Read the full architecture and trust model and security policy.

Development

git clone https://github.com/satwiksps/testseal.git
cd testseal
python -m venv .venv
# POSIX: source .venv/bin/activate
# Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m pytest

The TypeScript Action lives in packages/action and the Next.js/Tailwind site in site. See CONTRIBUTING.md for the complete verification commands and rule-change requirements.

Support

Use GitHub Issues for reproducible bugs and rule false positives. Report vulnerabilities through GitHub private vulnerability reporting.

License

TestSeal is licensed under the Apache License 2.0.

Release files for testseal 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for testseal 1.0.0
File Size Uploaded
testseal-1.0.0.tar.gz 46.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for testseal 1.0.0
File Interpreter ABI Platform
testseal-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 84.6 kB

Release files / testseal-1.0.0.tar.gz

Download URL testseal-1.0.0.tar.gz
Size 46.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9369d9d046b14df8cacdaa32b42065327f25f06b967bb6bb4da243fa03c875be
BLAKE2b-256 checksum
How to use checksums
3807874422cbc30a451bd95ed417bc2b046c18bad786ecdfc7eba02d10d032ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release files / testseal-1.0.0-py3-none-any.whl

Download URL testseal-1.0.0-py3-none-any.whl
Size 38.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a038fbe3a017adeac31cd793aecc9534c5c9139ed3d9b78af0499ce2772541ce
BLAKE2b-256 checksum
How to use checksums
1bc2cd93097f692c8bee5cc397dbd530d1703600fc3d4426088c4c888329496a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.1

2 release files

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page