RepoPilotOpen in app →

BurntSushi/quickcheck

Automated property based testing for Rust (with shrinking).

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 5w ago
  • 28+ active contributors
  • Unlicense licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 51% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/burntsushi/quickcheck)](https://repopilot.app/r/burntsushi/quickcheck)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/burntsushi/quickcheck on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: BurntSushi/quickcheck

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/BurntSushi/quickcheck shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 5w ago
  • 28+ active contributors
  • Unlicense licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 51% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live BurntSushi/quickcheck repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/BurntSushi/quickcheck.

What it runs against: a local clone of BurntSushi/quickcheck — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in BurntSushi/quickcheck | Confirms the artifact applies here, not a fork | | 2 | License is still Unlicense | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 65 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>BurntSushi/quickcheck</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of BurntSushi/quickcheck. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/BurntSushi/quickcheck.git
#   cd quickcheck
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of BurntSushi/quickcheck and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "BurntSushi/quickcheck(\\.git)?\\b" \\
  && ok "origin remote is BurntSushi/quickcheck" \\
  || miss "origin remote is not BurntSushi/quickcheck (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Unlicense)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Unlicense\"" package.json 2>/dev/null) \\
  && ok "license is Unlicense" \\
  || miss "license drift — was Unlicense at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 65 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~35d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/BurntSushi/quickcheck"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

QuickCheck is a property-based testing framework for Rust that automatically generates random test inputs and shrinks failing cases to minimal counter-examples. It provides the Arbitrary trait (in src/arbitrary.rs) for generating random values across types like integers, floats, strings, tuples, and collections, plus a shrinking engine that uses binary search to quickly narrow down bug-triggering inputs. The core testing logic lives in src/tester.rs and is exposed via the quickcheck! macro and the newer #[quickcheck] attribute from the quickcheck_macros crate. Monorepo with two workspace members: src/ contains the core library (src/lib.rs, src/arbitrary.rs for type generation, src/tester.rs for test execution), and quickcheck_macros/ contains the procedural macro implementations. Examples in examples/ demonstrate usage patterns (reverse.rs, sort.rs, sieve.rs). Tests reside in src/tests.rs and quickcheck_macros/tests/macro.rs.

👥Who it's for

Rust developers writing unit and integration tests who want to find edge cases without manually writing specific test cases. Property-based testers, fuzzing enthusiasts, and library authors maintaining correctness-critical code (like data structure implementations shown in examples/ like btree_set_range.rs and sort.rs).

🌱Maturity & risk

Production-ready and actively maintained. Version 1.1.0 with Rust 1.85.0 MSRV, dual-licensed (Unlicense/MIT), CI configured via .github/workflows/ci.yml, and a workspace structure with two stable crates (quickcheck + quickcheck_macros). The codebase is relatively compact (~78KB Rust) with no major breaking changes apparent, suggesting stable API design.

Very low risk. Minimal dependencies (only rand 0.10 for RNG, optional log/env_logger, no transitive bloat), single maintainer (Andrew Gallant / BurntSushi) but with no signs of abandonment (version 1.1.0 is recent). No visible high-churn or breaking-change patterns. Main risk is RNG-dependent behavior: tests can be non-deterministic unless QUICKCHECK_SEED env var is set, which isn't prominently documented in the README.

Active areas of work

The repository appears stable without active development signals from the file list alone. Version 1.1.0 is the latest release with Rust 1.85.0 support. The CI workflow (.github/workflows/ci.yml) likely runs on each commit. No explicit PRs or milestones are visible in the provided data, so check GitHub Issues and the last commit date to assess current work.

🚀Get running

git clone https://github.com/BurntSushi/quickcheck.git
cd quickcheck
cargo test

Optionally run examples: cargo run --example reverse or cargo build --all to include the quickcheck_macros subcrate.

Daily commands: Run tests: cargo test (runs src/tests.rs and quickcheck_macros/tests/macro.rs). Run examples: cargo run --example reverse or cargo run --example sort. Enable logging: RUST_LOG=quickcheck cargo test to see test iteration count and shrinking steps. Build docs: cargo doc --open.

🗺️Map of the codebase

  • src/lib.rs: Public API surface: defines TestResult, QuickCheck struct, and re-exports Arbitrary trait and quickcheck! macro
  • src/arbitrary.rs: Core generation logic: contains Arbitrary trait definition and implementations for all built-in types (int, float, Vec, String, Option, Result, tuples)
  • src/tester.rs: Test execution engine: implements property test runner, shrinking algorithm via binary search, and test case filtering/statistics
  • quickcheck_macros/src/lib.rs: Procedural macro implementation: converts #[quickcheck] attribute functions into #[test] functions and generates test harness code
  • src/tests.rs: Integration tests: demonstrates working property tests (e.g., reversing lists, sorting) and validates framework behavior
  • Cargo.toml: Workspace configuration: declares quickcheck_macros as member, specifies optional features (use_logging, regex), sets MSRV
  • examples/reverse.rs: Canonical usage example: shows quickcheck! macro pattern for testing a list reversal property

