{"id":16907197,"url":"https://github.com/ashfurrow/nimble-snapshots","last_synced_at":"2026-04-19T03:04:58.729Z","repository":{"id":715635,"uuid":"22723832","full_name":"ashfurrow/Nimble-Snapshots","owner":"ashfurrow","description":"Nimble matchers for FBSnapshotTestCase.","archived":false,"fork":false,"pushed_at":"2024-08-11T23:56:33.000Z","size":2955,"stargazers_count":319,"open_issues_count":13,"forks_count":100,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-12T14:18:52.123Z","etag":null,"topics":["fbsnapshottestcase","hacktoberfest","nimble","snapshots"],"latest_commit_sha":null,"homepage":"https://medium.com/cocoaacademymag/unit-testing-uiview-with-nimble-snapshot-651a7c5a5e93","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/ashfurrow.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2014-08-07T14:16:58.000Z","updated_at":"2024-10-29T17:42:40.000Z","dependencies_parsed_at":"2023-07-05T20:31:23.943Z","dependency_job_id":"8e701da0-a052-46bc-8740-e46d81e82a85","html_url":"https://github.com/ashfurrow/Nimble-Snapshots","commit_stats":{"total_commits":487,"total_committers":56,"mean_commits":8.696428571428571,"dds":0.6837782340862423,"last_synced_commit":"b451df00dea23d727472cffda1c5b19fe93dff96"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashfurrow%2FNimble-Snapshots","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashfurrow%2FNimble-Snapshots/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashfurrow%2FNimble-Snapshots/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashfurrow%2FNimble-Snapshots/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ashfurrow","download_url":"https://codeload.github.com/ashfurrow/Nimble-Snapshots/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248578876,"owners_count":21127714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["fbsnapshottestcase","hacktoberfest","nimble","snapshots"],"created_at":"2024-10-13T18:46:28.803Z","updated_at":"2026-04-19T03:04:58.721Z","avatar_url":"https://github.com/ashfurrow.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![GitHub Actions CI](https://github.com/ashfurrow/Nimble-Snapshots/actions/workflows/build-and-test.yml/badge.svg?branch=master)\n[![Cocoapods compatible](https://img.shields.io/cocoapods/v/Nimble-Snapshots.svg)](https://cocoapods.org/?q=Nimble-Snapshots)\n[![SPM compatible](https://img.shields.io/badge/SPM-compatible-brightgreen)](https://swift.org/package-manager)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![License](https://img.shields.io/github/license/ashfurrow/Nimble-Snapshots.svg)](https://github.com/ashfurrow/Nimble-Snapshots/blob/master/LICENSE)\n=============================\n\n[Nimble](https://github.com/Quick/Nimble) matchers for [iOSSnapshotTestCase](https://github.com/uber/ios-snapshot-test-case).\nOriginally derived from [Expecta Matchers for FBSnapshotTestCase](https://github.com/dblock/ios-snapshot-test-case-expecta).\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"http://gifs.ashfurrow.com/click.gif\" /\u003e\n\u003c/p\u003e\n\nInstalling\n----------\n\n## CocoaPods\n\nYou need to be using CocoaPods 0.36 Beta 1 or higher. Your `Podfile` should look\nsomething like the following.\n\n```rb\nplatform :ios, '10.0'\n\nsource 'https://github.com/CocoaPods/Specs.git'\n\n# Whichever pods you need for your app go here.\n\ntarget 'YOUR_APP_NAME_HERE_Tests', :exclusive =\u003e true do\n  pod 'Nimble-Snapshots'\n  pod 'Quick' # if you want to use it with Quick\nend\n```\n\nThen run:\n```\n$ pod install\n```\n\n## Carthage\n\nYou need to be using Carthage 0.40.0 or higher. Your `Cartfile` (or `Cartfile.private`) should look\nsomething like the following.\n\n```rb\ngithub \"Quick/Nimble\" \"v13.8.0\"\ngithub \"uber/ios-snapshot-test-case\" \"main\" # Temporarily pin to main due to known issues in 8.0.0\ngithub \"ashfurrow/Nimble-Snapshots\"\n```\n\nThen run:\n```\n$ carthage bootstrap --use-xcframeworks --platform iOS\n```\n\n## Swift Package Manager\n\nTo add `Nimble-Snapshots` as a dependency, you have to add it to the dependencies of your `Package.swift` file and refer to that dependency in your target.\n\n```swift\nimport PackageDescription\nlet package = Package(\n    name: \"\u003cYour Product Name\u003e\",\n    dependencies: [\n       .package(url: \"https://github.com/ashfurrow/Nimble-Snapshots\", .upToNextMajor(from: \"9.0.0\"))\n    ],\n    targets: [\n        .target(\n            name: \"\u003cYour Target Name\u003e\",\n            dependencies: [\"Nimble-Snapshots\"]),\n    ]\n)\n```\n\nUse\n---\n\nYour tests will look something like the following.\n\n```swift\nimport Quick\nimport Nimble\nimport Nimble_Snapshots\nimport UIKit\n\nclass MySpec: QuickSpec {\n    override func spec() {\n        describe(\"in some context\") {\n            it(\"has valid snapshot\") {\n                let view = ... // some view you want to test\n                expect(view).to( haveValidSnapshot() )\n            }\n        }\n    }\n}\n```\n\nThere are some options for testing the validity of snapshots. Snapshots can be\ngiven a name:\n\n```swift\nexpect(view).to( haveValidSnapshot(named: \"some custom name\") )\n```\n\nWe also have a prettier syntax for custom-named snapshots:\n\n```swift\nexpect(view) == snapshot(\"some custom name\")\n```\n\nTo record snapshots, just replace `haveValidSnapshot()` with `recordSnapshot()`\nand `haveValidSnapshot(named:)` with `recordSnapshot(named:)`. We also have a\nhandy emoji operator.\n\n```swift\n📷(view)\n📷(view, \"some custom name\")\n```\n\nBy default, this pod will put the reference images inside a `ReferenceImages`\ndirectory; we try to put this in a place that makes sense (inside your unit\ntests directory). If we can't figure it out, or if you want to use your own\ndirectory instead, call `setNimbleTestFolder()` with the name of the directory\nin your unit test's path that we should use. For example, if the tests are in\n`App/AppTesting/`, you can call it with `AppTesting`.\n\nIf you have any questions or run into any trouble, feel free to open an issue\non this repo.\n\n## Dynamic Type\n\nTesting Dynamic Type manually is boring and no one seems to remember doing it\nwhen implementing a view/screen, so you can have snapshot tests according to\ncontent size categories.\n\nIn order to use Dynamic Type testing, make sure to provide a valid `Host Application` in your testing target.\n\nThen you can use the `haveValidDynamicTypeSnapshot` and\n`recordDynamicTypeSnapshot` matchers:\n\n```swift\n// expect(view).to(recordDynamicTypeSnapshot()\nexpect(view).to(haveValidDynamicTypeSnapshot())\n\n// You can also just test some sizes:\nexpect(view).to(haveValidDynamicTypeSnapshot(sizes: [UIContentSizeCategoryExtraLarge]))\n\n// If you prefer the == syntax, we got you covered too:\nexpect(view) == dynamicTypeSnapshot()\nexpect(view) == dynamicTypeSnapshot(sizes: [UIContentSizeCategoryExtraLarge])\n```\n\nNote that this will post an `UIContentSizeCategoryDidChangeNotification`,\nso your views/view controllers need to observe that and update themselves.\n\nFor more info on usage, check out the\n[dynamic type tests](Bootstrap/BootstrapTests/DynamicTypeTests.swift).\n\n\n\n## Dynamic Size\n\nTesting the same view with many sizes is easy but error prone. It easy to fix one test\non change and forget the others. For this we create a easy way to tests all sizes at same time.\n\nYou can use the new `haveValidDynamicSizeSnapshot` and `recordDynamicSizeSnapshot`\nmatchers to test multiple sizes at once:\n\n```swift\nlet sizes = [\"SmallSize\": CGSize(width: 44, height: 44),\n\"MediumSize\": CGSize(width: 88, height: 88),\n\"LargeSize\": CGSize(width: 132, height: 132)]\n\n// expect(view).to(recordDynamicSizeSnapshot(sizes: sizes))\nexpect(view).to(haveValidDynamicSizeSnapshot(sizes: sizes))\n\n// You can also just test some sizes:\nexpect(view).to(haveValidDynamicSizeSnapshot(sizes: sizes))\n\n// If you prefer the == syntax, we got you covered too:\nexpect(view) == snapshot(sizes: sizes)\nexpect(view) == snapshot(sizes: sizes)\n```\n\nBy default, the size will be set on the view using the frame property. To change this behavior\nyou can use the `ResizeMode` enum:\n\n```swift\npublic enum ResizeMode {\n  case frame\n  case constrains\n  case block(resizeBlock: (UIView, CGSize) -\u003e Void)\n  case custom(viewResizer: ViewResizer)\n}\n```\nTo use the enum you can `expect(view) == dynamicSizeSnapshot(sizes: sizes, resizeMode: newResizeMode)`.\nFor custom behavior you can use `ResizeMode.block`. The block will be call on every resize. Or you can\nimplement the `ViewResizer` protocol and resize yourself.\nThe custom behavior can be used to record the views too.\n\nFor more info on usage, check the [dynamic sizes tests](Bootstrap/BootstrapTests/DynamicSizeTests.swift).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashfurrow%2Fnimble-snapshots","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashfurrow%2Fnimble-snapshots","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashfurrow%2Fnimble-snapshots/lists"}