Communitygithub.com

Bashテスト

このスキルは、ユーザーが「bashスクリプトをテスト」「シェルテストを書く」「shunit2を使う」「shellspecを使う」「bashのテストスイートを作成」など、シェルスクリプトの単体テスト、テストフレームワーク、モック、テスト駆動開発について言及した場合に使用します。

Bashテスト とは?

このスキルは、シェルスクリプトのテスト駆動開発を実現するために設計されています。shunit2(xUnit形式)とshellspec(BDD形式)の2つの主要なフレームワークをカバーし、それぞれのインストール方法、基本的なテスト構造、アサーション/マッチャーの使い方、モックの実装方法などを詳細に説明します。また、終了コードのテスト、標準出力/エラー出力のテスト、フィクスチャを使ったテスト、対話的な関数のテストなど、実践的なテストパターンを多数提供します。このスキルは、CI/CDパイプラインや手動テストを補完し、シェルスクリプトの品質と信頼性を向上させます。すべてのコード例、CLIコマンド、およびファイルパスはそのまま保持され、日本語の説明と組み合わされています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/bash-development/skills/bash-testing

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Bashテスト は何をしますか?

シェルスクリプト向けのテストフレームワークとパターン。shunit2とshellspecに焦点を当てています。

フレームワークの選択

フレームワーク強み最適な用途
shunit2xUnit形式、シンプル、ポータブル単体テスト、関数テスト
shellspecBDD形式、モダン、高機能振る舞いスペック、本格的なプロジェクト

shunit2

インストール

# 直接ダウンロード
curl -L https://github.com/kward/shunit2/raw/master/shunit2 -o shunit2

# またはパッケージマネージャー経由
apt install shunit2
brew install shunit2

基本的なテスト構造

#!/usr/bin/env bash

# テスト対象のスクリプトを読み込む
source ./my_script.sh

# テスト関数はtestで始まる
test_addition() {
    result=$(add 2 3)
    assertEquals "2 + 3 は 5 になるはず" "5" "$result"
}

test_string_output() {
    result=$(greet "World")
    assertEquals "Hello, World" "$result"
}

test_file_creation() {
    create_temp_file
    assertTrue "テンポラリファイルが存在するはず" "[ -f /tmp/testfile ]"
}

test_exit_code() {
    validate_input "valid"
    assertEquals "有効な入力に対して0を返すはず" 0 $?
}

# セットアップとティアダウン
oneTimeSetUp() {
    # 全テストの前に一度だけ実行
    export TEST_DIR=$(mktemp -d)
}

oneTimeTearDown() {
    # 全テストの後に一度だけ実行
    rm -rf "$TEST_DIR"
}

setUp() {
    # 各テストの前に実行
    cd "$TEST_DIR"
}

