Back to Skills

shipyard-testing

verified

Use when writing tests, structuring test suites, choosing test boundaries, or debugging test quality issues like flakiness, over-mocking, or brittle tests

View on GitHub

Marketplace

shipyard

lgbarn/shipyard

Plugin

shipyard

development

Repository

lgbarn/shipyard
28stars

skills/shipyard-testing/SKILL.md

Last Verified

February 4, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/lgbarn/shipyard/blob/main/skills/shipyard-testing/SKILL.md -a claude-code --skill shipyard-testing

Installation paths:

Claude
.claude/skills/shipyard-testing/
Powered by add-skill CLI

Instructions

<!-- TOKEN BUDGET: 400 lines / ~1200 tokens -->

# Writing Effective Tests

## Activation Triggers

- Writing or modifying test files (`*.test.*`, `*.spec.*`, `*_test.go`, `test_*.py`)
- Setting up test infrastructure or test utilities
- Debugging flaky, brittle, or slow tests
- Deciding between unit, integration, and E2E tests
- Choosing when and how to use mocks, stubs, or fakes

## Overview

Test behaviors through public APIs. Verify state, not interactions.

**Core principle:** If refactoring breaks your tests but not your users, your tests are wrong.

**Relationship to TDD:** The `shipyard:shipyard-tdd` skill covers WHEN to write tests (test-first, red-green-refactor). This skill covers HOW to write tests that are effective, maintainable, and trustworthy.

## The Iron Law

```
TEST BEHAVIORS, NOT IMPLEMENTATIONS
```

A test should break only when the system's observable behavior changes — never because of refactoring, renaming internals, or restructuring code.

**No exceptions:**
- Don't test private methods
- Don't assert on internal state
- Don't verify method call sequences
- Don't couple tests to data structures users never see

## Test Structure (AAA)

Every test follows Arrange-Act-Assert:

```
Arrange — Set up preconditions and inputs
Act     — Execute the behavior under test
Assert  — Verify the expected outcome
```

Separate the three sections with blank lines. One Act per test. One logical assertion per test.

<Good>
```python
def test_expired_subscription_denies_access():
    # Arrange
    user = create_user(subscription_end=yesterday())

    # Act
    result = check_access(user, resource="premium-content")

    # Assert
    assert result.denied is True
    assert result.reason == "subscription expired"
```
Clear name, tests one behavior, obvious structure
</Good>

<Bad>
```python
def test_subscription():
    user = create_user(subscription_end=yesterday())
    assert check_access(user, "premium-content").denied
    user.subscription_end = tomorrow()

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
10341 chars