🛠️How to make changes

Adding a new Arbitrary impl: Edit src/arbitrary.rs (lines with impl Arbitrary for YourType). Fixing shrinking logic: Check src/tester.rs for the shrink() method and the Shrinker enum. Updating macros: Modify quickcheck_macros/src/lib.rs (procedural macro entry point). Adding examples: Create new .rs files in examples/ and add a [[example]] block to Cargo.toml if needed. Tests: Add property functions to src/tests.rs or create files in tests/ directory.

🪤Traps & gotchas

Non-determinism by default: Tests use sys_rng (system RNG), making failures potentially unreproducible. Set QUICKCHECK_SEED=<seed> to replay failing tests, but this isn't emphasized in README. Logging not enabled by default: The use_logging feature is enabled by default but only activates via RUST_LOG=quickcheck env var—users may not realize INFO output is available. Macro hygiene: The quickcheck! block macro captures property names as function names; unusual naming can cause compile errors. No custom Arbitrary without derive or manual impl: The framework doesn't auto-derive Arbitrary for structs; users must implement or use quickcheck_macros derive helpers. Shrinking can be slow: Binary search shrinking on large vecs/strings can add significant test time; no timeout or iteration limit per test visible in public API.

💡Concepts to learn

  • Property-Based Testing — The core discipline behind quickcheck: instead of writing specific test cases, you declare invariants (properties) that should hold for any input, and the framework generates and shrinks counterexamples
  • Shrinking (in property testing) — Quickcheck's signature feature: when a property fails on a large random input, it automatically finds a minimal counterexample by iteratively removing or reducing parts of the input
  • Arbitrary Trait & Random Generation — The core abstraction in src/arbitrary.rs that defines how any Rust type can be randomly generated; users extend this trait to enable quickcheck testing for custom types
  • Binary Search for Shrinking — Quickcheck uses logarithmic-time binary search to narrow down failing inputs on integers and collections, avoiding linear O(n) shrinking that would be prohibitively slow on large test cases
  • Procedural Macros (syn/quote pattern) — The quickcheck_macros crate uses procedural macros to convert plain Rust functions into test harness code; understanding macro expansion is key to debugging macro-based properties
  • TestResult Combinator Pattern — Quickcheck properties can return bool, (), Result, or TestResult; the TestResult type allows discard() for conditional test skipping and reject() for filtering, enabling more sophisticated property definitions
  • Fuzzing (Unguided vs. Guided) — Quickcheck is unguided (purely random) fuzzing with shrinking; differs from guided fuzzers like libFuzzer that use coverage feedback, making it simpler but potentially less efficient for deep bug discovery
  • BurntSushi/regex — Same author (Andrew Gallant); the regex crate's test suite likely uses quickcheck extensively for property testing
  • proptest-rs/proptest — Alternative property-based testing framework for Rust with similar Arbitrary generation and shrinking, but different API and philosophy
  • assert-rs/assert_cmd — Complementary testing tool for testing CLI applications; often paired with quickcheck for property-based CLI argument fuzzing
  • Koe1/clippy — Heavy user of quickcheck for property-based testing of lint logic and AST transformations in the Rust compiler
  • hackage/quickcheck — Original QuickCheck library for Haskell; this Rust port directly implements Koen Claessen's shrinking strategies and design philosophy

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive shrinking strategy tests in src/tests.rs

The repo claims sophisticated shrinking strategies using binary search for lists and numbers (mentioned in README), but src/tests.rs likely lacks dedicated unit tests validating that shrinking actually produces minimal counter-examples. This is critical for a property-based testing library where shrinking is a core feature. Tests should verify that shrunk values are indeed smaller and that the shrinking terminates correctly.

  • [ ] Review src/tests.rs to identify gaps in shrinking validation tests
  • [ ] Add tests that verify shrinking produces minimal counter-examples for Vec<i32>, String, and Option types
  • [ ] Add regression tests for edge cases (empty collections, single elements, already-minimal values)
  • [ ] Verify that shrinking terminates and doesn't produce invalid or larger values
  • [ ] Document the expected shrinking behavior in src/arbitrary.rs where Shrink traits are implemented

Add MSRV (Minimum Supported Rust Version) validation in CI

