Run from the repository root on a fresh Release build. Commands use the default
single-configuration build/bin/ layout; MSVC uses build/bin/Release/*.exe and
requires ctest -C Release. Test counts depend on enabled targets and changes;
list them with ctest --test-dir build -N rather than relying on a copied count.
ctest --test-dir build --output-on-failurePerft checks known legal trees. State tests rebuild incremental fields and verify undo. NNUE tests compare integer scalar/SIMD and incremental/full paths. Variant tests add reserves, promoted markers and drops. Visualization tests capture inference, replay session moves, and exercise dataset shards and wire fixtures. These are separate properties; none alone proves complete rule adjudication.
On Windows, if CTest finds the system WSL launcher instead of Git Bash, set the intended shell at configure time:
cmake -S . -B build-ucrt -DBASH_EXECUTABLE="C:/Program Files/Git/bin/bash.exe"A failed or Not Run test is not a successful suite. Fix the environment or state which check remains unverified; do not exclude it just to report a green run.
Syzygy adapter regressions run without table files. For actual WDL/DTZ probing,
configure with -DSTK_SYZYGY_TEST_PATH=/absolute/path/three-piece-tables to
register the external-file integration test. See the
Syzygy verification instructions.
./build/bin/ChessEngine --perft
./build/bin/ChessEngine --perft test_data/standard.epd
./build/bin/ChessEngine --perft-one "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" 3 8902
./build/bin/ChessEngine --perft-divide "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" 3The EPD suite exits nonzero on mismatch/failure. Divide prints UCI root moves and
counts followed by Total: 8902 for this example. Depth zero is Total: 1;
invalid FEN/depth returns 2. --perft-divide belongs to the development checkout,
not the original v1.0.0 CLI. Old --nnue-consistency instructions are obsolete;
use CTest's consistency checks.
bash tools/bench_signature.sh build/bin/ChessEngine
bash tools/bench_signature.sh build/bin/ChessEngine-nnue nnueExpected depth/counts come from tools/bench_signature.txt. Both checks use one
thread and an 8 MB hash. For an intentional change only, regenerate with both
binaries using tools/update_bench_signature.sh; never edit counts by hand.
A fingerprint is search identity, not throughput or Elo. See
benchmark methodology.
python -m pip install -r requirements-dev.txt
python -m ruff check tools tests examples
python -m mypy tools tests/python tests/docs examples
ENGINE_BIN="$PWD/build/bin/ChessEngine" python -m pytestThe full Python suite also needs NumPy and, for training/export tests, PyTorch;
see training setup. ENGINE_BIN selects the classical binary
for UCI and parity tests. In PowerShell set
$env:ENGINE_BIN=(Resolve-Path build-ucrt/bin/ChessEngine.exe).Path first.
Missing PyTorch or engine paths can skip checks; inspect the summary rather than
claiming the entire contract was tested.
The docs conformance suite additionally needs the validator:
ENGINE_BIN="$PWD/build/bin/ChessEngine" VALIDATOR_BIN="$PWD/build/bin/ChessEngine-validator" python -m pytest tests/docs -vIt checks executable examples, documented UCI option names, structured request results/state, the feature example, and the shipped model identity. It checks selected examples, not every English sentence or every external link.
bash tools/viz_smoke.sh build/bin/ChessEngine-viz build/bin/ChessEngine-nnue
./build/bin/test_viz fixture "$PWD/artifacts/viz-frame.bin"
cd ui
npm ci
npm run typecheck
VIZ_FIXTURE="$PWD/../artifacts/viz-frame.bin" npm test
npm run buildCreate artifacts/ before writing a fixture if it does not exist. Use an
absolute VIZ_FIXTURE path in your shell. UI tests require the C++ fixture for
the cross-language wire contract. Rebuild/commit ui/dist/index.html after UI
changes; CI compares the bundle against its source build using Node 24.
The WASM job currently builds and checks the deployable file set; it does not prove browser startup or runtime integer parity. State those checks separately. Its Emscripten toolchain is pinned to 6.0.12, the version verified by CI.
CI runs actionlint 1.7.12 with ShellCheck against every workflow. The validator
download is checksum-verified. Locally, install those tools and run actionlint
from the repository root. This checks workflow expressions, job dependencies and
embedded shell syntax; it does not execute hosted runners or publish anything.
CI complete is the aggregate check for the CI job graph. It fails when any
dependency fails, is cancelled or is skipped. It can be selected as a required
repository check alongside Documentation; changing the workflow does not
configure branch protection automatically. CI and documentation runs have
concurrency cancellation and bounded job timeouts. The full Python job supplies
both engine/validator binaries, PyTorch and PowerShell, and fails on skipped tests.
The native Linux build runs the full CTest suite, both fingerprints, HTTP smoke
and dependency-boundary checks together. Its generated wire fixture feeds the UI
job, avoiding another native build. The portability matrix and ARM dot-product
checks remain separate. Workflow actions are pinned to full commit hashes;
CI and documentation also accept merge-group events if a merge queue is adopted.
The Unix sanitizer recipe follows CI:
cmake -S . -B build-sanitize -DCMAKE_BUILD_TYPE=Debug -DENGINE_LTO=OFF -DENGINE_NATIVE=OFF -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer -g"
cmake --build build-sanitize -j
./build-sanitize/bin/test_zobristThis does not establish race freedom for the shared SMP TT. Record supported hardware when verifying ARM/AVX2-specific kernels.
python -m pip install -r requirements-docs.txt
python -m mkdocs build --strictThe docs workflow builds without publishing, runs conformance tests against its own engine build, and exercises the tiny CPU training walkthrough. A generated site is a local artifact until explicitly deployed.