{"id":32148190,"url":"https://github.com/snapshot-testing/xc-snapshot-testing","last_synced_at":"2026-02-13T23:13:19.475Z","repository":{"id":312464165,"uuid":"1046842118","full_name":"snapshot-testing/xc-snapshot-testing","owner":"snapshot-testing","description":"[XCTest] 📸 Test less. Snap once. Stay pixel-perfect everywhere. 🖼️✨","archived":false,"fork":false,"pushed_at":"2026-02-07T22:19:52.000Z","size":10075,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-08T06:49:14.802Z","etag":null,"topics":["snapshot-testing","swift","swiftui","testing","xctest"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snapshot-testing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-29T10:07:10.000Z","updated_at":"2026-02-07T22:19:13.000Z","dependencies_parsed_at":"2025-08-30T20:50:55.835Z","dependency_job_id":null,"html_url":"https://github.com/snapshot-testing/xc-snapshot-testing","commit_stats":null,"previous_names":["snapshot-testing/xc-snapshot-testing"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/snapshot-testing/xc-snapshot-testing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapshot-testing%2Fxc-snapshot-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapshot-testing%2Fxc-snapshot-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapshot-testing%2Fxc-snapshot-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapshot-testing%2Fxc-snapshot-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snapshot-testing","download_url":"https://codeload.github.com/snapshot-testing/xc-snapshot-testing/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapshot-testing%2Fxc-snapshot-testing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29422675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T22:20:51.549Z","status":"ssl_error","status_checked_at":"2026-02-13T22:20:49.838Z","response_time":78,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["snapshot-testing","swift","swiftui","testing","xctest"],"created_at":"2025-10-21T09:01:07.120Z","updated_at":"2026-02-13T23:13:19.467Z","avatar_url":"https://github.com/snapshot-testing.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Swift Compatibility](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fsnapshot-testing%2Fxc-snapshot-testing%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/snapshot-testing/xc-snapshot-testing)\n[![Platform Compatibility](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fsnapshot-testing%2Fxc-snapshot-testing%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/snapshot-testing/xc-snapshot-testing)\n[![codecov](https://codecov.io/gh/snapshot-testing/xc-snapshot-testing/graph/badge.svg?token=YN43HSRRAU)](https://codecov.io/gh/snapshot-testing/xc-snapshot-testing)\n\n# XCSnapshotTesting\n\nXCSnapshotTesting is a comprehensive, cross-platform snapshot testing library for Swift that enables reliable UI and data structure testing across iOS, macOS, tvOS, watchOS, and visionOS. The library provides powerful tools for capturing, comparing, and verifying snapshots of your UI elements, data structures, and more, with support for both UIKit and SwiftUI.\n\n## [Documentation](https://swiftpackageindex.com/snapshot-testing/xc-snapshot-testing/main/documentation/xcsnapshottesting)\n\nCheck out our comprehensive documentation to get all the necessary information to start using XCSnapshotTesting in your project.\n\n## Installation\n\nXCSnapshotTesting can be installed using Swift Package Manager. To include it in your project, add the following dependency to your Package.swift file:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/snapshot-testing/xc-snapshot-testing\", from: \"1.0.0\")\n]\n```\n\n## Usage\n\nXCSnapshotTesting provides a comprehensive framework for snapshot testing across different platforms. It supports both synchronous and asynchronous snapshot testing for various types of content including UI elements, data structures, and more.\n\n### Basic Usage\n\nThe primary function for snapshot testing is `assert(of:as:named:)`. Here are the most common usage patterns:\n\n#### UI Snapshot Testing\n\nFor UI elements like views or view controllers:\n\n```swift\nimport XCSnapshotTesting\nimport XCTest\n\nclass MyViewControllerTests: XCTestCase {\n    func testViewController() async throws {\n        let vc = MyViewController()\n        \n        // Basic snapshot of a view\n        try await assert(\n            of: vc.view,\n            as: .image\n        )\n        \n        // With specific device layout\n        try await assert(\n            of: vc.view, \n            as: .image(layout: .device(.iPhone15Pro))\n        )\n        \n        // With custom precision and name\n        try await assert(\n            of: vc.view,\n            as: .image(\n                precision: 0.95,\n                layout: .device(.iPhone15Pro)\n            ),\n            named: \"light-mode\"\n        )\n    }\n}\n```\n\n#### Data Structure Snapshot Testing\n\nFor data structures like JSON, arrays, dictionaries, etc.:\n\n```swift\nfunc testDataStructure() async throws {\n    let data = [\"name\": \"John\", \"age\": 30]\n    \n    // Test as JSON\n    try await assert(\n        of: data,\n        as: .json\n    )\n    \n    // Test as pretty-printed JSON\n    try await assert(\n        of: data,\n        as: .json(pretty: true)\n    )\n}\n```\n\n#### Multiple Snapshots in One Test\n\nYou can test multiple configurations in a single test:\n\n```swift\nfunc testMultipleConfigurations() async throws {\n    let view = MyCustomView()\n    \n    // Test with multiple device layouts\n    try await assert(\n        of: view,\n        as: [\n            \"iPhone\": .image(layout: .device(.iPhone15Pro)),\n            \"iPad\": .image(layout: .device(.iPadPro)),\n            \"Dark\": .image(layout: .device(.iPhone15ProDark))\n        ]\n    )\n}\n```\n\n### Recording Mode\n\nBy default, the library uses the environment's recording mode, but you can override it:\n\n```swift\nfunc testWithRecordingOverride() async throws {\n    // Force recording a new snapshot\n    try await assert(\n        of: myView,\n        as: .image,\n        record: .always  // or .never to prevent recording\n    )\n}\n```\n\n### Advanced Configuration\n\nYou can customize various aspects of snapshot testing:\n\n```swift\nfunc testAdvancedConfiguration() async throws {\n    let view = MyCustomView()\n    \n    try await assert(\n        of: view,\n        as: .image(\n            precision: 0.98,           // Pixel tolerance\n            perceptualPrecision: 0.95, // Color/tone tolerance\n            layout: .device(.iPhone15Pro),\n            delay: 0.1                 // Wait before capturing\n        ),\n        serialization: .init(          // Additional serialization options\n            maxSize: CGSize(width: 1000, height: 1000)\n        ),\n        named: \"custom-snapshot\"\n    )\n}\n```\n\n### Testing Environment Configuration\n\nYou can configure the testing environment globally:\n\n```swift\noverride func setUp() {\n    super.setUp()\n    \n    // Configure global testing environment\n    withTestingEnvironment(\n        record: .never,  // Default to never record\n        diffTool: .imageMagick,  // Use ImageMagick for diffs\n        maxConcurrentTests: 4\n    ) {\n        // Tests run with these settings\n    }\n}\n```\n\n### Supported Platforms\n\nXCSnapshotTesting supports:\n\n- iOS (13.0+)\n- macOS (10.15+)\n- tvOS (13.0+)\n- watchOS (6.0+)\n\n### Available Snapshot Types\n\nThe library provides various built-in snapshot types:\n\n- `.image` - For UI elements (views, view controllers, etc.)\n- `.json` - For JSON-serializable data\n- `.text` - For string content\n- `.html` - For HTML content\n- `.xml` - For XML content\n- `.data` - For raw data\n\n### Asynchronous vs Synchronous\n\nThe library provides both asynchronous and synchronous versions of the `assert` function:\n\n- Use `assert(of:as:) async` for asynchronous operations\n- Use `assert(of:as:)` for synchronous operations\n\n### Custom Dump Snapshots\n\nThe package includes an additional module `XCSnapshotTestingCustomDump` that provides snapshot strategies based on the [swift-custom-dump](https://github.com/pointfreeco/swift-custom-dump) library. This allows for human-readable, structured snapshots of complex Swift types:\n\n```swift\nimport XCSnapshotTesting\nimport XCSnapshotTestingCustomDump  // Import for custom dump functionality\nimport XCTest\n\nfunc testCustomDump() throws {\n    struct User {\n        let id: Int\n        let name: String\n        let bio: String\n    }\n    \n    let user = User(id: 1, name: \"Blobby\", bio: \"Blobbed around the world.\")\n    \n    // Test using custom dump representation\n    try assert(\n        of: user,\n        as: .customDump\n    )\n}\n```\n\n### Testing Traits\n\nThe library provides a `Traits` system that allows you to customize the environment in which UI elements are rendered during snapshot testing. This is particularly useful for testing different accessibility settings, content size categories, and interface styles:\n\n```swift\nfunc testWithTraits() async throws {\n    let view = MyCustomView()\n    \n    // Test with specific accessibility traits\n    var traits = Traits()\n    traits.preferredContentSizeCategory = .extraLarge\n    traits.userInterfaceStyle = .dark\n    \n    try await assert(\n        of: view,\n        as: .image(\n            layout: .device(.iPhone15Pro),\n            traits: traits\n        ),\n        named: \"accessibility-large-dark\"\n    )\n}\n```\n\nThis allows you to ensure your UI renders correctly across different accessibility settings, content sizes, and interface styles.\n\n### Device Layouts\n\nThe library provides comprehensive device simulation capabilities. You can test your UI across various device sizes, orientations, and split-view configurations:\n\n```swift\nfunc testMultipleDeviceLayouts() async throws {\n    let vc = MyViewController()\n    \n    // Test different iPhone layouts\n    try await assert(\n        of: vc,\n        as: .image(layout: .device(.iPhone15Pro(.portrait)))\n    )\n    \n    try await assert(\n        of: vc,\n        as: .image(layout: .device(.iPhone15Pro(.landscape)))\n    )\n    \n    // Test iPad layouts including split-view\n    try await assert(\n        of: vc,\n        as: .image(layout: .device(.iPadPro12_9(.landscape(.regular))))\n    )\n    \n    try await assert(\n        of: vc,\n        as: .image(layout: .device(.iPadPro12_9(.landscape(.medium))))\n    )\n    \n    try await assert(\n        of: vc,\n        as: .image(layout: .device(.iPadPro12_9(.landscape(.compact))))\n    )\n}\n```\n\n### Alternative Snapshot Methods\n\nIn addition to image snapshots, you can also capture recursive descriptions of your views:\n\n```swift\nfunc testRecursiveDescription() async throws {\n    let vc = MyViewController()\n    \n    // Capture the view hierarchy as text\n    try await assert(\n        of: vc,\n        as: .recursiveDescription(layout: .device(.iPhone15Pro))\n    )\n}\n```\n\n### SwiftUI Support\n\nXCSnapshotTesting also supports SwiftUI views directly. You can test SwiftUI views just like UIKit/AppKit views:\n\n```swift\nimport SwiftUI\nimport XCSnapshotTesting\nimport XCTest\n\n@MainActor\nfunc testSwiftUIView() async throws {\n    struct MyView: SwiftUI.View {\n        var body: some SwiftUI.View {\n            HStack {\n                Image(systemName: \"checkmark.circle.fill\")\n                Text(\"Checked\").fixedSize()\n            }\n            .padding(5)\n            .background(RoundedRectangle(cornerRadius: 5.0).fill(Color.blue))\n            .padding(10)\n            .background(Color.yellow)\n        }\n    }\n    \n    let view = MyView()\n    \n    try await assert(\n        of: view,\n        as: .image  // This will render the SwiftUI view and take a snapshot\n    )\n    \n    // Test with specific sizing\n    try await assert(\n        of: view,\n        as: .image(layout: .sizeThatFits),\n        named: \"size-that-fits\"\n    )\n}\n```\n\n## Versioning\n\nWe follow semantic versioning for this project. The version number is composed of three parts: MAJOR.MINOR.PATCH.\n\n- MAJOR version: Increments when there are incompatible changes and breaking changes. These changes may require updates to existing code and could potentially break backward compatibility.\n\n- MINOR version: Increments when new features or enhancements are added in a backward-compatible manner. It may include improvements, additions, or modifications to existing functionality.\n\n- The PATCH version includes bug fixes, patches, and safe modifications that address issues, bugs, or vulnerabilities without disrupting existing functionality. It may also include new features, but they must be implemented carefully to avoid breaking changes or compatibility issues.\n\nIt is recommended to review the release notes for each version to understand the specific changes and updates made in that particular release.\n\n## Contributing\n\nIf you find a bug or have an idea for a new feature, please open an issue or  submit a pull request. We welcome contributions from the community!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnapshot-testing%2Fxc-snapshot-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnapshot-testing%2Fxc-snapshot-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnapshot-testing%2Fxc-snapshot-testing/lists"}