| description | Configure bashunit with environment variables and config files to control output, parallelism, reporting and test execution across your project. |
|---|
Environment variables and config files control bashunit behavior across your project.
It serves to configure the behavior of bashunit in your project.
You need to create a .env file in the root directory,
but you can give it another name if you pass it as an argument to the command with
--env option.
As an alternative to a .env file, you can place a .bashunitrc file in the
project root with KEY=value lines (blank lines and # comments are ignored):
# .bashunitrc
BASHUNIT_SHOW_HEADER=false
BASHUNIT_PARALLEL_RUN=true
BASHUNIT_PROFILE=trueIt is meant for committing sensible project defaults. Precedence, from highest to lowest:
- CLI flags (e.g.
--simple) - Environment variables and the
.envfile .bashunitrc- Built-in defaults
.bashunitrc only fills values that are not already set, so an exported
environment variable or a .env entry always wins. --skip-env-file skips
.bashunitrc as well.
BASHUNIT_DEFAULT_PATH=directory|file
Specifies the directory or file containing the tests to be run. empty by default.
If a directory is specified, it will execute tests within files ending in test.sh.
When running benchmarks (--bench), the same path is used to search for files ending in bench.sh.
If you use wildcards, bashunit will run any tests it finds.
::: code-group
# all tests inside the tests directory
BASHUNIT_DEFAULT_PATH=tests
# concrete test by full path
BASHUNIT_DEFAULT_PATH=tests/example_test.sh
# all test matching given wildcard
BASHUNIT_DEFAULT_PATH=tests/**/*_test.sh:::
BASHUNIT_SIMPLE_OUTPUT=true|false
Enables simplified output to the console. false by default.
Verbose is the default output, but it can be overridden by the environment configuration.
Similar as using -s|--simple | -vvv|--detailed option on the command line.
::: code-group
....BASHUNIT_SIMPLE_OUTPUT=true:::
::: code-group
Running tests/functional/logic_test.sh
✓ Passed: Other way of using the exit code
✓ Passed: Should validate a non ok exit code
✓ Passed: Should validate an ok exit code
✓ Passed: Text should be equal
BASHUNIT_SIMPLE_OUTPUT=false:::
BASHUNIT_PARALLEL_RUN=true|false
Runs the tests in child processes with randomized execution, which may improve overall testing speed, especially for larger test suites.
::: warning Parallel execution is supported on macOS, Ubuntu, Alpine, and Windows. On other systems bashunit forces sequential execution to avoid inconsistent results. :::
Similar as using -p|--parallel option on the command line.
BASHUNIT_PARALLEL_JOBS=<N>
Limits the number of concurrent jobs when running in parallel mode. Set to 0 (default) for unlimited concurrency.
Similar as using -j|--jobs option on the command line.
BASHUNIT_STOP_ON_FAILURE=true|false
Force to stop the runner right after encountering one failing test. false by default.
Similar as using -S|--stop-on-failure option on the command line.
::: tip Assertion behavior
By default, when an assertion fails within a test, subsequent assertions in the same test are skipped. Use -R, --run-all or set BASHUNIT_STOP_ON_ASSERTION_FAILURE=false to run all assertions even when one fails.
The --stop-on-failure flag is separate – it stops the entire test runner after a failing test, while assertion-level stopping happens within each test.
:::
BASHUNIT_TEST_TIMEOUT=<seconds>
Abort an individual test if it runs longer than the given number of seconds,
report it as a failure and keep running the remaining tests. 0 (disabled) by
default. Useful to stop a run from hanging forever on a blocked test, such as a
mock left without an implementation.
The value is expressed in whole seconds and applies per test (set up and tear
down included). It needs no external timeout command and works on Bash 3.2+,
including the default macOS Bash.
Similar as using --test-timeout option on the command line.
::: code-group
BASHUNIT_TEST_TIMEOUT=5BASHUNIT_TEST_TIMEOUT=0:::
BASHUNIT_RETRY=<n>
Re-run a failed test up to n extra times and report it as passed if any
attempt passes; it fails only after every attempt fails. 0 (disabled) by
default. Mitigates flaky tests in CI without hiding a consistently broken one; a
test that recovers on retry is annotated so the flakiness stays visible.
Applies per test and works together with --parallel and --stop-on-failure.
Similar as using --retry option on the command line.
::: code-group
BASHUNIT_RETRY=2BASHUNIT_RETRY=0:::
BASHUNIT_RANDOM_ORDER=true|falseandBASHUNIT_SEED=<n>
Randomize the order of test files and of the tests within each file to surface
hidden inter-test coupling. Disabled by default. BASHUNIT_SEED pins the
shuffle so a run can be replayed; when unset, a seed is generated and printed in
the run header. Composes with --parallel.
Similar as using --random-order / --seed options on the
command line.
::: code-group
BASHUNIT_RANDOM_ORDER=true
BASHUNIT_SEED=12345BASHUNIT_RANDOM_ORDER=false:::
BASHUNIT_STOP_ON_ASSERTION_FAILURE=true|false
Controls whether to stop at the first failed assertion within a test. true by default.
When enabled (default), subsequent assertions in the same test are skipped after a failure. When disabled, all assertions in the test run, showing all failures at once.
Similar as using -R|--run-all option on the command line.
::: code-group
BASHUNIT_STOP_ON_ASSERTION_FAILURE=falseBASHUNIT_STOP_ON_ASSERTION_FAILURE=true:::
BASHUNIT_WATCH_INTERVAL=<seconds>
Seconds between checks for the pure-shell polling loop used by watch mode when
neither inotifywait nor fswatch is installed. 2 by default. Must be a
positive integer; any other value falls back to the default.
::: code-group
BASHUNIT_WATCH_INTERVAL=5:::
BASHUNIT_SHOW_HEADER=true|false
BASHUNIT_HEADER_ASCII_ART=true|false
Specify if you want to show the bashunit header. true by default.
Additionally, you can use the env-var BASHUNIT_HEADER_ASCII_ART to display bashunit in ASCII. false by default.
::: code-group
✓ Passed: foo bar
BASHUNIT_SHOW_HEADER=false:::
::: code-group
bashunit - {{ pkg.version }} // [!code hl]
✓ Passed: foo bar
BASHUNIT_SHOW_HEADER=true:::
::: code-group
__ _ _ // [!code hl]
| |__ __ _ ___| |__ __ __ ____ (_) |_ // [!code hl]
| '_ \ / _' / __| '_ \| | | | '_ \| | __| // [!code hl]
| |_) | (_| \__ \ | | | |_| | | | | | |_ // [!code hl]
|_.__/ \__,_|___/_| |_|\___/|_| |_|_|\__| // [!code hl]
{{ pkg.version }} // [!code hl]
✓ Passed: foo bar
BASHUNIT_SHOW_HEADER=true
BASHUNIT_HEADER_ASCII_ART=true:::
BASHUNIT_SHOW_EXECUTION_TIME=true|false|auto
Specify if you want to display the per-test execution time after running bashunit. auto by default.
auto shows per-test times when the shell has a fork-free high-resolution clock (Bash 5.0+ via EPOCHREALTIME, or GNU date), and hides them when measuring a test would require forking an interpreter (for example the default Bash 3.2 on macOS, which falls back to perl). This keeps a plain run fast on those shells. Set true to always measure and show per-test times (paying that cost), or false to always hide them. --profile, --verbose, and the --report-*/--log-junit reports always measure regardless of this setting.
The time format adapts based on duration:
- Under 1 second: displayed in milliseconds (e.g.,
14 ms) - 1-59 seconds: displayed in seconds (e.g.,
5 s) - 60+ seconds: displayed in minutes and seconds (e.g.,
2m 1s)
::: code-group
✓ Passed: foo bar
Tests: 1 passed, 1 total
Assertions: 3 passed, 3 total
All tests passed
Time taken: 14 ms // [!code hl]
BASHUNIT_SHOW_EXECUTION_TIME=true:::
::: code-group
✓ Passed: foo bar
Tests: 1 passed, 1 total
Assertions: 3 passed, 3 total
All tests passed
BASHUNIT_SHOW_EXECUTION_TIME=false:::
BASHUNIT_OUTPUT_FORMAT=tap
Select an alternative output format. Currently supported: tap for
TAP version 13,
useful for CI/CD integrations.
Similar as using --output option on the command line.
::: code-group
BASHUNIT_OUTPUT_FORMAT=tap:::
BASHUNIT_LOG_JUNIT=file
Create a report XML file that follows the JUnit XML format and contains information about the test results of your bashunit tests.
::: code-group
BASHUNIT_LOG_JUNIT=log-junit.xml:::
BASHUNIT_LOG_GHA=file
Write GitHub Actions workflow commands (::error, ::warning, ::notice) to the given file, so failed, risky and incomplete tests show up as inline annotations in the "Files changed" tab of a pull request.
On a CI runner, stream the generated file to stdout so GitHub parses it:
::: code-group
BASHUNIT_LOG_GHA=gha.log- run: ./bashunit --log-gha gha.log tests/ || (cat gha.log && exit 1):::
BASHUNIT_REPORT_HTML=file
Create a report HTML file that contains information about the test results of your bashunit tests.
::: code-group
BASHUNIT_REPORT_HTML=report.html:::
BASHUNIT_BOOTSTRAP=file
Specifies an additional file to be loaded for all tests cases. Useful to set up global variables or functions accessible in all your tests.
::: tip Using functions in tests
If you need shell functions available in your tests, define them in a bootstrap
file and use export -f function_name to make them available in test subshells.
This is the recommended pattern for sharing functions across tests.
:::
Similarly, you can use load an additional file via the command line.
::: code-group
# a simple .env file
BASHUNIT_BOOTSTRAP=".env.tests"
# or a complete script file
BASHUNIT_BOOTSTRAP="tests/globals.sh"
# Default value
BASHUNIT_BOOTSTRAP="tests/bootstrap.sh":::
BASHUNIT_BOOTSTRAP_ARGS=arguments
Pass arguments to the bootstrap file. Arguments are space-separated and available
as positional parameters ($1, $2, etc.) in your bootstrap script.
::: code-group
BASHUNIT_BOOTSTRAP="tests/bootstrap.sh"
BASHUNIT_BOOTSTRAP_ARGS="staging verbose"#!/usr/bin/env bash
ENVIRONMENT="${1:-production}"
VERBOSE="${2:-false}"
export API_URL="https://${ENVIRONMENT}.api.example.com":::
You can also pass arguments inline via the --env option:
bashunit --env "tests/bootstrap.sh staging verbose" tests/
BASHUNIT_DEV_LOG=file
See: Globals > log
::: code-group
BASHUNIT_DEV_LOG="dev.log"log "I am tracing something..."
log "error" "an" "error" "message"
log "warning" "different log level messages!"2024-10-03 21:27:23 [INFO]: I am tracing something... #tests/sample.sh:11
2024-10-03 21:27:23 [ERROR]: an error message #tests/sample.sh:27
2024-10-03 21:27:24 [WARNING]: different log level messages! #tests/sample.sh:21:::
When enabled, the selected log file path is printed in the header so you can
quickly tail -f it while the tests run.
All internal messages emitted by bashunit are prefixed with
[INTERNAL]. You can toggle internal messages withBASHUNIT_INTERNAL_LOG=true|false.
BASHUNIT_VERBOSE=bool
Display internal details for each test.
Similarly, you can use the command line option for this: command line.
::: code-group
BASHUNIT_VERBOSE=true:::
BASHUNIT_NO_OUTPUT=true|false
Suppress all console output. Defaults to false.
Similar as using --no-output option on the command line.
::: code-group
BASHUNIT_NO_OUTPUT=true:::
BASHUNIT_FAIL_ON_RISKY=true|false
Treat risky tests (tests with zero assertions) as failures instead of warnings. false by default.
When enabled, a test that finishes without running any assertion is reported as failed, and the run exits with a non-zero status.
Similar as using --fail-on-risky option on the command line.
::: code-group
BASHUNIT_FAIL_ON_RISKY=true:::
BASHUNIT_PROFILE=true|false·BASHUNIT_PROFILE_COUNT=<n>
Report the slowest tests after a run. false by default; BASHUNIT_PROFILE_COUNT defaults to 10.
When enabled, each test's duration is recorded and the slowest ones are printed at the end,
sorted from slowest to fastest. BASHUNIT_PROFILE_COUNT limits how many are shown.
Similar as using --profile option on the command line.
::: code-group
BASHUNIT_PROFILE=true
BASHUNIT_PROFILE_COUNT=5:::
BASHUNIT_FAILURES_ONLY=true|false
Only show failures, suppressing passed, skipped, and incomplete tests. false by default.
When enabled, progress output is suppressed and only failing tests are displayed. The final summary still shows all counts (passed/failed/skipped/incomplete).
Similar as using --failures-only option on the command line.
::: code-group
BASHUNIT_FAILURES_ONLY=true:::
BASHUNIT_NO_PROGRESS=true|false
Suppress real-time progress display during test execution. false by default.
When enabled, bashunit hides per-test output, file headers, hook messages, and spinners, showing only the final summary. Useful for CI/CD pipelines or log-restricted environments.
Similar as using --no-progress option on the command line.
::: code-group
BASHUNIT_NO_PROGRESS=true:::
BASHUNIT_SHOW_OUTPUT_ON_FAILURE=true|false
Display captured stdout/stderr output when tests fail with runtime errors or assertion failures. true by default.
When a test fails due to a runtime error (command not found, unbound variable, etc.) or a failed assertion after the test printed diagnostics, bashunit displays the test's output in an "Output:" section to help debug the failure.
Similar as using --show-output or --no-output-on-failure options on the command line.
::: code-group
✗ Error: My test function
command not found
Output:
Debug: Setting up test
Running command: my_command
BASHUNIT_SHOW_OUTPUT_ON_FAILURE=false:::
BASHUNIT_NO_DIFF=true|false
When an assert_equals/assert_same failure involves a multiline value,
bashunit renders a git word-diff below the Expected/but got header so the
difference is easy to spot; the inline values are truncated to their first line
while the diff is shown. Requires git (falls back to the plain output when it is
unavailable), respects --no-color, and never affects single-line failures or
machine reports (JUnit/TAP/JSON). false by default — set BASHUNIT_NO_DIFF=true
to always print the full raw values instead.
::: code-group
✗ Failed: My test function
Expected 'alpha…'
but got 'alpha…'
alpha
[-beta-]{+DELTA+}
gamma
BASHUNIT_NO_DIFF=true:::
NO_COLOR=1
Disables ANSI color codes in output. Follows the no-color.org standard.
When set to any value, bashunit will output plain text without color formatting.
Similar as using --no-color option on the command line.
::: code-group
NO_COLOR=1:::
BASHUNIT_STRICT_MODE=true|false
Enable strict shell mode (set -euo pipefail) for test execution. false by default.
By default, tests run in permissive mode to maximize compatibility with different coding styles. Enable strict mode to catch potential issues like uninitialized variables and unchecked command failures.
Similar as using --strict option on the command line.
::: code-group
BASHUNIT_STRICT_MODE=true:::
BASHUNIT_SKIP_ENV_FILE=true|false
Skip loading the .env file and use the current shell environment only. false by default.
By default, bashunit loads variables from .env which can override environment
variables set in your shell. Enable this option when running in CI/CD pipelines
or when you want shell environment variables to take precedence.
::: warning Important Only environment variables are inherited from the parent shell. Shell functions and aliases are NOT available in tests due to bashunit's subshell architecture. Use a bootstrap file to define functions needed by your tests. :::
Similar as using --skip-env-file option on the command line.
::: code-group
BASHUNIT_SKIP_ENV_FILE=true ./bashunit tests/:::
BASHUNIT_LOGIN_SHELL=true|false
Run tests in a login shell context by sourcing profile files. false by default.
When enabled, bashunit sources the following files (if they exist) before each test:
/etc/profile~/.bash_profile~/.bash_login~/.profile
Use this when your tests depend on environment setup from login shell profiles.
Similar as using -l|--login option on the command line.
::: code-group
BASHUNIT_LOGIN_SHELL=true:::
BASHUNIT_COVERAGE=true|false
Enable code coverage tracking. false by default.
When enabled, bashunit tracks which lines of your source code are executed during tests and generates a coverage report.
Similar as using --coverage option on the command line.
::: code-group
BASHUNIT_COVERAGE=true:::
BASHUNIT_COVERAGE_PATHS=paths
Comma-separated list of paths to track for coverage.
By default, paths are auto-discovered from test file names (e.g., tests/unit/assert_test.sh discovers src/assert.sh).
::: code-group
# Single path (explicit)
BASHUNIT_COVERAGE_PATHS=src/
# Multiple paths (explicit)
BASHUNIT_COVERAGE_PATHS=src/,lib/,bin/:::
BASHUNIT_COVERAGE_EXCLUDE=patterns
Comma-separated list of patterns to exclude from coverage tracking.
Default: tests/*,vendor/*,*_test.sh,*Test.sh
::: code-group
BASHUNIT_COVERAGE_EXCLUDE=tests/*,vendor/*,*_test.sh,*_mock.sh:::
BASHUNIT_COVERAGE_REPORT=file
Path for the LCOV format coverage report. coverage/lcov.info by default.
Set to empty string to disable file generation (console report only).
::: code-group
# Custom path
BASHUNIT_COVERAGE_REPORT=reports/coverage.lcov
# Disable file output
BASHUNIT_COVERAGE_REPORT=:::
BASHUNIT_COVERAGE_MIN=percent
Minimum coverage percentage required. Empty by default (no minimum).
When set, bashunit will exit with a failure code if coverage falls below this threshold.
::: code-group
BASHUNIT_COVERAGE_MIN=80:::
BASHUNIT_COVERAGE_THRESHOLD_LOW=percent
BASHUNIT_COVERAGE_THRESHOLD_HIGH=percent
Thresholds for color-coding the coverage output. Defaults: 50 and 80.
- Below
THRESHOLD_LOW: Red - Between thresholds: Yellow
- Above
THRESHOLD_HIGH: Green
::: code-group
BASHUNIT_COVERAGE_THRESHOLD_LOW=60
BASHUNIT_COVERAGE_THRESHOLD_HIGH=90:::
- Command line — flags that mirror these settings
- Test files — how tests are discovered and named
- Coverage — measure how much code your tests exercise
- Globals — helper functions available in tests