← Spec-writing technique guides

How to write specs for edge cases

How-To Spec-writing technique Intermediate 1071012HOWTO-1071012

HOWTO-1071012Spec-writing techniqueIntermediate

This guide shows you how to write SpecDD specs for edge cases in a spec-driven development workflow.

Edge cases belong in specs when they define durable behavior or prevent recurring mistakes. The goal is not to list every theoretical possibility. The goal is to make important failure modes, boundary conditions, and degraded states explicit enough to implement and verify.

Short answer

Write edge cases as specific behavior. Use Must for required handling, Must not for unsafe fallback behavior, Handles for events or conditions the subject is responsible for, Raises for errors or signals, Scenario for concrete examples, and Done when to require checks.

When to use this guide

Use this guide when a spec needs to define behavior for:

Steps

1. Choose edge cases that matter

Start from real risk:

Do not fill a spec with unrelated edge cases just because they are imaginable.

2. State expected behavior

Use concrete Must rules:

Must:
  Reject itinerary items without a place name.
  Treat an empty itinerary as a valid trip state.
  Retry destination lookups only when the lookup fails with a retryable network error.

Avoid:

Must:
  Handle all edge cases gracefully.

That rule does not tell implementers or reviewers what behavior is expected.

3. Use scenarios for examples

Scenarios are useful when the edge case has multiple conditions:

Scenario: Empty itinerary
  Given a trip with no itinerary items
  When the itinerary is opened
  Then the trip is shown without an error
  And no placeholder item is created

The scenario can later guide a test, but it also makes the intended behavior readable.

4. Use Handles and Raises when appropriate

Use Handles for conditions the subject is responsible for:

Handles:
  validation failure for missing place name
  retryable destination lookup failure
  expired edit permission

Use Raises for errors, events, or signals the subject emits:

Raises:
  ItineraryValidationError when a place name is missing
  PermissionDenied when the user cannot edit the trip

These sections are especially useful for services, APIs, jobs, adapters, and event handlers.

5. Add boundaries for unsafe behavior

Use Must not for fallbacks that would be harmful:

Must not:
  Save a partial itinerary item after validation fails.
  Retry permission failures.
  Convert an unknown time zone to the server default.

These boundaries prevent plausible but incorrect “helpful” behavior.

6. Connect edge cases to checks

Use Done when to make important edge cases verifiable:

Done when:
  Missing-place validation is covered by a check.
  Empty itinerary rendering is covered by a check.
  Permission failures are not retried.

If an edge case matters enough to specify, it often matters enough to test.

Edge case patterns

Validation failure

Must:
  Reject itinerary items without a place name.

Raises:
  ItineraryValidationError when a place name is missing

Done when:
  Missing-place validation is covered by a check.

Retry behavior

Must:
  Retry destination lookup once after a retryable network error.

Must not:
  Retry validation failures or permission failures.

Time zone behavior

Must:
  Interpret trip dates in the trip's configured time zone.

Must not:
  Fall back to the server time zone when the trip time zone is missing.

Partial external failure

Handles:
  destination lookup timeout

Must:
  Preserve the user's unsaved itinerary item when destination lookup times out.

Common mistakes

How to verify the result

The edge-case spec is ready when:

← Spec-writing technique guides