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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Added

- Blog posts for releases 0.43.0 through 0.52.0, including the 0.50.1 cleanup patch

## [0.52.0](https://github.com/TypedDevs/bashunit/compare/0.51.0...0.52.0) - 2026-10-11

### Changed
Expand Down
40 changes: 40 additions & 0 deletions docs/blog/2026-07-24-release-0-43.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
date: '2026-07-24'
title: 'Release 0.43.0'
description: 'See which loops your tests reach, with fewer extra processes during checks and parallel tests.'
coverAlt: 'Reports of loops reached by tests and fewer extra processes during checks'

aside: false
---

# {{ $frontmatter.title }}

<time>{{ $formatDate($frontmatter.date) }}</time>

Release 0.43.0 reports whether your tests enter loops. It also reduces the extra processes started by checks, called assertions, and by tests running at the same time. Existing checks keep their behavior, so you do not need to rewrite tests.

## Find loops your tests never enter

The report now includes `while`, `until`, `for`, and `select` loops. Each loop body counts as one possible path through the code, called a branch. That path is marked reached when the loop runs at least once. A test with only empty input can leave the loop body untested even when the surrounding function runs successfully ([#855](https://github.com/TypedDevs/bashunit/issues/855)).

```bash
bashunit tests/ --coverage --coverage-paths src/
```

For a function that processes a list, include both an empty-list case and a case with at least one item. The first checks what happens when the loop is skipped; the second reaches its body. The report now makes that missing test case visible. It records whether the loop was entered, rather than treating each pass through the loop as a separate path.

## Fewer processes for the same checks

Text checks such as `assert_contains`, `assert_matches`, and checks of the start and end of a value no longer start an extra shell process to join their arguments. Checks of arrays, dates, durations, JSON, files, and folders also find their failure labels without starting a shell process to capture a value. The labels and comparisons stay the same ([#844](https://github.com/TypedDevs/bashunit/issues/844)).

Tests running at the same time now name result files using a sequence number assigned by the test run. This replaces creating and renaming a temporary file for every test. Tests supplied with different sets of input values also avoid the chain of commands previously used to make those inputs safe for filenames. Results are still collected in the same way ([#851](https://github.com/TypedDevs/bashunit/issues/851)).

```bash
bashunit --parallel tests/
```

These changes reduce repeated work as the number of checks and tests grows. They add no new options and do not change how you run the tests.

---

See the full changelog for [0.43.0](https://github.com/TypedDevs/bashunit/releases/tag/0.43.0) on GitHub.
52 changes: 52 additions & 0 deletions docs/blog/2026-07-29-release-0-44.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
date: '2026-07-29'
title: 'Release 0.44.0'
description: 'Test your own checks, manage saved expected output, and catch command-tracking and setup mistakes.'
coverAlt: 'Testing custom checks, reviewing saved expected output and catching setup mistakes'

aside: false
---

# {{ $frontmatter.title }}

<time>{{ $formatDate($frontmatter.date) }}</time>

Release 0.44.0 helps you test and document your own checks, called custom assertions. It also gives you more control over saved expected output and catches setup mistakes that could previously produce misleading results.

## Build and test your own checks

`bashunit::assert_that` runs a command and records whether the check passed in one call. `bashunit::assert_once` lets a check made of several smaller checks count and report once under its own label. Existing totals stay unchanged unless you choose to use it ([#915](https://github.com/TypedDevs/bashunit/issues/915), [#917](https://github.com/TypedDevs/bashunit/issues/917)).

The new `assert_assertion_passes`, `assert_assertion_fails`, and `assert_assertion_fails_with` helpers test what your check reports. They keep its counts and output separate, so an expected failure does not fail the surrounding test ([#916](https://github.com/TypedDevs/bashunit/issues/916)).

```bash
function test_positive_assertion() {
assert_assertion_passes assert_positive_number 3
assert_assertion_fails_with "positive number" assert_positive_number 0
}
```

Here, `assert_positive_number` is your project's check. Load the setup file that defines it to list its documentation alongside the built-in reference. Use `--custom` to list only your project's checks ([#918](https://github.com/TypedDevs/bashunit/issues/918)).

```bash
bashunit doc --custom --boot tests/bootstrap.sh
```

## Review saved expected output

A snapshot is saved expected output that later runs compare against. Use `--snapshot-update` to replace existing snapshots after an intentional change, optionally narrowing the run with `--filter`. Snapshots containing markers for text you chose to ignore are left alone. In automated checks, `--no-snapshot-create` makes a missing snapshot fail instead of silently saving the first reference. `--snapshot-report-unused` lists leftovers from renamed or deleted tests without deleting anything. It requires a full run ([#900](https://github.com/TypedDevs/bashunit/issues/900), [#901](https://github.com/TypedDevs/bashunit/issues/901), [#902](https://github.com/TypedDevs/bashunit/issues/902)).

```bash
bashunit tests/ --no-snapshot-create
bashunit tests/ --snapshot-report-unused
```

## Catch mistakes before trusting a pass

A spy tracks calls to a command. Checks of those calls now reject a command that was never registered for tracking, instead of reporting zero calls. Comparing arguments one at a time distinguishes one argument containing a space from two separate arguments. Failed checks show the recorded calls.

Invalid options, numeric settings, and missing setup or environment files now produce errors. Coverage, which reports how much code the tests reach, also gains an `xtrace` method of recording execution on Bash 4.1 and later. Automatic selection keeps the existing `trap` method on older shells. Bash 3.0 remains the minimum supported version.

---

See the full changelog for [0.44.0](https://github.com/TypedDevs/bashunit/releases/tag/0.44.0) on GitHub.
50 changes: 50 additions & 0 deletions docs/blog/2026-08-09-release-0-45.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
date: '2026-08-09'
title: 'Release 0.45.0'
description: 'Check symbolic links and commands, save multiple expected outputs, and avoid misleading test results.'
coverAlt: 'Symbolic-link and command checks, saved expected outputs and corrected results'

aside: false
---

# {{ $frontmatter.title }}

<time>{{ $formatDate($frontmatter.date) }}</time>

Release 0.45.0 adds ways to check symbolic links, pass arguments to command checks, and save multiple expected outputs in one test. It also fixes cases where invalid inputs or missing commands could produce misleading results.

## Check the link itself

A symbolic link is a path that points to another file or directory. Most file checks follow the link and check its target. The new `assert_is_symlink`, `assert_is_not_symlink`, and `assert_symlink_to` check the link itself. They are useful for scripts that keep a link pointing to the current release ([#981](https://github.com/TypedDevs/bashunit/issues/981)).

```bash
function test_current_release_link() {
assert_is_symlink "./current"
assert_symlink_to "./releases/42" "./current"
}
```

## Pass arguments directly to command checks

`assert_true` and `assert_false` now accept a command followed by its arguments. A single argument retains its previous meaning ([#994](https://github.com/TypedDevs/bashunit/issues/994)).

```bash
function test_release_directory() {
assert_true test -d "./releases/42"
assert_false test -d "./releases/missing"
}
```

Both checks now fail when the command is unknown or cannot be executed. A missing command is no longer accepted by `assert_false` as evidence that the intended condition was false; the failure message explains that the command could not run ([#982](https://github.com/TypedDevs/bashunit/issues/982)).

## Keep expected outputs separate and results reliable

Snapshots save expected output for comparison on later runs. Giving each snapshot a name lets a test save more than one expected value. When values differ, bashunit shows the snapshot file path and the `--snapshot-update` hint. Test paths starting from the filesystem root now find snapshots correctly. When Perl is unavailable, the alternative comparison checks the whole value, including any markers for text you chose to ignore ([#986](https://github.com/TypedDevs/bashunit/issues/986), [#1002](https://github.com/TypedDevs/bashunit/issues/1002)).

Input checks are stricter too. Core comparison checks reject missing arguments, date checks reject values they cannot read as dates, and `assert_json_equals` rejects invalid JSON. Runs with tests executing at the same time retain results from same-named test files in different directories.

Several existing checks start fewer extra processes. These include snapshots without ignored-text markers, counters that track command calls, text searches that ignore letter case, and common comparisons that allow a small numeric difference. The single-file executable also omits source comments while keeping text blocks inside shell commands and markers identifying source files. These changes reduce extra work while preserving how the checks behave.

---

See the full changelog for [0.45.0](https://github.com/TypedDevs/bashunit/releases/tag/0.45.0) on GitHub.
50 changes: 50 additions & 0 deletions docs/blog/2026-08-11-release-0-46.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
date: '2026-08-11'
title: 'Release 0.46.0'
description: 'Choose tests, find intermittent failures, and report results and changed-line coverage in automated checks.'
coverAlt: 'Selecting changed tests, finding intermittent failures and reporting changed lines reached by tests'

aside: false
---

# {{ $frontmatter.title }}

<time>{{ $formatDate($frontmatter.date) }}</time>

Release 0.46.0 makes it easier to choose tests, investigate failures that happen only sometimes, and publish results from automated checks. It also fixes reports that could contain zero tests after running tests at the same time.

## Inspect and select a run

`--changed` selects test files Git reports as changed since a chosen commit or branch. It includes changes prepared for a commit, other edits, and new files not yet tracked by Git. It selects changed test files, rather than finding every test affected by a source-code change. Use `--list` to inspect the selected tests without executing them ([#1010](https://github.com/TypedDevs/bashunit/issues/1010), [#1007](https://github.com/TypedDevs/bashunit/issues/1007)).

```bash
bashunit tests/ --changed origin/main --list
bashunit tests/ --list --list-format json
```

Tag expressions can require two tags together with AND or leave out a tag with NOT. Repeating `--tag` still selects tests that match any of those options. `--exclude-filter` excludes matching test names even when another option selected them. `--order-by defects` runs the previous failures first while still running every selected test.

## Find tests that fail only sometimes

`--repeat` runs every selected test several times, reports one combined result, and identifies which repetition failed. Tests that pass only after a retry are now counted separately as flaky, with the first failure included in reports. They still count as passed, so the run can succeed. Use `--fail-on-flaky` to make those results fail the run ([#1013](https://github.com/TypedDevs/bashunit/issues/1013), [#1012](https://github.com/TypedDevs/bashunit/issues/1012)).

```bash
bashunit tests/ --repeat 20 --filter flaky_candidate
bashunit tests/ --retry 2 --fail-on-flaky
```

## Publish useful reports from automated checks

JSON, TAP, HTML, and JUnit file reports now collect results correctly under `--parallel`. JUnit groups tests by file, includes their recorded output, and carries informative failure messages. Markdown summaries can appear in the GitHub Actions step summary. Automatic error notices in Actions point to the failing file and line ([#1004](https://github.com/TypedDevs/bashunit/issues/1004), [#1016](https://github.com/TypedDevs/bashunit/issues/1016)).

Coverage reports which lines the tests reach. It gains the Cobertura XML format used by other automated-check tools. `--coverage-diff` limits the report and minimum-percentage check to changed lines:

```bash
bashunit tests/ --coverage --coverage-diff origin/main --coverage-min 90
```

Preparing coverage reports also avoids starting an extra process to decide whether each source line can run. New checks test whether a number falls within a range and whether a command is available. Invalid numbers and failures from checks you define now receive clearer handling.

---

See the full changelog for [0.46.0](https://github.com/TypedDevs/bashunit/releases/tag/0.46.0) on GitHub.
48 changes: 48 additions & 0 deletions docs/blog/2026-08-13-release-0-47.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
date: '2026-08-13'
title: 'Release 0.47.0'
description: 'Pipe reports to other commands, reuse test settings, catch unexpected commands, and include untested files in coverage.'
coverAlt: 'Reports sent to other commands, reusable test settings and coverage including untested files'

aside: false
---

# {{ $frontmatter.title }}

<time>{{ $formatDate($frontmatter.date) }}</time>

Release 0.47.0 lets you send reports directly to other commands, reuse settings for groups of tests, and control individual tests. Coverage, which reports how much code the tests reach, now includes tracked files that no test ran. Keep that change in mind when comparing percentages after an upgrade.

## Send reports straight to another command

`--output json` and `--output junit` write a report to the normal terminal output, which you can pipe to another command or redirect to a file. You do not need a temporary report file. The existing options that write reports to files remain available alongside them ([#1018](https://github.com/TypedDevs/bashunit/issues/1018)).

```bash
bashunit tests/ --output json | jq '.summary'
bashunit tests/ --output junit > report.xml
```

Named `[suite:<name>]` sections in `.bashunitrc` store paths and options for groups of tests. Use `--suite <name>` to select one group, repeat the option to combine groups, or use `--list-suites` to see available names ([#1021](https://github.com/TypedDevs/bashunit/issues/1021)).

```bash
bashunit --list-suites
bashunit --suite unit
```

## Give each test the settings it needs

The comments `# @timeout`, `# @retry`, and `# @skip` above a test set its time limit, retries, or skipped status. They override settings for the whole run. Invalid values stop the run instead of quietly using another setting. The new helpers for skipping a test under certain conditions both mark it skipped and end it, replacing a separate `return` ([#1020](https://github.com/TypedDevs/bashunit/issues/1020), [#1019](https://github.com/TypedDevs/bashunit/issues/1019)).

`--sandbox` fails a test that runs an external command it did not replace with a test-controlled response, except commands already allowed by default. `--sandbox-allow` adds more allowed commands. To test code that retries, `bashunit::mock_sequence` supplies a different answer on each call and repeats the final answer after all the listed answers have been used ([#1022](https://github.com/TypedDevs/bashunit/issues/1022), [#1023](https://github.com/TypedDevs/bashunit/issues/1023)).

## Include files no test reached

Previously, coverage considered only files a test ran. Now it includes every file under `--coverage-paths`, with untouched files reported at zero coverage. Percentages may drop because the report includes more of the code. Reports limited to changed lines also include changed files that no test ran. A new untested file therefore cannot escape the minimum-percentage check ([#1053](https://github.com/TypedDevs/bashunit/issues/1053), [#1054](https://github.com/TypedDevs/bashunit/issues/1054)).

Fixes to how bashunit reads alternatives in `case` statements and finds where functions begin and end also change coverage details. Preparing the report now uses one call to `awk` per run to identify executable lines and write the output, rather than repeating shell loops and starting processes for each file.

Runs that measure execution time can now save JSON and JUnit reports and compare the middle timing sample, called the median, against a saved reference. `--snapshot-prune` removes unused snapshots, the files holding saved expected output, only after a full run without failures. It prints each deleted path. Runs that select only some tests cannot remove them ([#1029](https://github.com/TypedDevs/bashunit/issues/1029), [#1030](https://github.com/TypedDevs/bashunit/issues/1030)).

---

See the full changelog for [0.47.0](https://github.com/TypedDevs/bashunit/releases/tag/0.47.0) on GitHub.
Loading
Loading