Testing Shell Scripts📜
Overview📜
Big Bang uses BATS (Bash Automated Testing System) to unit-test shell scripts in the repository. The primary test suites cover k3d-dev.sh, the script that automates remote k3d development environments on AWS, and quickstart.sh, the script that orchestrates quickstart provisioning, deployment, and wait flows.
These tests verify pure functions and argument parsing – no real AWS API calls, SSH connections, or network requests are made. Each test sources the script, calls a function, and checks a variable.
Optionally, Lefthook can run these tests automatically as git hooks so you catch regressions before they leave your machine.
Prerequisites📜
Install BATS📜
macOS (Homebrew):
brew install bats-core
Linux and other platforms: See the official BATS installation guide for options including apt, dnf, npm, and building from source.
Install Lefthook (optional)📜
Lefthook is not required to run BATS tests directly, but it wires them into your git workflow so they fire on commit and push.
macOS (Homebrew):
brew install lefthook
Linux and other platforms: See the Lefthook installation docs for options including apt, rpm, npm, standalone binaries, and building from source.
Running Tests📜
Run tests directly📜
bats tests/bats/k3d-dev/k3d-dev.bats
To run the quickstart suite directly:
bats tests/bats/quickstart/quickstart.bats
To run all BATS test suites recursively (useful as more suites are added):
bats --recursive tests/bats/
Run tests in parallel📜
BATS supports parallel execution with the --jobs flag when the local BATS installation has the required parallel runner available:
bats --jobs 4 --recursive tests/bats/
Expected output📜
A passing run looks like this:
k3d-dev/k3d-dev.bats
✓ k3dsshcmd builds correct SSH command
✓ set_kubeconfig uses PublicIP when not provisioning
✓ set_kubeconfig uses AWSUSERNAME when provisioning
✓ process_arguments -b sets BIG_INSTANCE=true
✓ process_arguments -M sets METAL_LB=false
✓ process_arguments -p sets PRIVATE_IP=true
✓ process_arguments -d sets action=destroy_instances
✓ process_arguments -t sets PROJECTTAG
✓ process_arguments -K sets RESET_K3D=true
✓ process_arguments -H sets PublicIP and disables cloud provisioning
✓ process_arguments -H without -P sets PrivateIP=PublicIP
✓ process_arguments -D and --domain set BASE_DOMAIN
✓ process_arguments handles multiple flags
✓ process_arguments reports unknown option
✓ set_domains builds PUBLIC_DOMAINS and PASSTHROUGH_DOMAINS
✓ set_domains uses default BASE_DOMAIN
✓ set_domains clears stale values before rebuilding
✓ run_batch_add fails if no batch started
Enabling Lefthook📜
Lefthook is opt-in. It does nothing until you explicitly install its hooks into your local clone.
One-time setup📜
lefthook install
This writes git hooks into .git/hooks/ that delegate to lefthook.yaml in the repo root. If you later want to remove them, run lefthook uninstall.
What the hooks do📜
| Hook | Trigger | Runs when |
|---|---|---|
pre-commit |
git commit |
A covered script or its matching tests/bats/... suite is staged |
pre-push |
git push |
Any *.sh or *.bats file changed vs. the remote |
The pre-commit hook runs the focused suite for the staged script, such as bats tests/bats/quickstart/quickstart.bats for quickstart.sh changes. The pre-push hook runs bats --jobs 4 --recursive tests/bats/. The glob filters mean they only fire when shell or test files are involved – a commit that only touches YAML or Markdown skips them entirely.
Running hooks manually📜
You can invoke the hooks by name without actually committing or pushing:
# Run the pre-commit hook against all files
lefthook run pre-commit --all-files
# Run the pre-push hook
lefthook run pre-push
Test structure📜
Test files live under tests/bats/, organized by the script they cover:
tests/bats/
├── k3d-dev/
│ └── k3d-dev.bats # Tests for docs/reference/scripts/developer/k3d-dev.sh
└── quickstart/
└── quickstart.bats # Tests for docs/reference/scripts/quickstart.sh
Each .bats file is a valid Bash script annotated with @test blocks. Helper functions load the script under test and restore default variable state between tests so they stay independent.
The k3d-dev.sh test suite covers four areas:
- Pure functions –
k3dsshcmd,set_kubeconfig - Argument parsing – common flags accepted by
process_arguments - Domain configuration –
set_domainsbuilding FQDN lists from subdomains - Error guards – batch-file operations fail cleanly when misused
The quickstart.sh test suite covers:
- Argument parsing – quickstart flags, implied flags, unknown options, and Helm passthrough arguments
- Pure helpers – k3d-dev argument generation and dependency checks
- Command construction – mocked
k3d-dev.shandhelminvocations - Workflow orchestration – mocked destroy and deploy/wait flows without real Git, AWS, Helm, Flux, or Kubernetes calls