本文へ移動
cccskills
無料GitHub で公開

bats-testing

Configures Bats-core (Bash Automated Testing System) for testing CLI tools, shell scripts, and Unix programs - `.bats` test files with `@test` blocks, `run` to capture command exit + output, `[ "$status" -eq 0 ]` and `[ "$output" = ... ]` assertions, `setup`/`teardown` hooks, `load` for shared helpers, parallel execution via `--jobs N`, TAP-compliant output for CI integration. Use whenever the unit-under-test is a shell script, CLI binary, or anything invokable from Bash.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qaスター 13(GitHub 13 + cccskills 0)
連携ツールDocker

実行スコア 未検証

インストール方法を見る

含まれるファイル(3)

  • SKILL.md9.6 KB
  • .tessl-plugin/plugin.json608 B
  • references/ci-integration.md1.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

bats-testing

Overview

Per bats-readthedocs:

"Bats (Bash Automated Testing System) is a TAP-compliant testing framework for Bash 3.2 or above."

Per bats-github:

"Bats is a TAP-compliant testing framework for Bash 3.2 or above. It provides a simple way to verify that the UNIX programs you write behave as expected."

Bats works "with any Unix program," not just Bash - it captures stdout / stderr / exit code of any executable.

When to use

  • Testing a shell script (deployment scripts, CI scripts, installers).
  • Testing a CLI binary's interface (commands, flags, exit codes, output) at the integration layer.
  • Validating that wrapper scripts (e.g., kubectl plugins, git aliases) behave as expected.
  • Cross-platform smoke tests for a CLI's install scripts.

How to use

  1. Install bats (npm / Homebrew / git submodule); pin via submodule for CI determinism (Step 1).
  2. Create test/<feature>.bats starting with #!/usr/bin/env bats and one @test block per behavior (Step 2).
  3. Wrap each command under test with run, then assert on $status, $output, and $lines[] (Step 3).
  4. Add setup / teardown with mktemp -d so each test is isolated and parallel-safe (Step 4).
  5. load shared helpers plus bats-support / bats-assert for diff-style assertions (Steps 5-6).
  6. Guard environment-specific tests with skip; run the suite via bats test/, adding --jobs N for parallelism (Steps 7-8).
  7. Wire it into CI with TAP or JUnit output (references/ci-integration.md).

Step 1 - Install

Per bgh:

# npm
npm install -g bats

# Homebrew
brew install bats-core

# Git submodule (vendored, deterministic for CI)
git submodule add https://github.com/bats-core/bats-core.git test/bats
git submodule add https://github.com/bats-core/bats-support.git test/test_helper/bats-support
git submodule add https://github.com/bats-core/bats-assert.git test/test_helper/bats-assert

The git-submodule approach pins the Bats version per repo - recommended for CI determinism.

Step 2 - First test file

Per bgh (verbatim example):

#!/usr/bin/env bats

@test "addition using bc" {
  result="$(echo 2+2 | bc)"
  [ "$result" -eq 4 ]
}

@test "addition using dc" {
  result="$(echo 2 2+p | dc)"
  [ "$result" -eq 4 ]
}

Save as test/math.bats; run bats test/math.bats.

Step 3 - run for exit-code + output capture

The run helper invokes a command and captures $status, $output, and $lines[]:

@test "myscript --help exits 0 and mentions usage" {
  run ./myscript --help
  [ "$status" -eq 0 ]
  [[ "$output" == *"Usage:"* ]]
}

@test "myscript with no args exits 1" {
  run ./myscript
  [ "$status" -eq 1 ]
  [ "$output" = "error: missing required argument" ]
}

@test "myscript output line count" {
  run ./myscript list
  [ "$status" -eq 0 ]
  [ "${#lines[@]}" -eq 3 ]
  [ "${lines[0]}" = "alice" ]
}

Without run, a non-zero exit code aborts the test before assertions execute.

Step 4 - setup / teardown

Per bats: "setup and teardown: Pre- and post-test hooks."

setup() {
  TEST_DIR="$(mktemp -d)"
  cp fixtures/sample.txt "$TEST_DIR/"
}

teardown() {
  rm -rf "$TEST_DIR"
}

@test "myscript processes the sample file" {
  run ./myscript "$TEST_DIR/sample.txt"
  [ "$status" -eq 0 ]
}

setup_file / teardown_file run once per file (vs once per test). Use for expensive setup (Docker container start, database init).

Step 5 - load shared helpers

Per bats: "load: Share common code."