tearDown() {
    # 各テストの後に実行
    rm -f "$TEST_DIR"/*
}

# shunit2を読み込む
source shunit2

shunit2 アサーション

# 等価
assertEquals [メッセージ] 期待値 実際の値
assertNotEquals [メッセージ] 予期しない値 実際の値

# Null/空
assertNull [メッセージ] 値
assertNotNull [メッセージ] 値

# 真偽/ステータス
assertTrue [メッセージ] 条件
assertFalse [メッセージ] 条件

# 同一参照(文字列比較)
assertSame [メッセージ] 期待値 実際の値
assertNotSame [メッセージ] 予期しない値 実際の値

# 包含(文字列内)
assertContains [メッセージ] コンテナ 内容

# 終了ステータス
assertEquals 0 $?

関数の分離テスト

コード例

#!/usr/bin/env bash
# test_my_functions.sh

source ./my_functions.sh

test_calculate_sum_empty() {
    result=$(calculate_sum)
    assertEquals "空の合計は0になるはず" "0" "$result"
}

test_calculate_sum_single() {
    result=$(calculate_sum 5)
    assertEquals "5" "$result"
}

test_calculate_sum_multiple() {
    result=$(calculate_sum 1 2 3 4 5)
    assertEquals "15" "$result"
}

test_validate_email_valid() {
    validate_email "[email protected]"
    assertTrue "有効なメールはパスするはず" $?
}

test_validate_email_invalid() {
    validate_email "not-an-email"
    assertFalse "無効なメールは失敗するはず" $?
}

source shunit2

shellspec

インストール

# curl経由
curl -fsSL https://git.io/shellspec | sh

# Homebrew経由
brew install shellspec

# パッケージマネージャー経由
apt install shellspec

ディレクトリ構造

project/
├── lib/
│   └── functions.sh
├── spec/
│   ├── spec_helper.sh
│   ├── functions_spec.sh
│   └── support/
│       └── fixtures/
└── .shellspec

設定(.shellspec)

--require spec_helper
--format documentation
--color

基本的なスペック構造

コード例

shellspec マッチャー

# 出力マッチャー
The output should eq "完全一致"
The output should include "部分一致"
The output should start with "プレフィックス"
The output should end with "サフィックス"
The output should match pattern "*glob*"
The output should be blank

# ステータスマッチャー
The status should be success    # 終了コード0
The status should be failure    # 終了コード非ゼロ
The status should eq 1          # 特定のコード

# 変数マッチャー
The variable VAR should eq "値"
The variable VAR should be defined
The variable VAR should be undefined

# ファイルマッチャー
The file "パス" should be exist
The file "パス" should be file
The file "パス" should be directory
The file "パス" should be readable

# パスマッチャー
The path "file.txt" should be exist

shellspecでのモック

Describe 'デプロイ関数'
  # 外部コマンドをモック
  curl() {
    echo "モックされた応答"
    return 0
  }

  It 'APIエンドポイントを呼び出す'
    When call deploy "server"
    The output should include "モックされた応答"
  End
End

Describe 'ファイル操作'
  # 関数オーバーライドでモック
  Mock rm
    echo "rm が次の引数で呼び出されました: $*"
  End

  It 'ファイル削除を試みる'
    When call cleanup_temp
    The output should include "rm が次の引数で呼び出されました"
  End
End

スペックヘルパー

# spec/spec_helper.sh

# 共通関数の読み込み
spec_helper_precheck() {
  minimum_version "0.28.0"
}

spec_helper_loaded() {
  # テスト環境のセットアップ
  export TEST_MODE=true
}

spec_helper_configure() {
  # プロジェクトの関数をインポート
  import 'lib/functions.sh'
}

テストパターン

終了コードのテスト

# shunit2
test_success_exit() {
    run_command "valid_input"
    assertEquals 0 $?
}

test_error_exit() {
    run_command "invalid_input"
    assertEquals 1 $?
}

# shellspec
It '成功時に0で終了する'
  When call run_command "valid_input"
  The status should eq 0
End

標準出力と標準エラー出力のテスト

# shunit2
test_stdout() {
    result=$(my_function 2>/dev/null)
    assertEquals "期待される出力" "$result"
}

test_stderr() {
    error=$(my_function 2>&1 >/dev/null)
    assertContains "$error" "エラーメッセージ"
}

# shellspec
It '標準出力に出力する'
  When call my_function
  The stdout should eq "期待される出力"
End

It 'エラーを標準エラー出力に出力する'
  When call my_function
  The stderr should include "エラーメッセージ"
End

フィクスチャを使ったテスト

# テストフィクスチャのセットアップ
setUp() {
    TEST_DIR=$(mktemp -d)
    cat > "$TEST_DIR/config.json" <<EOF
{
    "key": "value"
}
EOF
}

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

test_config_parsing() {
    result=$(parse_config "$TEST_DIR/config.json")
    assertEquals "value" "$result"
}

対話的な関数のテスト

# ヒアドキュメントで入力を提供
test_interactive() {
    result=$(my_prompt <<EOF
yes
EOF
)
    assertEquals "confirmed" "$result"
}

# またはprintfを使用
test_with_input() {
    result=$(printf 'yes\n' | my_prompt)
    assertEquals "confirmed" "$result"
}

テストの実行

# shunit2
./test_script.sh

# shellspec
shellspec                    # すべてのスペックを実行
shellspec spec/file_spec.sh  # 特定のスペックを実行
shellspec --format tap       # TAP形式で出力
shellspec --jobs 4           # 並列実行

ベストプラクティス

  1. 可能な限りテストごとに1つのアサーション
  2. 説明的なテスト名 - 何をテストしているかを説明
  3. テストの分離 - テスト間の依存関係なし
  4. エッジケースのテスト - 空の入力、特殊文字、大きなデータ
  5. tearDownでリソースをクリーンアップ
  6. 外部コマンドをモック - curlをテストするのではなく、自身のロジックをテスト
  7. 出力だけでなく終了コードもテスト

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Jamie-BitFlight/agentskill-kaizen-meta-docs

Agentskill kaizen plugin documentation index. Load when needing to read about cross-platform notes, improvement plans, or DuckDB integration.

Jamie-BitFlight/bash-51-features

Bash 5.1 release features and improvements with practical examples. Use when working with Bash 5.1 features, epoch time variables, redirection enhancements, or when user asks about Bash 5.1 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-52-features

Bash 5.2 release features and improvements with practical examples. Use when working with Bash 5.2 features, variable handling enhancements, readline improvements, or when user asks about Bash 5.2 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-53-features

Bash 5.3 release features and improvements with practical examples. Use when working with Bash 5.3 features, new command substitution, GLOBSORT, loadable builtins, or when user asks about Bash 5.3 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-development

This skill should be used when the user asks to "write a bash script", "create a shell script", "implement bash function", "parse arguments in bash", "handle errors in bash", or mentions bash development, shell scripting, script templates, or modern bash patterns.

Jamie-BitFlight/bash-lint

This skill should be used when the user asks to "lint bash script", "run shellcheck", "format shell script", "use shfmt", "fix shellcheck errors", or mentions shell script linting, formatting, code quality, or pre-commit hooks for bash.

Jamie-BitFlight/bash-logging

This skill should be used when the user asks to "add logging to bash script", "colorize output", "implement log levels", "CI/CD sections", "terminal colors in bash", or mentions logging functions, emoji output, collapsible CI sections, or shlocksmith.

Jamie-BitFlight/bash-portability

This skill should be used when the user asks about "POSIX compatibility", "portable shell scripts", "cross-shell compatibility", "bashisms", "shebang selection", or mentions writing scripts that work on different shells (bash, sh, dash, zsh) or different systems.

Jamie-BitFlight/brainstorming-skill

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or when users request help with ideation, marketing, and strategic planning. Explores user intent, requirements, and design before implementation using research-validated prompt patterns.

Jamie-BitFlight/clang-format

Configure clang-format code formatting. Use when: user mentions clang-format or .clang-format, analyzing code style/patterns, creating/modifying formatting config, troubleshooting formatting, brace styles/indentation/spacing/alignment/pointer alignment, or codifying conventions.

Jamie-BitFlight/commitlint

When setting up commit message validation for a project. When project has commitlint.config.js or .commitlintrc files. When configuring CI/CD to enforce commit format. When extracting commit rules for LLM prompt generation. When debugging commit message rejection errors.

Jamie-BitFlight/conventional-commits

When writing a git commit message. When task completes and changes need committing. When project uses semantic-release, commitizen, git-cliff. When choosing between feat/fix/chore/docs types. When indicating breaking changes. When generating changelogs from commit history.

Jamie-BitFlight/dasel-reference

Use when querying, modifying, or converting JSON, YAML, TOML, XML, CSV, HCL, or INI with dasel v3. Complete reference for selectors, functions, conditionals, variables, spread operator, type casting, and format-specific patterns.

Jamie-BitFlight/data-exploration

Use when exploring unknown structured data files with dasel v3 — discover schema, list keys, find nested values, sample arrays, identify data types across JSON, YAML, TOML, XML, CSV, HCL, INI formats

Jamie-BitFlight/data-transformation

Use when modifying, converting, or transforming structured data with dasel v3 — in-place mutations, format conversion, batch operations, array manipulation, object construction, and merge patterns across JSON, YAML, TOML, XML, CSV, HCL, INI

Jamie-BitFlight/delegate

Decompose substantive work into phases, dispatch each phase to a sub-agent, and adjudicate what comes back. Use whenever a request asks for implementation, investigation, a fix, a review, or any change to files — including small ones — and whenever you are about to read source or run a diagnostic yourself instead of handing it off. Also use when a report from a sub-agent needs judging, when a phase needs re-dispatching, or when a user names one instance of a pattern. Does not apply when your own prompt begins "Your ROLE_TYPE is sub-agent." — then follow references/sub-agent-contract.md instead.

Jamie-BitFlight/enterprise-hibernate-hbm

Dasel v3 query patterns for Hibernate .hbm.xml mapping files — entity-table binding, Java property-to-column extraction, one-to-many set/list/bag relationship tracing, many-to-one foreign key discovery, batch scanning across 60+ HBM files. Use when querying Hibernate ORM class mappings, extracting schema metadata from Java persistence layer, or auditing entity-column relationships in enterprise legacy codebases.

Jamie-BitFlight/enterprise-installanywhere

Dasel v3 query patterns for InstallAnywhere .iap_xml installer definitions — use when querying action sequences, discovering variables, resolving platform conditions, navigating panels, or comparing installer variants. Files are 2.5+ MB, 65,000+ lines — too large for context reads, requires structural dasel queries.

Jamie-BitFlight/enterprise-maven-pom

Dasel v3 selector patterns for Maven POM XML files — use when querying dependency versions, filtering by groupId or scope, extracting module hierarchy from parent POMs, or detecting version conflicts across enterprise multi-module Java projects. Load this skill when working with pom.xml files using dasel.

Jamie-BitFlight/enterprise-spring-xml

Dasel v3 selectors for Spring bean factory XML — use when querying any Spring ApplicationContext XML for bean discovery, dependency wiring, JMS destination mapping, property injection extraction, or cross-bean reference tracing. Load this skill before writing dasel selectors against Spring bean XML files (applicationContext.xml, *_beans.xml, spring-*.xml).

関連スキル