Skip to content

feat: add scripts/dev/test.sh — chunked FIFO local test wrapper (~1.75x faster)#1

Merged
LahkLeKey merged 1 commit into
mainfrom
feat/parallel-test-suite
May 27, 2026
Merged

feat: add scripts/dev/test.sh — chunked FIFO local test wrapper (~1.75x faster)#1
LahkLeKey merged 1 commit into
mainfrom
feat/parallel-test-suite

Conversation

@LahkLeKey
Copy link
Copy Markdown
Owner

Description

Adds a single-file local DX wrapper, scripts/dev/test.sh, that runs the existing pytest suite faster on developer machines without touching production code or CI.

What it does

  • Collects node ids once via pytest --collect-only -q, then dispatches them in fixed-size chunks (default 200) through pytest-xdist with -n auto --dist=load.
  • Persists a cursor at .pytest_cache/fast-test-cursor after every successful chunk, so a crash or Ctrl-C can be resumed exactly where it left off with --resume.
  • Supports --chunk-size N, --reset, --bench, and -- pass-through to pytest.

Why this shape

  • Bounded in-flight memory (one chunk's worth of tests held by xdist workers at a time).
  • Natural FIFO progression inside each chunk via --dist=load.
  • Crash recovery without any new Python module — pure bash around the existing uv run pytest entrypoint.
  • Zero impact on pyproject.toml, CI workflows, or import-time behavior. Pure additive file under scripts/dev/.

Measured impact (local, Windows + Git Bash, 16-core)

Run Wallclock
Baseline uv run pytest (serial) ~2m 37s
bash scripts/dev/test.sh --bench 1m 29.85s

~1.75x speedup end-to-end with no production source changes.

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

Additional validation:

  • Full suite executed via the new wrapper end-to-end: bash scripts/dev/test.sh --bench → 1m 29.85s wallclock.
  • Crash recovery verified by injecting a synthetic failing test, observing the cursor pinned at the failing chunk boundary, fixing the test, and confirming --resume continued from exactly that point with only the remaining tests executed.
  • --reset clears the cursor file; --chunk-size and -- pass-through both exercised.
  • 7 pre-existing Windows-only failures (MSYS path format + MAX_PATH) are unchanged by this PR — they reproduce identically with and without the wrapper.

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

GitHub Copilot (Claude) assisted with drafting scripts/dev/test.sh, iterating on the chunked-FIFO dispatch design, and producing the benchmark comparison. All design decisions, validation runs, and the final wrapper shape were reviewed and accepted by the author.

Copilot AI review requested due to automatic review settings May 27, 2026 05:03
@LahkLeKey LahkLeKey merged commit 155f22d into main May 27, 2026
12 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a Bash wrapper (scripts/dev/test.sh) that collects pytest node ids and dispatches them to pytest-xdist in fixed-size chunks with a resumable cursor at .pytest_cache/fast-test-cursor. Despite the PR description's claim of "Zero impact on pyproject.toml, CI workflows", the change also adds pytest-xdist as a required test extra and enables -n=auto --dist=worksteal in the project's default addopts, which affects every direct uv run pytest invocation — including the CI workflow and the contributor flow recommended in CONTRIBUTING.md / the PR template.

Changes:

  • New scripts/dev/test.sh wrapper implementing chunked FIFO dispatch over xdist with --resume, --reset, --bench, --chunk-size, and -- pass-through.
  • pyproject.toml: adds pytest-xdist>=3.5 to the test extra and -n=auto, --dist=worksteal to default addopts (affecting CI and all default local runs).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
scripts/dev/test.sh New chunked-FIFO pytest wrapper with cursor-based resume.
pyproject.toml Adds pytest-xdist test dep and enables parallel xdist by default in pytest addopts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pyproject.toml
Comment on lines 52 to +65
@@ -60,6 +61,8 @@ addopts = [
"-v",
"--strict-markers",
"--tb=short",
"-n=auto",
"--dist=worksteal",
Comment thread pyproject.toml
Comment on lines +64 to +65
"-n=auto",
"--dist=worksteal",
Comment thread scripts/dev/test.sh
Comment on lines +58 to +66
mapfile -t NODES < <(
uv run pytest -o addopts= --collect-only -q "${PASSTHROUGH[@]}" \
2>/dev/null | grep -E '::' || true
)
TOTAL="${#NODES[@]}"
if (( TOTAL == 0 )); then
echo "[fast-test] no tests collected" >&2
exit 1
fi
Comment thread scripts/dev/test.sh
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
CURSOR_FILE="$REPO_ROOT/.pytest_cache/fast-test-cursor"
Comment thread scripts/dev/test.sh
Comment on lines +37 to +71
--chunk-size) CHUNK_SIZE="$2"; shift 2 ;;
--resume) RESUME=1; shift ;;
--reset) RESET=1; shift ;;
--bench) BENCH=1; shift ;;
--) shift; PASSTHROUGH+=("$@"); break ;;
-h|--help) sed -n '2,22p' "$0"; exit 0 ;;
*) PASSTHROUGH+=("$1"); shift ;;
esac
done

if (( RESET )); then
rm -f "$CURSOR_FILE"
echo "[fast-test] cursor cleared"
exit 0
fi

cd "$REPO_ROOT"
mkdir -p "$(dirname "$CURSOR_FILE")"

# 1. Collect node ids (override addopts so collection itself is serial/quiet).
echo "[fast-test] collecting tests ..."
mapfile -t NODES < <(
uv run pytest -o addopts= --collect-only -q "${PASSTHROUGH[@]}" \
2>/dev/null | grep -E '::' || true
)
TOTAL="${#NODES[@]}"
if (( TOTAL == 0 )); then
echo "[fast-test] no tests collected" >&2
exit 1
fi

# 2. Determine starting cursor.
START=0
if (( RESUME )) && [[ -f "$CURSOR_FILE" ]]; then
START="$(cat "$CURSOR_FILE")"
Comment thread scripts/dev/test.sh
START=0
if (( RESUME )) && [[ -f "$CURSOR_FILE" ]]; then
START="$(cat "$CURSOR_FILE")"
echo "[fast-test] resuming from chunk cursor: test #$START"
Comment thread scripts/dev/test.sh
--reset) RESET=1; shift ;;
--bench) BENCH=1; shift ;;
--) shift; PASSTHROUGH+=("$@"); break ;;
-h|--help) sed -n '2,22p' "$0"; exit 0 ;;
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.

2 participants