From apple-dev
Use before refactoring legacy code, or when the user says 'characterization test', 'lock behavior', '特征测试', 'write characterization tests', 'snapshot behavior'. Generates Swift Testing test cases that capture current behavior as a safety net before refactoring.
npx claudepluginhub n0rvyn/indie-toolkit --plugin apple-devThis skill uses the workspace's default tool permissions.
Lock current behavior with test cases before refactoring. Uses Swift Testing framework (`@Test` + `#expect`).
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Lock current behavior with test cases before refactoring. Uses Swift Testing framework (@Test + #expect).
Ask user to specify one of:
If user says "the code I'm about to refactor" without specifics, check recent git changes or ask.
For each target type, extract:
@Published, @Observable)throw, optional returns, Result typesOutput analysis:
## Interface Analysis: {TypeName}
### Methods ({N})
- `func methodName(param: Type) -> ReturnType` — {one-line behavior description}
Side effects: {none / publishes to X / writes to Y}
### Properties ({N})
- `var propName: Type` — {computed/stored, observable?}
### Initializers ({N})
- `init(param: Type)` — {what it sets up}
### Error Paths ({N})
- `methodName` throws `ErrorType` when {condition}
### Identified Edge Cases ({N})
- {description of boundary/edge case from code}
For each item from Step 2, generate Swift Testing test cases.
Test file naming: {TypeName}CharacterizationTests.swift
Test structure:
import Testing
@testable import {ModuleName}
// MARK: - {TypeName} Characterization Tests
// Generated: {date}
// Purpose: Lock current behavior before refactoring.
// DELETE these tests after refactoring is verified with proper unit tests.
struct {TypeName}CharacterizationTests {
// MARK: - Initialization
@Test("init sets default values")
func initDefaults() {
let sut = TypeName()
#expect(sut.property == expectedValue)
}
// MARK: - Method Behavior
@Test("methodName returns X when given Y")
func methodNameHappyPath() {
let sut = TypeName()
let result = sut.methodName(param: testValue)
#expect(result == expectedValue)
}
@Test("methodName handles empty input")
func methodNameEmptyInput() {
let sut = TypeName()
let result = sut.methodName(param: [])
#expect(result == expectedEmptyResult)
}
// MARK: - Error Paths
@Test("methodName throws when input is invalid")
func methodNameThrows() {
let sut = TypeName()
#expect(throws: SpecificError.self) {
try sut.methodName(param: invalidValue)
}
}
// MARK: - Side Effects
@Test("methodName publishes update")
func methodNamePublishes() async {
let sut = TypeName()
sut.methodName(param: value)
#expect(sut.publishedProperty == expectedValue)
}
}
Test generation rules:
@Test per observable behavior (not per line of code)#expect for assertions, #require for preconditionsasync test functions// CHARACTERIZATION comment for easy cleanup laterExecute:
xcodebuild test \
-scheme {scheme} \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-only-testing:{testTarget}/{TypeName}CharacterizationTests \
-quiet 2>&1
If any test fails:
If build fails (missing imports, wrong module name):
Report baseline:
## Baseline Results
- Tests generated: {N}
- Tests passing: {N}
- Tests fixed (expected value adjusted): {N}
- Build issues resolved: {N}
## Characterization Test Summary
### Coverage
| Type | Methods | Properties | Error Paths | Edge Cases | Total Tests |
|------|---------|------------|-------------|------------|-------------|
| {TypeName} | X | Y | Z | W | N |
### Test Files
- `{TestTarget}/{TypeName}CharacterizationTests.swift`
### Baseline
All {N} tests passing at commit {SHA short}.
### Next Steps
- Proceed with refactoring; run these tests after each change
- When refactoring is complete, replace characterization tests with proper unit tests
- Delete characterization test files when no longer needed
@Test + #expect + #require. No XCTest.xcodebuild test)