test-script
Utility for creating and maintaining txtar-based test scripts for git workflows.
Install
mkdir -p .claude/skills/test-script && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3576" && unzip -o skill.zip -d .claude/skills/test-script && rm skill.zipInstalls to .claude/skills/test-script
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when writing or modifying .txt test scripts in testdata/script/ for git-spice - covers txtar format, end-to-end testing, ShamHub forge simulation, interactive prompts, and golden file comparisons for branch operations and stack workflows.Key capabilities
- →Write end-to-end test scripts
- →Simulate forge interactions
- →Compare golden files
- →Test interactive prompts
- →Verify git-spice commands
How it works
The skill uses the txtar format to define repository states and command expectations, running them against the git-spice CLI in a controlled environment.
Inputs & outputs
When to use test-script
- →Writing end-to-end branch test scripts
- →Configuring ShamHub forge simulations
- →Creating golden file comparisons
- →Maintaining git-spice testdata
About this skill
Test Scripts
Overview
Write test scripts for git-spice commands as .txt files in txtar format.
Test scripts verify end-to-end behavior and are stored in testdata/script/.
Quick Reference
| Task | Command/Pattern |
|---|---|
| Run specific test | mise run test:script --run $name |
| Update golden files | mise run test:script --run $name --update |
| Create branch | gs branch create <name> -m <msg> |
| Make commit | gs commit create -m <msg> |
| Compare stdout | cmp stdout $WORK/golden/file.txt |
| Partial match | stdout 'expected substring' for non-JSON text only |
| Check file exists | exists filename |
| Compare with env vars | cmpenv stdout $WORK/golden/file.txt |
| Test interactive | env ROBOT_INPUT=$WORK/robot.golden ROBOT_OUTPUT=$WORK/robot.actual |
Common Mistakes
Avoid these errors when writing test scripts:
-
❌ Using shell operations: Test scripts don't support
>,>>,2>,|, or command substitution. Usecmp stdout,cmp stderr,stdout, andstderrinstead. -
❌ Using
catorls: Useexists filenameto check existence,cmp have_file want_fileto compare contents. -
❌ Forgetting
asandat: Always freeze time and author for deterministic Git hashes. -
❌ Using
git checkout -b: Usegs branch createinstead (unless testing non-git-spice scenarios). -
❌ Empty golden files with
(empty): Just leave content blank after-- path --. -
❌ String matching JSON output: Use
cmpenvJSONfor ShamHub JSON dumps and other JSON outputs. Do not usestdoutorstderrsubstring assertions on JSON.
Writing a test script
Test scripts are plain text files with a series of commands. Most test scripts follow this general structure:
# Brief description of what the test does.
# Wrap comments at 80 characters.
as 'Test <[email protected]>'
at '2025-10-18T21:28:29Z'
# Setup
cd repo
git init
git commit --allow-empty -m 'Initial commit'
gs repo init
# (Optional) ShamHub setup for forge interactions
shamhub-setup
shamhub register alice
shamhub new origin alice/example.git
git push origin main
# Login as user
env SHAMHUB_USERNAME=alice
gs auth login
# ...
some command
cmp stdout $WORK/golden/output.txt
-- repo/file.txt --
file inside repo
-- repo/path/to/another-file.txt --
another file inside repo
-- extra/supporting-file.txt --
supporting file outside repo.
may be copied into repo during test.
-- golden/output.txt --
expected output for comparison
Notes:
-
Deterministic Git hashes
To get Git SHAs that are consistent across test runs, always freeze time and author at the start of the script using the
atandascommands.as 'Test <[email protected]>' at '2025-10-18T21:28:29Z'The
atshould always use the current time at the moment of writing the test script. -
Repository initialization
Initialize the Git repository and git-spice within it:
cd repo git init git commit --allow-empty -m 'Initial commit' gs repo init -
ShamHub setup
For tests involving forge interactions, we use a simulation server called ShamHub. To set it up, use
shamhub-setup, then useshamhubcommands to create users and repositories:shamhub-setup shamhub register alice shamhub new origin alice/example.git git push origin main env SHAMHUB_USERNAME=alice gs auth login
Following setup, use git-spice via gs commands to perform actions.
Test script style
-
Naming
Follow the convention:
<command>_<scenario>.txtWhere<command>is the git-spice command being tested insnake_case, and<scenario>describes the specific test case. Examples:repo_sync_conflict.txtstack_submit_with_labels.txt
If the test script is a regression test for a specific issue, include the issue number in the name:
issue123_stack_rebase_does_not_do_a_thing.txt
-
Comments
Use comments (
#) to explain the purpose of each step. Wrap comments at 80 characters for readability.If the test script is a regression test for a specific issue, include a comment with the issue link at the top.
Common tasks
Creating branches
gs branch create <branch-name> -m <commit-msg>
This will create a new branch and commit all staged changes to it with the given commit message.
See gs branch create --help for more options.
Never use manual git checkout -b
unless specifically testing a non-git-spice branch creation scenario.
Making commits
gs commit create -m <commit-msg>
This will commit all staged changes to the current branch with the given commit message.
See gs commit create --help for more options.
Supporting files
Files needed by test scripts are defined
at the end of the script using -- path/to/file -- syntax.
For each such section,
everything after the -- path/to/file -- line
until the next -- path/to/another/file -- line, or the end of the file,
is treated as the contents of that file.
-- repo/feature.txt --
Initial content of feature.txt
-- extra/feature-new.txt --
Updated content of feature.txt
-- golden/output.txt --
Expected output of the command
Using golden files
If the expected output of any command is stored in a supporting file,
put it inside a golden/ subdirectory in the test script,
and refer to it using $WORK/golden/filename.
Tip:
For outputs that we do not control (e.g. git commit hashes),
save time by putting placeholder values in the golden files,
then run the test script with the --update flag to auto-update them.
(This only works for cmp comparisons, not cmpenv or cmpenvJSON.)
Verifying git state
-
View git graph:
git graph --branches cmp stdout $WORK/golden/graph.txt -
View git status:
git status --porcelain cmp stdout $WORK/golden/status.txt -
Verify git-spice branch relationships:
gs ls cmp stderr $WORK/golden/ls.txt -
Verify git-spice branch and commit details:
gs ll cmp stderr $WORK/golden/ll.txt
Verifying command output
-
Matching entire stdout
run some command cmp stdout $WORK/golden/output.txt -
Matching stdout partially
run some command stdout 'expected output substring' -
Matching entire stderr
run some command cmp stderr $WORK/golden/error.txt -
Matching stderr partially
run some command stderr 'expected error message substring' -
Comparing with environment variable substitutions
run some command cmpenv stdout $WORK/golden/output.txt cmpenv stderr $WORK/golden/error.txt(
$FOOplaceholders in the golden file will be replaced with their actual values from the test environment.) -
Comparing JSON output with environment variable substitutions
run some command --json cmpenvJSON stdout $WORK/golden/output.json(
$FOOplaceholders in the golden JSON file will be replaced with their actual values from the test environment.)For ShamHub JSON dump fixtures, start with a plain
cmpassertion, run the script with--update, and then replace volatile ShamHub URLs such ashttp://127.0.0.1:<port>with$SHAMHUB_URLin the generated golden file. After that, change the assertion tocmpenvJSON.
Testing Interactive Prompts
For commands with interactive prompts,
-
Declare a golden fixture file with pre-defined answers for each expected prompt. These are JSON-encoded answers separated by
===lines, with>comments that contain the rendered prompt text.-- robot.golden -- > Enter your name: "Alice" === > Choose an option: > 1) Option A > 2) Option B 2 -
Before invoking the interactive command, set the
ROBOT_INPUTenvironment variable to point to the fixture file, andROBOT_OUTPUTto capture rendered prompts.env ROBOT_INPUT=$WORK/robot.golden ROBOT_OUTPUT=$WORK/robot.actual -
Run the command that prompts for input.
gs some interactive command -
After the command completes, compare the captured output file with the golden fixture file.
cmp $WORK/robot.actual $WORK/robot.golden(Use
cmpenvif environment variable substitutions are needed.)
Testing opening browser URLs
For commands that open browser URLs,
set BROWSER_RECORDER_FILE to a file path
that will capture the URLs that were requested to be opened.
env BROWSER_RECORDER_FILE=$WORK/browser.log
gs branch submit --web
Verify the recorded URLs against the golden copy:
cmpenv $WORK/browser.log $WORK/golden/browser.log
Running test scripts
-
Run a specific test script:
mise run test:script --run $nameWhere
$nameis the script name without.txtextension. For example, to runtestdata/script/repo_sync_conflict.txt:mise run test:script --run repo_sync_conflict -
Auto-update golden files:
If a test script fails because the expected output has changed intentionally, use the
--updateflag to update golden files:mise run test:script --run $name --updateNote: This only works for
cmpcomparisons.cmpenvandcmpenvJSONdo not support--updatemode.
ShamHub
ShamHub is a simulated forge server (e.g., GitHub/GitLab) used for testing git-spice's forge interactions.
Outside of using git-spice (gs) commands,
ShamHub interactions are available through the shamhub command
defined at internal/forge/shamhub/cli_main.go.
Common shamhub commands:
shamhub-setup: Initialize the ShamHub server and set environment variables.shamhub register <username>: Register user
Content truncated.
When not to use it
- →Testing non-git-spice scenarios
- →General shell scripting tasks
Prerequisites
Limitations
- →Does not support standard shell operators like pipes or redirection
- →Requires specific naming conventions
How it compares
It uses a specialized, deterministic testing framework for git-spice rather than standard shell-based integration tests.
Compared to similar skills
test-script side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| test-script (this skill) | 2 | 1mo | Review | Advanced |
| dependency-upgrade | 26 | 5mo | Review | Intermediate |
| testing-workflow | 16 | 9mo | Review | Intermediate |
| finishing-a-development-branch | 4 | 3mo | Review | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
dependency-upgrade
wshobson
Manage major dependency version upgrades with compatibility analysis, staged rollout, and comprehensive testing. Use when upgrading framework versions, updating major dependencies, or managing breaking changes in libraries.
testing-workflow
amo-tech-ai
Comprehensive testing workflow for E2E, integration, and unit tests. Use when testing applications layer-by-layer, validating user journeys, or running test suites.
finishing-a-development-branch
obra
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
dev
atopile
LLM-focused workflow for working in this repo: compile Zig, run the orchestrated test runner, consume test-report.json/html artifacts, and discover/debug ConfigFlags.
positron-pr-helper
posit-dev
Generates well-structured PR bodies with dynamically fetched e2e test tags
overnight-development
jeremylongshore
Automates software development overnight using git hooks to enforce test-driven Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.