mcpbeat Sign in

Test Data Factory Skill for Claude

Generate test fixture factories for your models. Builder pattern and static factories for zero-boilerplate test data. Use when tests need sample data setup.

2k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
585
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill test-data-factory

The instruction itself

17 sections, as written by the author

Test Data Factory

Generate factory helpers that make creating test data effortless. Eliminates boilerplate in test setup so writing tests has zero friction.

When This Skill Activates

Use this skill when the user:

  • Has repetitive test setup code
  • Asks for "test fixtures" or "test factories" or "sample data"
  • Wants to reduce boilerplate in tests
  • Says "my tests have too much setup"
  • Is building a test suite and needs realistic sample data
  • Mentions "builder pattern" for tests

Why Test Factories

// ❌ Without factory — every test repeats this
let item = Item(
    id: UUID(),
    title: "Test Item",
    description: "A test description",
    category: .general,
    createdAt: Date(),
    updatedAt: Date(),
    isFavorite: false,
    tags: [],
    author: User(id: UUID(), name: "Test User", email: "[email protected]")
)

// ✅ With factory — one line, override only what matters
let item = Item.fixture()
let favoriteItem = Item.fixture(isFavorite: true)
let taggedItem = Item.fixture(tags: ["swift", "testing"])

Process

Phase 1: Discover Models

