A new Swift library called Replay solves the perennial pain of flaky network tests by recording real HTTP interactions once and replaying them instantly. Leveraging the HAR standard and modern Swift capabilities, it eliminates slow API calls and stale fixtures while ensuring sensitive data protection through configurable filters.

For Swift developers, testing network code has long meant choosing between unreliable live API calls, high-maintenance stubs, or manually curated JSON fixtures that inevitably drift from reality. A new open-source library called Replay finally brings a battle-tested solution to this problem—HTTP traffic recording—to the Swift ecosystem.
The VCR Legacy Perfected
As reported by NSHipster, Replay builds on 15 years of proven patterns pioneered by tools like Ruby's VCR (2010), Python's VCR.py, and Java's Betamax. These tools intercept HTTP requests during tests, serving pre-recorded responses instead of hitting live networks—dramatically speeding up test suites while eliminating flakiness.
Replay modernizes this approach with two key advancements:
Embracing HAR standardization: Instead of inventing custom formats, Replay uses HTTP Archive (HAR)—a ubiquitous format supported by browsers (Safari/Firefox), proxies (Charles/Postman), and testing tools. Developers can capture traffic via Safari's Network tab and immediately use it as test fixtures.
Leveraging modern Swift: Swift 6.1's
TestScopingprotocol and package plugins enable declarative, per-test configuration previously impossible. As NSHipster notes: "These capabilities simply didn't exist before—not in any way that felt intuitive or convenient."
How Replay Works
Tests adopt the .replay trait to intercept URLSession calls:
@Test(.replay("fetchUser"))
func fetchUser() async throws {
let (data, _) = try await URLSession.shared.data(
from: URL(string: "https://api.example.com/users/42")!
)
let user = try JSONDecoder().decode(User.self, from: data)
#expect(user.id == 42)
}
This loads responses from Replays/fetchUser.har—a human-editable JSON file containing captured requests and responses. Crucially, no protocol mocks or dependency injection are required—it works with vanilla URLSession, custom sessions, and libraries like Alamofire.
Secure Recording Workflow
Replay prioritizes security with an intentional friction-first approach:
- Initial runs without recordings fail explicitly to prevent accidental capture of credentials or PII
- Recording requires explicit opt-in via environment variables:
REPLAY_RECORD_MODE=once swift test --filter fetchUser - Built-in filters redact sensitive data during capture:
@Test(.replay("fetchUser", filters: [
.headers(removing: ["Authorization", "Cookie"]),
.queryParameters(removing: ["token"])
]))
func fetchUser() async throws { ... }
Advanced Matching & Stubbing
Beyond exact URL matching, Replay supports:
- Flexible matchers for volatile APIs (e.g., ignoring timestamps):
matching: [.method, .path] - Inline stubs for edge cases without HAR files:
@Test(.replay(stubs: [
.get("https://api.example.com/health", 200,
["Content-Type": "application/json"],
#"{"status": "ok"}"#)
]))
func testHealthCheck() async throws { ... }
The Future Is Recorded
By converging HAR standardization with Swift's evolving capabilities, Replay delivers a mature testing pattern honed across ecosystems. For teams tired of slow, brittle network tests, it offers an elegant path to faster feedback cycles without compromising security or maintainability—proving that some solutions are worth replaying.

Comments
Please log in or register to join the discussion