battest
Runtime test runner for Windows batch files (.bat / .cmd). battest launches
real cmd.exe, then asserts on exit code, stdout, stderr, environment, and
filesystem side effects.
It is a trusted-fixture runner, not a sandbox. Destructive scripts can still
harm the host. Use --safe-defaults (or the GitHub Action, which enables it)
and a disposable VM or CI runner for untrusted suites. Details:
Safety.
battest is a sibling of Blinter (static analysis) and batch-spec (language spec). It does not depend on Blinter.
Requirements: Python 3.11+ and Windows for battest run. License:
AGPL-3.0-or-later (COPYING).
Quick start
pip install battest
Create hello.cmd:
@echo off
echo hello
exit /b 0
Create hello.battest.yaml next to it:
description: hello prints hello
script: hello.cmd
expect:
exit_code: 0
stdout:
contains: hello
Run:
battest run hello.battest.yaml
python -m battest is the same as battest. A passing case prints PASS. A
failing case prints a diff and exits 1. Invalid YAML or usage exits 2.
Case-directory form (batch-spec corpus layout) is equivalent:
tests/hello/input.cmd
tests/hello/expect.yaml
Then battest run tests. From this repository, battest run examples runs the
bundled fixtures.
CLI --safe-defaults is off. The GitHub Action turns it on. That flag
PATH-stubs common destructive externals (format, shutdown, reg, and
others); it does not isolate the filesystem. See CLI and
Mocking.
GitHub Action
Requires a Windows runner. Use the moving major tag (@v1), not a commit SHA.
jobs:
test-batch:
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
- id: battest
uses: tboy1337/battest@v1
with:
path: tests
safe-defaults: "true"
- uses: actions/upload-artifact@v7
if: always()
with:
name: battest-junit
path: ${{ steps.battest.outputs.junit-xml }}
Inputs, outputs, and -- before path are documented in
GitHub Action.
Installation
pip (recommended)
pip install battest
Wheels on PyPI are published from the GitHub pypi environment with
twine upload and the project-scoped PYPI_BATTEST secret.
See Security.
Standalone executable (no Python)
Run this from cmd.exe (not PowerShell). It downloads the bootstrap script,
installs the latest battest.exe to %LOCALAPPDATA%\Programs\battest\bin,
adds that directory to your user PATH, and returns the installer exit code
after deleting the downloaded .cmd:
curl -L https://raw.githubusercontent.com/tboy1337/battest/main/scripts/install_battest.cmd -o install_battest.cmd && call install_battest.cmd & set "BATTEST_INSTALL_EXIT=%ERRORLEVEL%" & del install_battest.cmd & exit /b %BATTEST_INSTALL_EXIT%
The installer always fetches the latest GitHub release and verifies the zip
SHA-256 digest before extract. Download URLs must be https on github.com,
objects.githubusercontent.com, or release-assets.githubusercontent.com.
The bootstrap .cmd itself is not digest-pinned; the exe payload is. Pinning
the curl URL to a release tag (instead of main) is stricter if you want a
known installer script. Restart the terminal or IDE after install so PATH
updates are visible.
Manual zip: download Battest-vX.Y.Z.zip from
GitHub Releases and run
Battest-vX.Y.Z\battest.exe. Some antivirus products flag PyInstaller unpacking
as a false positive. The source is public; pip avoids that class of heuristic.
Uninstall
Standalone install (cmd.exe):
curl -L https://raw.githubusercontent.com/tboy1337/battest/main/scripts/uninstall_battest.cmd -o uninstall_battest.cmd && call uninstall_battest.cmd & set "BATTEST_UNINSTALL_EXIT=%ERRORLEVEL%" & del uninstall_battest.cmd & exit /b %BATTEST_UNINSTALL_EXIT%
pip:
pip uninstall battest
Python API
from battest import load_case, run_case, run_cases
cases = load_case("hello.battest.yaml")
result = run_case(cases[0], safe_defaults=False)
results = run_cases(cases, jobs=1, safe_defaults=False)
run_case / run_cases require Windows cmd.exe. safe_defaults defaults to
off, matching the CLI. Full notes: CLI.
Development
Clone this repository and run python scripts/verify.py (format, types, lint,
pytest, and the PATH-mock stub checks). Stub build details:
PATH mock stub crate.
Documentation
Getting started:
Behavior:
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file battest-1.0.9.tar.gz.
File metadata
- Download URL: battest-1.0.9.tar.gz
- Upload date:
- Size: 280.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f02bea510b453f60080fb4ca63cd7f1f8c8ba2e3e203655ac860a4cac9db9b4
|
|
| MD5 |
076762c4d8bb845f9e5fc64e6517b39a
|
|
| BLAKE2b-256 |
5945bb693f3051a9ed81b4435bad981c3d5ff1a909987454afe5de4ef93716e5
|
File details
Details for the file battest-1.0.9-py3-none-any.whl.
File metadata
- Download URL: battest-1.0.9-py3-none-any.whl
- Upload date:
- Size: 217.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb119e845ffec20df9be990abc1462fed26fe87f4aa6f19d224a7407b8839324
|
|
| MD5 |
eda57a7c0ba7e897a4dfdc6c36ef309d
|
|
| BLAKE2b-256 |
8eb7dd37b8e2154835ac7cb40a6ba6e03d5596bba04c4e10ba6d947d86015c65
|