Glob: **/*.swift (in source targets)
Grep: "struct.*:.*Identifiable|class.*:.*Identifiable|@Model"
Grep: "struct.*:.*Codable|struct.*:.*Sendable"

Identify models that appear in test files:

Grep: "let.*=.*Model(" in test targets (manual construction)

Phase 2: Choose Factory Pattern

Ask via AskUserQuestion:

  • Factory style?
  • Static factory methods (simpler, recommended)
  • Builder pattern (more flexible, for complex models)
  • Both
  • Where to add?
  • Test target extension (recommended — keeps production code clean)
  • Shared test helper file

Phase 3: Generate Factories

Pattern 1: Static Factory Extension
// Tests/Factories/Item+Factory.swift

import Foundation
@testable import YourApp

extension Item {
    /// Creates a test fixture with sensible defaults.
    /// Override only the properties relevant to your test.
    static func fixture(
        id: UUID = UUID(),
        title: String = "Test Item",
        description: String = "A test description",
        category: Category = .general,
        createdAt: Date = Date(timeIntervalSince1970: 1_700_000_000),
        updatedAt: Date = Date(timeIntervalSince1970: 1_700_000_000),
        isFavorite: Bool = false,
        tags: [String] = [],
        author: User = .fixture()
    ) -> Item {
        Item(
            id: id,
            title: title,
            description: description,
            category: category,
            createdAt: createdAt,
            updatedAt: updatedAt,
            isFavorite: isFavorite,
            tags: tags,
            author: author
        )
    }

    /// Named fixtures for common test scenarios
    static var sample: Item { .fixture() }
    static var favorite: Item { .fixture(isFavorite: true) }
    static var empty: Item { .fixture(title: "", description: "") }

    /// Collection fixtures
    static var sampleList: [Item] {
        [
            .fixture(id: UUID(), title: "First Item", category: .work),
            .fixture(id: UUID(), title: "Second Item", category: .personal),
            .fixture(id: UUID(), title: "Third Item", category: .general)
        ]
    }
}

extension User {
    static func fixture(
        id: UUID = UUID(),
        name: String = "Test User",
        email: String = "[email protected]"
    ) -> User {
        User(id: id, name: name, email: email)
    }

    static var sample: User { .fixture() }
}
Pattern 2: Builder Pattern

For models with many optional fields or complex relationships:

// Tests/Factories/ItemBuilder.swift

@testable import YourApp

final class ItemBuilder {
    private var id: UUID = UUID()
    private var title: String = "Test Item"
    private var description: String = "A test description"
    private var category: Category = .general
    private var createdAt: Date = .init(timeIntervalSince1970: 1_700_000_000)
    private var isFavorite: Bool = false
    private var tags: [String] = []
    private var author: User = .fixture()

    @discardableResult
    func with(title: String) -> Self {
        self.title = title
        return self
    }

    @discardableResult
    func with(category: Category) -> Self {
        self.category = category
        return self
    }

    @discardableResult
    func favorited() -> Self {
        self.isFavorite = true
        return self
    }

    @discardableResult
    func with(tags: [String]) -> Self {
        self.tags = tags
        return self
    }

    @discardableResult
    func authored(by user: User) -> Self {
        self.author = user
        return self
    }

    func build() -> Item {
        Item(
            id: id,
            title: title,
            description: description,
            category: category,
            createdAt: createdAt,
            updatedAt: createdAt,
            isFavorite: isFavorite,
            tags: tags,
            author: author
        )
    }
}

// Usage:
let item = ItemBuilder()
    .with(title: "Important")
    .with(category: .work)
    .favorited()
    .build()
Pattern 3: Sequence Factories

For generating unique test data in loops:

extension Item {
    /// Creates N unique items with sequential titles
    static func fixtures(count: Int) -> [Item] {
        (0..<count).map { index in
            .fixture(
                id: UUID(),
                title: "Item \(index + 1)"
            )
        }
    }

    /// Creates items matching specific states for state-based testing
    static var allStates: [Item] {
        [
            .fixture(title: "Draft", category: .draft),
            .fixture(title: "Active", category: .active),
            .fixture(title: "Archived", category: .archived),
            .fixture(title: "Deleted", category: .deleted)
        ]
    }
}

Phase 4: Generate Date/Time Helpers

Provide fixed reference dates:

// Tests/Factories/Date+Factory.swift

extension Date {
    /// Fixed reference dates for deterministic tests
    static let testReference = Date(timeIntervalSince1970: 1_700_000_000)  // 2023-11-14
    static let testYesterday = testReference.addingTimeInterval(-86_400)
    static let testLastWeek = testReference.addingTimeInterval(-604_800)
    static let testNextMonth = testReference.addingTimeInterval(2_592_000)

    /// Create a date relative to test reference
    static func testDate(daysFromReference days: Int) -> Date {
        testReference.addingTimeInterval(TimeInterval(days * 86_400))
    }
}

Phase 5: Generate Mock Response Factories

For network/API testing:

// Tests/Factories/APIResponse+Factory.swift

extension APIResponse where T == [Item] {
    static func success(items: [Item] = Item.sampleList) -> APIResponse {
        APIResponse(data: items, statusCode: 200, error: nil)
    }

    static func empty() -> APIResponse {
        APIResponse(data: [], statusCode: 200, error: nil)
    }

    static func error(_ error: APIError = .serverError) -> APIResponse {
        APIResponse(data: nil, statusCode: 500, error: error)
    }

    static func notFound() -> APIResponse {
        APIResponse(data: nil, statusCode: 404, error: .notFound)
    }
}

Factory Design Rules

Defaults Should Be

| Property Type | Default Strategy |

|--------------|-----------------|

| UUID | UUID() |

| String | Descriptive placeholder ("Test Item") |

| Date | Fixed timestamp, not Date() |

| Bool | false |

| Array | Empty [] (opt-in to populated) |

| Optional | nil |

| Enum | Most common case |

| Nested model | That model's .fixture() |

Naming Conventions

// Static factory — use .fixture() for customizable, .sample for quick
Item.fixture(title: "Custom")   // Customizable
Item.sample                     // Quick default
Item.sampleList                 // Collection

// Named scenarios
Item.favorite                   // Specific state
Item.expired                    // Specific state
Item.empty                      // Edge case

// Builder — use descriptive method names
ItemBuilder().favorited().build()
ItemBuilder().with(title: "X").build()

Output Format

## Test Data Factories Generated

### Models Covered
| Model | Factory Type | Named Fixtures | Collection Fixtures |
|-------|-------------|----------------|-------------------|
| Item | Static + Builder | sample, favorite, empty | sampleList, fixtures(count:) |
| User | Static | sample | — |
| APIResponse | Static | success, empty, error | — |

### Files Created
- `Tests/Factories/Item+Factory.swift`
- `Tests/Factories/User+Factory.swift`
- `Tests/Factories/ItemBuilder.swift`
- `Tests/Factories/Date+Factory.swift`
- `Tests/Factories/APIResponse+Factory.swift`

### Usage Example

// Before (30 lines of setup)

let user = User(id: UUID(), name: "Test", email: "[email protected]")

let item = Item(id: UUID(), title: "T", description: "D", ...)

// After (1 line)

let item = Item.fixture(isFavorite: true)

References

  • generators/test-generator/ — generates tests that use these factories
  • testing/tdd-feature/ — TDD workflow benefits from low-friction factories
  • testing/integration-test-scaffold/ — integration tests need realistic data

Other skills for the same job

different authors, same section of the catalogue
Webapp Testing
by anthropics
vendor ×12

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

6k tokens scripts
Finishing A Development Branch
by ZhanlinCui
×7

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

1k tokens
Test Driven Development
by w95
×7

Use when implementing any feature or bugfix, before writing implementation code

2k tokens
Systematic Debugging
by ratacat
×7

Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes

10k tokens scripts
Verification Before Completion
by ZhanlinCui
×6

Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always

1k tokens
Backtest Expert
by BaggaT236
×3

Expert guidance for systematic backtesting of trading strategies. Use when developing, testing, stress-testing, or validating quantitative trading strategies. Covers "beating ideas to death" methodology, parameter robustness testing, slippage modeling, bias prevention, and interpreting backtest results. Applicable when user asks about backtesting, strategy validation, robustness testing, avoiding overfitting, or systematic trading development.

15k tokens scripts
Adaptyv
by christophacham
×3

Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding assays, expression testing, thermostability measurements, enzyme activity assays, or protein sequence optimization. Also use for submitting experiments via API, tracking experiment status, downloading results, optimizing protein sequences for better expression using computational tools (NetSolP, SoluProt, SolubleMPNN, ESM), or managing protein design workflows with wet-lab validation.

16k tokens
Aeon
by christophacham
×3

This skill should be used for time series machine learning tasks including classification, regression, clustering, forecasting, anomaly detection, segmentation, and similarity search. Use when working with temporal data, sequential patterns, or time-indexed observations requiring specialized algorithms beyond standard ML approaches. Particularly suited for univariate and multivariate time series analysis with scikit-learn compatible APIs.

19k tokens

How to use it

Copy the folder

Take rshankras/test-data-factory from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.