# test/test_helper.bash
make_temp_repo() {
  local d
  d="$(mktemp -d)"
  (cd "$d" && git init -q)
  echo "$d"
}
# test/integration.bats
load test_helper

@test "git status in fresh repo is clean" {
  local d
  d="$(make_temp_repo)"
  cd "$d"
  run git status --porcelain
  [ "$status" -eq 0 ]
  [ -z "$output" ]
}

Step 6 - bats-assert / bats-support

Better assertions than raw [ ]:

load test_helper/bats-support/load
load test_helper/bats-assert/load

@test "myscript produces expected JSON" {
  run ./myscript --json
  assert_success
  assert_output --partial '"version":'
  refute_output --partial 'ERROR'
}

@test "myscript fails on bad input" {
  run ./myscript --bad-flag
  assert_failure 2
  assert_line --index 0 "Unknown flag: --bad-flag"
}

assert_success / assert_failure / assert_output / assert_line give clear diff-style failure messages (vs [ ]'s silent fail).

Step 7 - skip

Per bats: "skip: Easily skip tests."

@test "macOS-only behavior" {
  if [[ "$(uname -s)" != "Darwin" ]]; then
    skip "macOS-only test"
  fi
  run ./myscript --use-keychain
  [ "$status" -eq 0 ]
}

@test "needs docker daemon" {
  if ! command -v docker >/dev/null; then
    skip "docker not installed"
  fi
  if ! docker info >/dev/null 2>&1; then
    skip "docker daemon not running"
  fi
  run ./deploy-script --dry-run
  [ "$status" -eq 0 ]
}

skip reports the reason in test output (vs commenting out, which hides the fact that coverage dropped).

Step 8 - Parallel execution

Per bats: "Parallel Execution."

# Install GNU parallel first (apt install parallel / brew install parallel)
bats --jobs 4 test/

Tests must be independent - share no global filesystem state, no shared ports. Use setup/teardown with mktemp -d to isolate.

Step 9 - Output formats and CI

bats emits pretty output by default, TAP or JUnit XML for CI, and runs in the official bats/bats Docker image. The output-format flags, a GitHub Actions job, and the Docker one-liner are in references/ci-integration.md.

Worked example

You maintain release.sh, a shell script that prints usage on --help and exits non-zero when called with no arguments. Cover both paths with Bats:

  1. Vendor Bats as a submodule (Step 1), then create test/release.bats:

    #!/usr/bin/env bats
    
    load test_helper/bats-support/load
    load test_helper/bats-assert/load
    
    @test "release.sh --help exits 0 and prints usage" {
      run ./release.sh --help
      assert_success
      assert_output --partial "Usage:"
    }
    
    @test "release.sh with no args exits non-zero" {
      run ./release.sh
      assert_failure
      assert_output --partial "missing required argument"
    }
    
  2. Run it: bats test/release.bats. Bats reports:

    release.bats
     ✓ release.sh --help exits 0 and prints usage
     ✓ release.sh with no args exits non-zero
    
    2 tests, 0 failures
    
  3. In CI, swap to bats --formatter junit test/ > junit.xml and upload the report (see references/ci-integration.md).

Anti-patterns

Anti-patternWhy it failsFix
Calling commands directly without runNon-zero exit aborts the test before any assertion runs.Wrap with run; check $status.
Tests sharing /tmp / fixed portsParallel execution breaks intermittently.Per-test mktemp -d in setup (Step 4).
Using [ ] for everythingSilent failures; no diff message.bats-assert (Step 6).
Commenting out skipped testsHides coverage loss; no signal.skip with reason (Step 7).
Asserting full multiline outputBrittle - any whitespace change breaks tests.Use assert_output --partial or assert_line --index N.
One mega .bats fileSlow; hard to grep failures.Per-feature files in test/.

Limitations

  • Bash-only. Tests are written in Bash; PowerShell scripts need Pester instead.
  • Slow vs in-language tests. Each run forks a process - expensive vs library-level tests in the language.
  • Output capture quirks. run strips trailing newlines; some binary output is not faithfully captured.
  • Windows requires WSL or Git Bash. Per bats: "Installing Bats from source via Git Bash."

References

  • bats - overview, install methods, test structure, @test / run / setup / teardown / load / skip, parallel execution, Docker.
  • bgh - example test file, install one-liners.
  • references/ci-integration.md - output formats, GitHub Actions job, Docker image.
  • tui-snapshot-tester - TUI snapshot tests (visual layer; bats covers exit code + text output).
  • cli-output-conventions - what to assert on (stable formats, exit codes, stderr).

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

testland のスキルをすべて見る

このスキルの問題を報告する