Fixtures, Temp Environments, and Coverage
Build isolated test fixtures and measure which script branches your tests actually exercise.
Why Fixtures and Isolation Matter
When testing Bash scripts, the biggest risk is side effects: your tests accidentally modify real files, real databases, or real system state. A test that passes on your machine but corrupts production data is worse than no test at all.
The solution is test fixtures — controlled, disposable environments that mirror real conditions without touching anything real. Good fixtures give you:
- Reproducibility — tests produce the same result every run
- Isolation — tests do not interfere with each other or with the host
- Safety — destructive operations only touch throwaway data
- Speed — no network calls, no heavy I/O unless absolutely necessary
In Bash testing, fixtures are typically temporary directories populated with known files, mock executables placed early on $PATH, and environment variables scoped to the test process.
Creating and Cleaning Up Temp Directories
The standard pattern for a per-test temporary directory uses mktemp -d, which creates a unique directory in /tmp and prints its path. You store the path and register a trap to remove it automatically when the shell exits — even on failure.
This two-line idiom should appear in every test file that touches the filesystem:
#!/usr/bin/env bash
set -euo pipefail
# Create an isolated temp directory
TMPDIR=$(mktemp -d)
# Always clean up, even if the script exits early or errors out
trap 'rm -rf "$TMPDIR"' EXIT
echo "Working in: $TMPDIR"
# Simulate creating fixture files
mkdir -p "$TMPDIR/project/{src,tests,logs}"
echo 'version=1.2.3' > "$TMPDIR/project/.env"
echo 'Hello fixture' > "$TMPDIR/project/src/main.sh"
ls -R "$TMPDIR/project"
echo 'Temp dir will be removed automatically on exit'All lessons in this course
- Unit Testing Functions with Bats-core
- Mocking Commands and Stubbing External Tools
- Fixtures, Temp Environments, and Coverage
- Running Shell Tests in CI Pipelines