Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 134 additions & 10 deletions docs/command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
```bash
bashunit test [path] [options] # Run tests (default)
bashunit bench [path] [options] # Run benchmarks
bashunit watch [path] [options] # Watch files, re-run tests on change
bashunit assert <fn> <args> # Run standalone assertion
bashunit doc [filter] # Show assertion documentation
bashunit init [dir] # Initialize test directory
bashunit learn # Interactive tutorial
Expand Down Expand Up @@ -55,6 +57,10 @@ bashunit test tests/ --parallel --simple
| `-a, --assert <fn> <args>` | Run a standalone assert function |
| `-e, --env, --boot <file>` | Load custom env/bootstrap file (supports args) |
| `-f, --filter <name>` | Only run tests matching name |
| `--tag <name>` | Only run tests with matching `@tag` (repeatable) |
| `--exclude-tag <name>` | Skip tests with matching `@tag` (repeatable) |
| `--output <format>` | Output format (`tap` for TAP version 13) |
| `-w, --watch` | Watch files and re-run tests on change |
| `--log-junit <file>` | Write JUnit XML report |
| `-j, --jobs <N>` | Run tests in parallel with max N concurrent jobs |
| `-p, --parallel` | Run tests in parallel |
Expand Down Expand Up @@ -114,6 +120,84 @@ bashunit test tests/ --filter "user_login"
```
:::

### Tags

> `bashunit test --tag <name>`
> `bashunit test --exclude-tag <name>`

Filter tests by `# @tag` annotations. Both flags are repeatable. `--tag` uses OR
logic across names; `--exclude-tag` wins when a test matches both.

::: code-group
```bash [Annotate tests]
# @tag slow
function test_heavy_computation() {
...
}

# @tag integration
function test_api_call() {
...
}
```
```bash [Run by tag]
bashunit test tests/ --tag slow
bashunit test tests/ --tag slow --tag integration
bashunit test tests/ --exclude-tag integration
```
:::

### Output format

> `bashunit test --output <format>`

Select an alternative output format. Currently supported:

