Skip to content

feat(cli): --list / --dry-run to show which tests would run #1007

Description

@Chemaclass

Problem

There is no way to ask bashunit which tests it would run. Every selection mechanism — --filter, --tag, --exclude-tag, --shard i/n, --random-order --seed, --rerun-failed, file::fn, file:LINE — is only observable by actually running the suite.

Consequences today:

  • --shard 1/4 cannot be checked for balance without four full runs.
  • A typo'd --filter silently runs 0 tests and exits 1 with "No tests found" (src/console/summary.sh:128), indistinguishable from a genuinely empty suite.
  • Editor/CI tooling has no machine-readable list of test ids.

bats-core has -c/--count, shellspec has --dry-run and --list examples.

Proposal

--list                    Print the tests that would run, then exit 0
--list-format <fmt>       text (default) | json
--dry-run                 Alias of --list (shellspec-compatible spelling)
  • Honours every selection flag, applied in the same order as a real run, including shard slicing and --random-order --seed ordering.
  • text output: one path/to/file_test.sh::test_function_name per line, followed by N tests on stderr.
  • json output: {"count": N, "tests": [{"file": "...", "function": "...", "name": "human readable", "line": 12, "tags": ["slow"]}]}.
  • No test body is executed, no bootstrap side effects beyond sourcing, no reports are written.
  • Exit code 0 even when the list is empty (this is a query, not a run).

Where to change

  • src/helper/discovery.sh:62 get_functions_to_run and :134 find_total_tests already do the selection work — the list command should reuse them rather than re-implement filtering.
  • src/helper/tags.sh:99 function_matches_tags for the tag column.
  • src/helper/discovery.sh:243 get_function_line_number for the line column.
  • src/main/run.sh — branch before the runner loop.
  • src/helper/naming.sh normalize_test_function_name for the human-readable name.

Acceptance criteria

  • bashunit --list tests/ lists every test, one per line, and exits 0
  • --list respects --filter, --tag, --exclude-tag, --shard, --rerun-failed, file::fn and file:LINE
  • --list --random-order --seed 42 prints the same order that --random-order --seed 42 would execute
  • --list-format json emits valid JSON (verify with jq) including file, function, name, line, tags
  • Data-provider tests are listed once per test function (document the choice in the docs if a provider expands to N cases)
  • No test body runs: a fixture whose test writes a marker file leaves no marker after --list
  • Empty selection prints nothing and exits 0
  • Acceptance test in tests/acceptance/bashunit_list_test.sh

Repo checklist (agent)

  • TDD: RED → GREEN → REFACTOR. Write the failing test first.
  • Bash 3.0+ only: no printf -v, no += append, no declare -A, no [[ ]], no ${var,,}, no &>>, no ${arr[-1]}. Expanding a possibly-empty array under set -u needs ${arr[@]+"${arr[@]}"}.
  • A new CLI flag must be wired in all of these or a parity test fails:
  • Gates: make sa, make lint, ./bashunit tests/, ./bashunit --parallel tests/. Never run shfmt -w.
  • Docs: update docs/command-line.md. Editing docs/assertions.md invalidates the bashunit doc acceptance snapshot — regenerate it.
  • CHANGELOG.md: add one line under ## Unreleased.
  • Fixtures under tests/acceptance/fixtures/ must not end in *test.sh.
  • One issue = one PR.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions