Skip to content
Agent Orchestration
Skill

/designing-tests

Guides test strategy, TDD/BDD approaches, test coverage planning, and testing best practices. Use when designing test suites, improving coverage, or choosing testing approaches.

BOOST
From plugin
opencode-workflow
2757 skills7 agents12 commands
Install
$ npx -y skills add cloudai-x/opencode-workflow --skill designing-tests --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/designing-tests

Context preview

The summary Claude sees to decide when to auto-load this skill.

Guides test strategy, TDD/BDD approaches, test coverage planning, and testing best practices. Use when designing test suites, improving coverage, or choosing testing approaches.

SKILL.md

designing-tests.SKILL.md
name: designing-tests
description: Guides test strategy, TDD/BDD approaches, test coverage planning, and testing best practices. Use when designing test suites, improving coverage, or choosing testing approaches.
license: MIT
compatibility: opencode
metadata:
  category: quality
  audience: developers

Designing Tests

Strategies and patterns for designing effective, maintainable test suites.

When to Use This Skill

  • Planning test coverage for new features
  • Choosing between testing approaches (TDD, BDD)
  • Designing integration or E2E tests
  • Improving existing test suites
  • Setting up testing infrastructure
  • Debugging flaky tests

---

The Testing Pyramid

                 ┌─────────┐
                 │   E2E   │  ← Few, slow, expensive
                 │  Tests  │     (Selenium, Playwright)
                 ├─────────┤
                 │         │
              ┌──┤ Integr- │  ← Some, medium speed
              │  │  ation  │     (API tests, DB tests)
              │  │  Tests  │
              │  ├─────────┤
              │  │         │
              │  │  Unit   │  ← Many, fast, cheap
              │  │  Tests  │     (Pure functions, isolated)
              └──┴─────────┘

| Level | Speed | Scope | Quantity | Purpose | |-------|-------|-------|----------|---------| | Unit | ~ms | Single function/class | Many (70-80%) | Logic correctness | | Integration | ~s | Multiple components | Some (15-20%) | Component interaction | | E2E | ~10s+ | Full system | Few (5-10%) | User flows work |

---

Test-Driven Development (TDD)

The Red-Green-Refactor Cycle

     ┌─────────────────────────────────┐
     │                                 │
     ▼                                 │
┌─────────┐    ┌─────────┐    ┌────────┴──┐
│   RED   │───▶│  GREEN  │───▶│ REFACTOR  │
│  Write  │    │  Make   │    │  Clean    │
│ failing │    │   it    │    │   up      │
│  test   │    │  pass   │    │  code     │
└─────────┘    └─────────┘    └───────────┘

TDD Best Practices

1. **Write the test first** - Don't write production code without a failing test 2. **Write the minimal test** - One behavior per test 3. **Write the minimal code** - Just enough to pass 4. **Refactor ruthlessly** - Clean up after green 5. **Run tests frequently** - After every small change

TDD Example Flow

# Step 1: RED - Write failing test
def test_calculate_total_with_discount():
    order = Order(items=[Item(price=100)])
    order.apply_discount(10)  # 10%
    assert order.total() == 90

# Step 2: GREEN - Minimal implementation
class Order:
    def __init__(self, items):
        self.items = items
        self.discount = 0

    def apply_discount(self, percent):
        self.discount = percent

    def total(self):
        subtotal = sum(i.price for i in self.items)
        return subtotal * (100 - self.discount) / 100

# Step 3: REFACTOR - Clean up (if needed)

---

Behavior-Driven Development (BDD)

Gherkin Syntax

Feature: Shopping Cart
  As a customer
  I want to add items to my cart
  So that I can purchase them later

  Scenario: Add item to empty cart
    Given I have an empty cart
    When I add a product "Widget" priced at $10
    Then my cart should contain 1 item
    And my cart total should be $10

  Scenario: Apply discount code
    Given I have a cart with total $100
    When I apply discount code "SAVE10"
    Then my cart total should be $90

BDD Benefits

  • Tests as documentation
  • Shared language with stakeholders
  • Focus on behavior, not implementation
  • Easy to understand test intent

---

Test Design Patterns

Arrange-Act-Assert (AAA)

def test_user_registration():
    # Arrange - Set up preconditions
    user_data = {"email": "test@example.com", "password": "secure123"}
    user_service = UserService(mock_repository)

    # Act - Perform the action
    result = user_service.register(user_data)

    # Assert - Verify the outcome
    assert result.success is True
    assert result.user.email == "test@example.com"

Given-When-Then (BDD style)

def test_order_cancellation():
    # Given - a confirmed order
    order = create_confirmed_order()

    # When - the customer cancels it
    order.cancel()

    # Then - the order is cancelled and refund initiated
    assert order.status == "cancelled"
    assert order.refund_initiated is True

Test Data Builders

class UserBuilder:
    def __init__(self):
        self.email = "default@test.com"
        self.name = "Test User"
        self.role = "user"

    def with_email(self, email):
        self.email = email
        return self

    def with_role(self, role):
        self.role = role
        return self

    def build(self):
        return User(email=self.email, name=self.name, role=self.role)

# Usage
admin = UserBuilder().with_role("admin").build()

Object Mother Pattern

class TestUsers:
    @staticmethod
    def admin():
        return User(email="admin@test.com", role="admin")

    @staticmethod
    def customer():
        return User(email="customer@test.com", role="customer")

    @staticmethod
    def guest():
        return User(email=None, role="guest")

---

Mocking Strategies

When to Mock

| Mock | Don't Mock | |------|------------| | External APIs | Pure business logic | | Database (for unit tests) | Simple value objects | | File system | Deterministic functions | | Time/random | Core domain entities | | Third-party services | Internal collaborators (usually) |

Mock Types

| Type | Purpose | Example | |------|---------|---------| | **Stub** | Return canned responses | `mock.return_value = 42` | | **Mock** | Verify interactions | `mock.assert_called_with(...)` | | **Spy** | Track real calls | Wraps real object, records calls | | **Fake** | Simplified implementation | In-memory database |

Mocking Example

# Using unittest.mock
from unittest.mock import Mock, patch

def test
Read more
Ships withopencode-workflow

A universal OpenCode workflow setup with specialized agents, skills, commands, and plugins for any software project.

Get the whole plugin

Other skills on opencode-workflow.