shell-tdd

Shell-based TDD test harness patterns — pass/fail counters, common assertions, set -e gotchas, and exit code conventions for bash test scripts

5 stars

Best use case

shell-tdd is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Shell-based TDD test harness patterns — pass/fail counters, common assertions, set -e gotchas, and exit code conventions for bash test scripts

Teams using shell-tdd should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/shell-tdd/SKILL.md --create-dirs "https://raw.githubusercontent.com/vamseeachanta/workspace-hub/main/.agents/skills/development/shell-tdd/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/shell-tdd/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How shell-tdd Compares

Feature / Agentshell-tddStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Shell-based TDD test harness patterns — pass/fail counters, common assertions, set -e gotchas, and exit code conventions for bash test scripts

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Shell TDD Test Harness

## Quick Start

Shell TDD scripts follow a simple pattern: counter functions, if-block assertions,
and `exit $FAIL` for CI integration. The critical rule is **never use `(( var++ ))`
with `set -e`** — use `var=$((var + 1))` instead.

## Template

```bash
#!/usr/bin/env bash
set -euo pipefail

REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)"
PASS=0
FAIL=0

pass() { PASS=$((PASS + 1)); echo "  PASS: $1"; }
fail() { FAIL=$((FAIL + 1)); echo "  FAIL: $1"; }

echo "=== Suite: <name> ==="

# --- AC1: <description> ---
echo ""
echo "--- AC1: <description> ---"

if <check>; then
    pass "<what passed>"
else
    fail "<what failed>"
fi

# --- Summary ---
echo ""
echo "=== Results: $PASS passed, $FAIL failed ==="
exit $FAIL
```

## Common Assertions

```bash
# File exists
if [ -f "$path" ]; then pass "file exists"; else fail "file missing"; fi

# Directory exists
if [ -d "$path" ]; then pass "dir exists"; else fail "dir missing"; fi

# File contains text
if grep -q "pattern" "$file"; then pass "pattern found"; else fail "pattern missing"; fi

# Git ignores file
if git check-ignore -q "$path"; then pass "ignored"; else fail "not ignored"; fi

# Command succeeds
if command_here; then pass "command ok"; else fail "command failed"; fi

# Command output matches expected value
if [ "$(command)" = "expected" ]; then pass "output matches"; else fail "output mismatch"; fi

# File is not empty
if [ -s "$path" ]; then pass "file has content"; else fail "file empty"; fi

# String variable is non-empty
if [ -n "$var" ]; then pass "var set"; else fail "var empty"; fi
```

## Gotchas

### 1. Counter increment with `set -e` (CRITICAL)

```bash
# BROKEN — exits script when PASS=0 because (( 0 )) returns exit code 1
(( PASS++ ))

# CORRECT — arithmetic substitution always succeeds
PASS=$((PASS + 1))
```

Why: `(( expr ))` returns exit code 1 when the expression evaluates to 0.
When `PASS=0`, `(( PASS++ ))` evaluates `0` (the pre-increment value), which is
falsy, so `set -e` kills the script on the very first pass.

### 2. `set -e` and conditionals

`set -e` does **not** exit when a failing command is inside an `if` condition,
`while` condition, or the left side of `&&`/`||`. Always wrap checks that might
fail in `if` blocks rather than running them bare.

```bash
# BROKEN — exits script if grep finds nothing
grep -q "pattern" "$file"

# CORRECT — if block suppresses set -e for the condition
if grep -q "pattern" "$file"; then pass "found"; else fail "missing"; fi
```

### 3. `set -u` and optional variables

Use `${var:-default}` for variables that may be unset. Bare `$var` with `set -u`
exits immediately if `var` is not defined.

### 4. `set -o pipefail` and pipes

The pipe exit code is the rightmost non-zero exit. A `grep | head` where grep
finds nothing will fail the whole pipe. Wrap in `if` when failure is expected.

## Exit Code Convention

`exit $FAIL` — zero means all tests passed, non-zero equals the failure count.
This integrates directly with CI: any non-zero exit fails the build.

Related Skills

github-actions-trigger-and-shell-gotchas

5
from vamseeachanta/workspace-hub

Prevent false verification gaps in GitHub Actions by checking push path filters, shell compatibility, and shared CI environment failures before concluding a workflow fix worked or failed.

shell-script-hardening-patterns

5
from vamseeachanta/workspace-hub

Harden Bash automation scripts with TDD-first static and behavioral checks, safe Python invocation via uv, locking, persistent state, and review-driven correction loops.

cli-productivity-8-shell-aliases-and-functions

5
from vamseeachanta/workspace-hub

Sub-skill of cli-productivity: 8. Shell Aliases and Functions.

cli-productivity-1-complete-shell-configuration

5
from vamseeachanta/workspace-hub

Sub-skill of cli-productivity: 1. Complete Shell Configuration (+1).

test-oversized-skill

5
from vamseeachanta/workspace-hub

A test fixture skill that exceeds 200 lines with multiple H2/H3 sections for split testing.

interactive-report-generator

5
from vamseeachanta/workspace-hub

Generate interactive HTML reports with Plotly visualizations from data analysis results. Supports dashboards, charts, and professional styling.

data-validation-reporter

5
from vamseeachanta/workspace-hub

Generate interactive validation reports with quality scoring, missing data analysis, and type checking. Combines Pandas validation, Plotly visualization, and YAML configuration for comprehensive data quality reporting.

agent-os-framework

5
from vamseeachanta/workspace-hub

Generate standardized .agent-os directory structure with product documentation, mission, tech-stack, roadmap, and decision records. Enables AI-native workflows.

OrcaFlex Specialist Skill

5
from vamseeachanta/workspace-hub

```yaml

repo-ecosystem-hygiene

5
from vamseeachanta/workspace-hub

Interpret the daily read-only repo ecosystem hygiene audit and route remediation through approved workflows.

domain-knowledge-sweep

5
from vamseeachanta/workspace-hub

Systematic multi-source research of an engineering domain. Spawns parent issue → 6 research subissues (Standards, Academic, Industry, LinkedIn-marketing, Code-audit, Synthesis) → gap implementation subissues. Replaces LinkedIn-only extraction with defensible comprehensive sourcing.

subagent-write-verification

5
from vamseeachanta/workspace-hub

Independently verify subagent-claimed file writes with filesystem and git checks before treating the artifact as real, before committing it, and before referencing the path in downstream prompts.