The Cargo.toml specifies rust-version = '1.85.0' as the MSRV, but .github/workflows/ci.yml likely doesn't test against this version. This creates risk that contributions break MSRV compatibility silently. Add a dedicated CI job using cargo-msrv or manual toolchain pinning to catch regressions early.

  • [ ] Review .github/workflows/ci.yml to confirm MSRV testing is absent
  • [ ] Add a new CI job that explicitly tests against Rust 1.85.0 using 'rust-toolchain.toml' or 'actions-rs/toolchain@v1'
  • [ ] Include both quickcheck and quickcheck_macros in the MSRV test matrix
  • [ ] Ensure the job runs 'cargo test --all --all-features' against the pinned MSRV
  • [ ] Document the MSRV policy in README.md if not already present

Add integration tests for quickcheck_macros attribute macro in quickcheck_macros/tests/

quickcheck_macros/tests/macro.rs exists but is likely minimal. The macros are a key user-facing API, and the test coverage should comprehensively validate: macro expansion correctness, integration with the main quickcheck crate, custom Arbitrary implementations, and error handling for malformed macro invocations. This ensures the ergonomic macro interface is robust.

  • [ ] Review quickcheck_macros/tests/macro.rs and quickcheck_macros/src/lib.rs to map macro capabilities
  • [ ] Add integration tests validating #[quickcheck] macro expands correctly with various function signatures (different argument counts, generic types, custom Arbitrary impls)
  • [ ] Add tests for edge cases: zero-argument properties, Result return types, timeout configurations
  • [ ] Add negative tests for compilation errors (e.g., malformed attributes, incompatible function signatures)
  • [ ] Ensure tests compile against the main quickcheck crate and validate end-to-end property execution

🌿Good first issues

  • Add Arbitrary impl + shrinking for common std types like std::collections::HashMap and std::collections::HashSet (currently only BTreeMap and BTreeSet have examples). Check src/arbitrary.rs for the pattern and add Hash-based variants.: Improves coverage of Rust std library; straightforward Arbitrary trait implementation with clear shrinking logic from existing map/set impls.
  • Enhance README with a dedicated section on reproducibility and debugging: document QUICKCHECK_SEED, RUST_LOG=quickcheck, and show a failing test → shrunk output → fix workflow. Currently this is buried or missing.: First-time users struggle to understand non-determinism and logging; clear docs reduce friction and support questions.
  • Add a comprehensive benchmark suite in benches/ comparing shrinking speed on vecs/strings of varying sizes. Currently no perf tests exist.: Establishes baseline for performance regressions; helps validate shrinking algorithm efficiency; useful for future optimization PRs.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • eb00091 — Fix the gen deprecation note from set_rng to rng (#348) (cuviper)
  • 692527d — quickcheck_macros-1.2.0 (BurntSushi)
  • 93bb1ea — 1.1.0 (BurntSushi)
  • c69a43c — api: add Gen::from_size_and_seed (jakoschiko)
  • 44127d7 — api: add a wrapper for disabling shrinking for an Arbitrary (neithernut)
  • b151ea6 — impl: move shrinking logic out of inline function (neithernut)
  • d61d01c — impl: do recursive shrinking without recursive fn call (neithernut)
  • 23c68ea — impl: make sure a float's shrinker does not yield the original value (neithernut)
  • 89eaaf3 — impl: simplify control flow in SignedShrinker (neithernut)
  • 598decd — impl: make SignedShrinker bounded for <$ty>::MIN (neithernut)

🔒Security observations

The quickcheck crate demonstrates strong security practices overall. No critical or high-severity vulnerabilities were identified. The codebase has no hardcoded secrets, no apparent injection risks (it's a testing library, not a web framework), and no infrastructure exposure. Dependencies are minimal and well-vetted (rand, log, env_logger are established crates). The main observations are around feature configuration defaults and the relatively recent MSRV, both of which are minor concerns. The licensing model (dual Unlicense/MIT) is transparent and appropriate for an open-source utility library.

  • Low · Permissive Default Features — Cargo.toml - [features] section. The crate enables 'regex' and 'use_logging' features by default. The 'regex' feature pulls in the regex crate as a transitive dependency through env_logger, and 'use_logging' enables logging infrastructure by default. While not directly a vulnerability, enabling features by default increases the attack surface and dependency chain. Fix: Consider making verbose features opt-in rather than default. Users who don't need regex support or logging would benefit from lighter default dependencies. Document the features clearly for users.
  • Low · Older Rust Version Requirement — Cargo.toml - rust-version field. The minimum Rust version is set to 1.85.0, which is relatively recent but still allows older compiler versions. While 1.85.0 is not particularly old, the crate should ensure all dependencies are compatible and regularly audit for compiler-related security fixes. Fix: Regularly review and update the MSRV (Minimum Supported Rust Version) based on security advisories and new compiler features. Document any security-relevant reasons for version requirements.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · BurntSushi/quickcheck — RepoPilot