Swift Testing Attachment support for swift-snapshot-testing.
When snapshot tests fail, automatically attach reference snapshots and diff artifacts to Xcode's test report — visible right in the Test Navigator. Works as a standalone extension, no modifications to the original library.
Requires: Swift 6.2+ / Xcode 26+ for
Attachment.record().
On older toolchains everything compiles but attachments are a no-op.
Add to your Package.swift:
dependencies: [
.package(
url: "https://github.com/oscarcv/swift-snapshot-testing-attach",
from: "1.0.0"
),
]Then add to your test target:
.testTarget(
name: "MyAppTests",
dependencies: [
.product(name: "SnapshotTestingAttachments", package: "swift-snapshot-testing-attach"),
]
)
swift-snapshot-testingis pulled in automatically — no need to add it separately.
Replace assertSnapshot with assertSnapshotWithAttachments:
import Testing
import SnapshotTesting
import SnapshotTestingAttachments
@Suite struct MyViewTests {
@Test func myView() {
let view = MyView()
assertSnapshotWithAttachments(of: view, as: .image)
// On failure → reference + diff appear as attachments in Xcode
}
}Set attachment behavior once for an entire suite:
// Using the trait (recommended for Swift Testing):
@Suite(.snapshotAttachments(.always))
struct MySnapshotTests {
@Test func homepage() {
assertSnapshotWithAttachments(of: homepageView, as: .image)
}
@Test func settings() {
assertSnapshotWithAttachments(of: settingsView, as: .image)
}
}// Using withSnapshotAttachments (works with XCTest too):
class FeatureTests: XCTestCase {
override func invokeTest() {
withSnapshotAttachments(options: .always) {
super.invokeTest()
}
}
}Override global settings for individual assertions:
// Global is .onFailure, but this one also attaches on record:
assertSnapshotWithAttachments(of: view, as: .image, attachments: .always)Handle attachment data manually:
let result = verifySnapshotWithAttachments(of: myView, as: .image)
if let failure = result.failure {
for attachment in result.attachmentData {
print("\(attachment.name): \(attachment.data.count) bytes")
}
}| Option | Description |
|---|---|
.onFailure |
Attach reference + diff when comparison fails (default) |
.onRecord |
Attach snapshot data when recording new references |
.always |
Both .onFailure and .onRecord |
When assertSnapshotWithAttachments determines which options to use:
- Per-call
attachments:parameter (highest priority) withSnapshotAttachments(options:)scoped configuration@Suite(.snapshotAttachments(…))trait configuration.defaults(.onFailure)
This is a standalone extension package — it does not modify swift-snapshot-testing:
swift-snapshot-testing-attach
├── assertSnapshotWithAttachments() ← wraps verifySnapshot()
├── SnapshotFileLocator ← computes snapshot file paths
├── SnapshotAttachmentsConfiguration ← @TaskLocal global config
├── SnapshotAttachmentsTrait ← TestScoping trait
└── Testing.Attachment.record() ← Swift 6.2+ only
│
▼ depends on (unmodified)
swift-snapshot-testing
MIT — same as swift-snapshot-testing.