✨ Improvements
--changed [<ref>]runs only the test files git reports as touched since<ref>(defaultorigin/HEAD, thenHEAD), covering committed, staged, unstaged and untracked changes (#1010)--order-by <defined|defects|random>picks the execution order;defectsruns the last run's failures first and still runs the whole suite (#1011)--list(alias--dry-run) prints the tests a run would execute without running them;--list-format jsonemits file, function, name, line and tags, honouring every selection flag including--shard(#1007)--exclude-filter <name>skips tests by name, the counterpart of--exclude-tag: repeatable, OR'd, and wins over--filter(#1009)--tagaccepts expressions:'a&&b'(AND),'!a'(NOT) and'a&&!b'; repeated--tagflags keep OR semantics and--exclude-tagstill wins (#1008)# @tags a babove any top-level line tags every test in the file, unioned with per-function# @tag(#1008)--repeat <n>runs each selected test n times to hunt flakiness before CI does: one report line with the aggregate outcome, a failure names its iteration, and repeat wraps--retry(#1013)- Flaky is a first-class outcome: a test that only passed after a retry is counted separately, stays inside the pass total so the exit code is unchanged, and is carried into JUnit (
<flakyFailure>), TAP, JSON, HTML and GitHub Actions with the first attempt's failure message;--fail-on-flakyturns such a run red (#1012) --coverage-report-cobertura [file]writes Cobertura XML (defaultcoverage/cobertura.xml), the format GitLab merge-request visualisation, Azure DevOps and Jenkins consume, with repo-relative filenames, per-line hits andcondition-coverageon branch lines, alongside the LCOV and HTML reports (#1017)--coverage-diff <ref>limits the coverage console report to lines changed since a base ref;--coverage-minthen gates on that diff percentage (#1032)--report-md <file>writes a Markdown run summary — verdict, counts table, failures with their message, plus coverage and slowest tests when those ran — and inside GitHub Actions appends it to$GITHUB_STEP_SUMMARY(#1015)- GitHub Actions annotations print to stdout automatically inside Actions, carrying the failing test's file and line so they land on the right line of the diff;
--gha-annotations <auto|always|never>overrides the detection andaction.ymlgains anannotationsinput (#1014) assert_between <min> <max> <actual>andassert_not_betweenadd inclusive numeric-range assertions for integers and decimals (#1026)assert_command_available <command>asserts a command, shell builtin or function resolves throughcommand -v(#1027)--verbosereports the coverage engine in use, and an explicitBASHUNIT_COVERAGE_ENGINE=xtracethe running Bash cannot honour now warns instead of being silently ignored (#1005)
🛠️ Changes
- JUnit XML: one
<testsuite>per test file with its own counts, time and timestamp instead of a single flat suite,classnameon every<testcase>,<failure message="...">carrying the first informative line of the real message withtype="AssertionFailed",<system-out>with the test's captured output, and aggregate totals on<testsuites>, so consumers that group by suite or classname (Jenkins, GitLab, dorny/test-reporter) get real groupings (#1016) - Performance:
--coverageis about 1.6x to 2.3x faster; executable-line classification no longer forksgrepper source line, roughly half of a coverage run's wall time on both engines (#1005) bashunit test --helplists--show-skippedand--show-incomplete, both accepted by the parser but never advertised;BASHUNIT_COVERAGE_SHOW_FUNCTIONSandBASHUNIT_COVERAGE_SHOW_UNCOVEREDare registered insrc/config/env.shlike every other setting, and.env.examplenow lists all 66 settings, 19 of which were missing (#1063)- Docs: full audit of the reference pages against the code —
docs/configuration.mdgained the 17 settings it never documented,docs/command-line.mdgained theassertsubcommand section and real example output, and the coverage settings and diff-coverage narrative now live in one place instead of two that had drifted (#1063)
🐛 Bug Fixes
- Report formats are no longer empty under
--parallel;--report-junit,--report-tap,--report-json,--report-htmland--log-junitall recorded zero tests, because the rows were collected inside the per-test worker and nothing rebuilt them in the parent (#1004) - A failed assertion is no longer reported twice:
bashunit::assert_thatreturns 1 on failure by design, so a custom assertion ending with it made the test body exit non-zero and the runner printed a spurious✗ Erroron top of the✗ Failed. Custom assertions no longer need a trailingreturn 0, and a real runtime error is still reported as an error (#1063) --coverage-reportwith no value usescoverage/lcov.infoinstead of aborting the run with$2: unbound variable, and no longer consumes a following flag as its filename; write the test path before it, since an optional value cannot be told apart from a path (#1063)--list --list-format jsonreports each tag as its own array element; the emitter split the tag list on whitespace while every other consumer splits it on commas, so two tags rendered as["slow,fileTag"](#1063)assert_within_deltarejects malformed numbers such as1.2.3or5-3as non-numeric instead of leaking a rawbcparse error or evaluating them as an expression (#1026)- Build: the standalone binary size budget is 544 KiB, raised from 500 KiB after ordinary feature growth crossed it; the artifact keeps its indentation rather than being minified (#1045)
👥 Contributors
Checksum
SHA256: c49fd3874c7df68170f6a22d76599031113f2bb8a5a3bca664fa056dc214e85f
Full Changelog: 0.45.0...0.46.0