- `tap` — [TAP version 13](https://testanything.org/tap-version-13-specification.html) for CI/CD integrations.

The `TAP version 13` header comes first, each test file is announced via a
`# <path>` diagnostic line, each test emits an `ok <n> - <name>` or
`not ok <n> - <name>` line (failures include a YAML `--- ... ...` block with
expected/actual), and the `1..N` plan line closes the report.

::: code-group
```bash [Example]
bashunit test tests/ --output tap
```
```[Output]
TAP version 13
# tests/example_test.sh
ok 1 - Should validate input
not ok 2 - Should handle errors
---
Expected 'foo'
but got 'bar'
...

1..2
```
:::

### Watch mode

> `bashunit test -w|--watch`

Watch the test path (plus `src/` if present) and re-run tests when files change.
The `-w`/`--watch` flag uses a lightweight **checksum polling loop** that works
on any system — no external tools required.

::: code-group
```bash [Example]
bashunit test tests/ --watch
```
:::

::: tip
For file-event-driven watching (no polling), use the dedicated
[`watch`](#watch) subcommand, which relies on `inotifywait` (Linux) or
`fswatch` (macOS).
:::

### Environment / Bootstrap

> `bashunit test -e|--env|--boot <file>`
Expand Down Expand Up @@ -326,7 +410,7 @@ This is useful for:
bashunit test tests/ --no-progress
```
```[Output]
bashunit - 0.32.0 | Tests: 10
bashunit - 0.34.1 | Tests: 10
Tests: 10 passed, 10 total
Assertions: 25 passed, 25 total

Expand Down Expand Up @@ -464,6 +548,43 @@ bashunit bench --filter "parse"
| `--skip-env-file` | Skip `.env` loading, use shell environment only |
| `-l, --login` | Run in login shell context |

## watch

> `bashunit watch [path] [test-options]`

Dedicated watch subcommand that uses **OS file-event notifications** (no
polling) to re-run tests as soon as a `.sh` file changes. Any option accepted
by `bashunit test` is also accepted here.

::: code-group
```bash [Examples]
# Watch current directory
bashunit watch

# Watch the tests/ directory
bashunit watch tests/

# Watch and filter by name
bashunit watch tests/ --filter user

# Watch with simple output
bashunit watch tests/ --simple
```
:::

::: warning Requirements
- **Linux:** `inotifywait` (`sudo apt install inotify-tools`)
- **macOS:** `fswatch` (`brew install fswatch`)

If the required tool is not installed, bashunit prints a clear installation hint
and exits with a non-zero code.
:::

::: tip
If you cannot install `inotifywait` or `fswatch`, use the portable
[`-w/--watch`](#watch-mode) flag on `bashunit test` instead (uses polling).
:::

## doc

> `bashunit doc [filter]`
Expand Down Expand Up @@ -567,7 +688,7 @@ bashunit upgrade
```
```[Output]
> Upgrading bashunit to latest version
> bashunit upgraded successfully to latest version 0.28.0
> bashunit upgraded successfully to latest version 0.34.1
```
:::

Expand Down Expand Up @@ -604,16 +725,18 @@ bashunit --help
Usage: bashunit <command> [arguments] [options]

Commands:
test [path] Run tests (default command)
bench [path] Run benchmarks
doc [filter] Display assertion documentation
init [dir] Initialize a new test directory
learn Start interactive tutorial
upgrade Upgrade bashunit to latest version
test [path] Run tests (default command)
bench [path] Run benchmarks
assert <fn> <args> Run standalone assertion
doc [filter] Display assertion documentation
init [dir] Initialize a new test directory
learn Start interactive tutorial
watch [path] Watch files and re-run tests on change
upgrade Upgrade bashunit to latest version

Global Options:
-h, --help Show this help message
-v, --version Display the current version
-h, --help Show this help message
-v, --version Display the current version

Run 'bashunit <command> --help' for command-specific options.
```
Expand All @@ -624,6 +747,7 @@ Each subcommand also supports `--help`:
```bash
bashunit test --help
bashunit bench --help
bashunit watch --help
bashunit doc --help
```

Expand Down
16 changes: 16 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,22 @@ BASHUNIT_SHOW_EXECUTION_TIME=false
```
:::

## Output format

> `BASHUNIT_OUTPUT_FORMAT=tap`

Select an alternative output format. Currently supported: `tap` for
[TAP version 13](https://testanything.org/tap-version-13-specification.html),
useful for CI/CD integrations.

Similar as using `--output` option on the [command line](/command-line#output-format).

::: code-group
```bash [.env]
BASHUNIT_OUTPUT_FORMAT=tap
```
:::

## Log JUnit

> `BASHUNIT_LOG_JUNIT=file`
Expand Down
43 changes: 42 additions & 1 deletion docs/globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Internal messages from bashunit include the `[INTERNAL]` prefix so you can easil

> `bashunit::caller_filename`: Gets the caller filename.

## bashunit::caller_line

> `bashunit::caller_line`: Gets the line number of the caller.

Useful inside custom assertions to report the line that triggered the failure.

## bashunit::current_timestamp

> `bashunit::current_timestamp`: Gets the current timestamp.
Expand All @@ -54,4 +60,39 @@ The directory is automatically deleted when bashunit completes.

## bashunit::is_command_available

> `bashunit::is_command_available`: Checks if command is available
> `bashunit::is_command_available <command>`: Checks if a command is available in `PATH`.

Returns `0` when the command is found, `1` otherwise.

```bash
if bashunit::is_command_available jq; then
# jq-based assertions
fi
```

## bashunit::print_line

> `bashunit::print_line <?length> <?char>`: Prints a horizontal separator.

Defaults to 70 characters of `-`. Both arguments are optional.

```bash
bashunit::print_line # 70 dashes
bashunit::print_line 40 '=' # 40 equals signs
```

## Custom assertion helpers

These helpers are intended for building [custom assertions](/custom-asserts).

- `bashunit::assertion_passed` — Mark the current assertion as passed.
- `bashunit::assertion_failed <expected> <actual> <?label>` — Mark the current
assertion as failed and print a failure report.
- `bashunit::fail <?message>` — Fail the current test with an optional message.

See [Custom asserts](/custom-asserts) for full examples.

## Test doubles

The `bashunit::spy`, `bashunit::mock`, and `bashunit::unmock` helpers are
documented in [Test doubles](/test-doubles).
35 changes: 35 additions & 0 deletions tests/acceptance/bashunit_tap_output_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail

function set_up_before_script() {
TEST_ENV_FILE="tests/acceptance/fixtures/.env.default"
}

function test_tap_output_passing_tests_matches_snapshot() {
local test_file=tests/acceptance/fixtures/test_bashunit_when_a_test_passes.sh

assert_match_snapshot "$(./bashunit --no-parallel --env "$TEST_ENV_FILE" --output tap "$test_file")"
}

function test_tap_output_failing_tests_matches_snapshot() {
local test_file=tests/acceptance/fixtures/test_bashunit_when_a_test_fail.sh

assert_match_snapshot "$(./bashunit --no-parallel --env "$TEST_ENV_FILE" --output tap "$test_file" 2>&1 || true)"
}

function test_tap_output_env_var_equivalent_to_flag() {
local test_file=tests/acceptance/fixtures/test_bashunit_when_a_test_passes.sh
local via_flag
local via_env

via_flag=$(./bashunit --no-parallel --env "$TEST_ENV_FILE" --output tap "$test_file")
via_env=$(BASHUNIT_OUTPUT_FORMAT=tap ./bashunit --no-parallel --env "$TEST_ENV_FILE" "$test_file")

assert_equals "$via_flag" "$via_env"
}

function test_tap_output_exits_non_zero_on_failure() {
local test_file=tests/acceptance/fixtures/test_bashunit_when_a_test_fail.sh

assert_general_error "$(./bashunit --no-parallel --env "$TEST_ENV_FILE" --output tap "$test_file" 2>&1)"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
TAP version 13
# tests/acceptance/fixtures/test_bashunit_when_a_test_fail.sh
ok 1 - Assert same
ok 2 - Assert contains
not ok 3 - Assert failing
---
Expected '1'
but got '0'
...
ok 4 - Assert greater and less than
ok 5 - Assert empty

1..5
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TAP version 13
# tests/acceptance/fixtures/test_bashunit_when_a_test_passes.sh
ok 1 - Assert same
ok 2 - Assert contains
ok 3 - Assert greater and less than
ok 4 - Assert empty

1..4
Loading