Shellkin is a Gherkin-style test framework for Bash scripts.
It lets you write feature files such as:
Feature: --help
Show help message
Scenario: Run --help
When I run 'shellkin --help'
Then the output should include 'shellkin COMMAND'and back them with shell step definitions:
@When I run '{command}'
run "$command"
@Then the output should include '{text}'
[[ "$LAST_STDOUT" == *"$text"* ]]This setup script will download the latest shellkin release executable as well as the man pages.
$ curl -Ls get.dannyb.co/shellkin/setup | bashFeel free to inspect the setup script before running.
Download the shellkin bash script from the
latest release, place
it in your path and make it executable.
# download the latest release and place it in /usr/local/bin
wget https://get.dannyb.co/shellkin
sudo install -m 0755 shellkin /usr/local/bin/Shellkin is currently usable for local feature testing and dogfoods itself
through the repository features/ directory.
Implemented pieces include:
- feature discovery from a directory or a single
.featurefile - optional support script loading from
support.sh - step definition loading from
step_definitions/*.shand*.bash - step matching with
{token}placeholders Background,Scenario,Given/When/Then,And/But, and*- doc strings via Gherkin-style
"""blocks exposed asDOC_STRING - colored terminal output and scenario summary
| Feature | Status |
|---|---|
Feature |
Supported |
| Feature description text | Supported |
Scenario |
Supported |
Background |
Supported |
Given, When, Then |
Supported |
And , But |
Supported |
* step keyword |
Supported |
Doc strings (""") |
Supported |
Comments (#) |
Supported |
Rule |
Unsupported |
Scenario Outline |
Unsupported |
Examples |
Unsupported |
| Data tables | Unsupported |
Tags (@tag) |
Unsupported |
# Run all repo features:
shellkin test
# Validate feature and step definition files without executing steps:
shellkin validate
# Stop after the first failing scenario:
shellkin test --fail-fast
# Run a specific directory:
shellkin test path/to/features
# Run a single feature file:
shellkin test path/to/features/example.featureWhen a step fails, the remaining steps in that scenario are marked as skipped and are not executed.
Use shellkin validate to check feature structure and step-definition matching
without running any step bodies.
This repository also provides a Codex skill for AI agents that need to write Shellkin tests in user projects.
Use the built-in installer skill.
In Codex chat, use this prompt:
install the skill from https://github.com/DannyBen/shellkin/tree/main/skills/shellkin
(master branch)
Claude Code supports project and user skill locations:
- Project skill:
.claude/skills/shellkin/SKILL.md - User skill:
~/.claude/skills/shellkin/SKILL.md
Copy skills/shellkin from this repo into one of those locations.
Shellkin expects this structure:
features/
├── support.sh
├── step_definitions/
│ └── core.sh
└── example.feature
- Feature files live in the target directory.
- If present,
support.shis sourced before step definitions are loaded. - Step definitions live in
step_definitions/under that same directory. - Set
SHELLKIN_SUPPORT_FILEto change the support script name relative to the features directory.
Step definitions are shell snippets declared in files under
step_definitions/.
To share helper functions across step definition files, place them in
support.sh in the features directory. Shellkin sources this file before it
loads step definitions. You can rename it with SHELLKIN_SUPPORT_FILE.
@When I run '{command}'
run "$command"
@Then the output should include '{text}'
[[ "$LAST_STDOUT" == *"$text"* ]]Each step definition starts with a header line:
@Given ...
@When ...
@Then ...
The lines that follow are the step body and are executed when the step matches.
Definition headers can use named tokens in braces. When a step matches, each token becomes an exported shell variable available to the body:
@Then the file '{path}' should exist
[[ -f "$path" ]]Token names must start with a letter or underscore, and may contain letters, numbers, and underscores.
Each definition continues until the next step header or the end of the file.
Shellkin currently provides these built-in helpers for step definitions:
Use run to execute a shell command while capturing its result for later
assertions.
@When I run '{command}'
run "$command"run always returns success, even if the command fails. Inspect the captured
result through the environment variables described below.
Use fail to fail the current step with an optional custom message.
@Then the output should include '{text}'
[[ "$LAST_STDOUT" == *"$text"* ]] || fail "invalid output detected"Use defer to register cleanup code that should run when the current scenario
finishes.
@Given I am in a temp directory
old_pwd=$PWD
temp_dir=$(mktemp -d)
cd "$temp_dir"
defer cd "$old_pwd"
defer rm -rf "$temp_dir"Deferred actions are scenario-scoped, run after both passing and failing scenarios, and execute in reverse order of registration.
Shellkin exposes these variables to step definition bodies:
| Variable | Meaning |
|---|---|
LAST_EXIT_CODE |
Exit status captured by the most recent run call |
LAST_STDOUT |
Standard output captured by the most recent run call |
LAST_STDERR |
Standard error captured by the most recent run call |
DOC_STRING |
Doc string attached to the current step, if any |
Example:
@Then the output should match
[[ "$LAST_STDOUT" == "$DOC_STRING" ]]If you used the setup script, you can run this uninstall script:
$ curl -Ls get.dannyb.co/shellkin/uninstall | bashIf you experience any issue, have a question or a suggestion, or if you wish to contribute, feel free to open an issue.
