Communitygithub.com

Jamie-BitFlight/bash-testing

이 스킬은 사용자가 'bash 스크립트 테스트', '셸 테스트 작성', 'shunit2 사용', 'shellspec 사용', 'bash 테스트 스위트 생성' 또는 셸 스크립트에 대한 단위 테스트, 테스트 프레임워크, 모킹, 테스트 주도 개발을 언급할 때 사용해야 합니다.

bash-testing란 무엇인가요?

이 스킬은 bash 스크립트를 위한 두 가지 주요 테스트 프레임워크인 shunit2와 shellspec을 중심으로 한 종합적인 테스트 가이드를 제공합니다. shunit2는 xUnit 스타일의 간단하고 이식성이 뛰어난 단위 테스트에 적합하며, shellspec은 BDD 스타일의 현대적이고 광범위한 기능을 갖춘 프로젝트에 적합합니다. 사용자는 기본 테스트 구조, 다양한 어설션(assertion)과 매처(matcher), 함수 격리 테스트, 모킹 기법, 종료 코드 및 표준 출력/오류 테스트, 픽스처(fixture) 설정, 인터랙티브 함수 테스트 등 실제 코드 예제를 통해 학습할 수 있습니다. 또한 각 프레임워크의 설치 방법과 테스트 실행 명령어, 그리고 '한 테스트에 하나의 어설션', '테스트 격리', '모킹 우선' 등의 모범 사례를 제공하여 개발자가 안정적이고 유지보수 가능한 셸 스크립트를 작성할 수 있도록 돕습니다.

지원 대상~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/Empty
assertNull [메시지] 값
assertNotNull [메시지] 값

# Boolean/상태
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

기본 Spec 구조

코드 예제

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    # 종료 0 아님
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 'deploy 함수'
  # 외부 명령 모킹
  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/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

stdout 및 stderr 테스트

# shunit2
test_stdout() {
    result=$(my_function 2>/dev/null)
    assertEquals "예상 출력" "$result"
}

test_stderr() {
    error=$(my_function 2>&1 >/dev/null)
    assertContains "$error" "오류 메시지"
}

# shellspec
It 'stdout으로 출력'
  When call my_function
  The stdout should eq "예상 출력"
End

It 'stderr로 오류 출력'
  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"
}

인터랙티브 함수 테스트

# heredoc으로 입력 제공
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                    # 모든 spec 실행
shellspec spec/file_spec.sh  # 특정 spec 실행
shellspec --format tap       # TAP 출력
shellspec --jobs 4           # 병렬 실행

모범 사례

  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).

관련 스킬