{"id":32110078,"url":"https://github.com/andriidoroshko/snappyshrimp","last_synced_at":"2025-10-20T13:53:43.647Z","repository":{"id":62455717,"uuid":"113975531","full_name":"AndriiDoroshko/SnappyShrimp","owner":"AndriiDoroshko","description":"New snapshot testing experience for iOS apps. It runs your tests on all possible screens, orientations, and multitasking modes. It also makes proper snapshots for iPhone X, considering it's shape and safe areas. ","archived":false,"fork":false,"pushed_at":"2020-04-14T08:18:43.000Z","size":1044,"stargazers_count":30,"open_issues_count":5,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-20T13:53:34.906Z","etag":null,"topics":["automation","ios","mobile","screenshot","snapshot","snapshot-testing","ui"],"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/AndriiDoroshko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-12T10:18:28.000Z","updated_at":"2025-10-11T17:10:18.000Z","dependencies_parsed_at":"2022-11-02T00:15:12.882Z","dependency_job_id":null,"html_url":"https://github.com/AndriiDoroshko/SnappyShrimp","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/AndriiDoroshko/SnappyShrimp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndriiDoroshko%2FSnappyShrimp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndriiDoroshko%2FSnappyShrimp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndriiDoroshko%2FSnappyShrimp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndriiDoroshko%2FSnappyShrimp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndriiDoroshko","download_url":"https://codeload.github.com/AndriiDoroshko/SnappyShrimp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndriiDoroshko%2FSnappyShrimp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280102713,"owners_count":26272390,"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","status":"online","status_checked_at":"2025-10-20T02:00:06.978Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["automation","ios","mobile","screenshot","snapshot","snapshot-testing","ui"],"created_at":"2025-10-20T13:53:41.789Z","updated_at":"2025-10-20T13:53:43.640Z","avatar_url":"https://github.com/AndriiDoroshko.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eSnappy Shrimp - New Snapshot Testing Experience\u003c/h1\u003e  \n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.org/AndriiDoroshko/SnappyShrimp\"\u003e\n        \u003cimg src=\"https://travis-ci.org/AndriiDoroshko/SnappyShrimp.svg?branch=master\" alt=\"Build Status\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\" alt=\"Carthage Compatible\" /\u003e\n    \u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift-4.0-orange.svg\" alt=\"Swift 4\" /\u003e\n    \u003ca href=\"https://raw.githubusercontent.com/AndriiDoroshko/SnappyShrimp/master/LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat\" alt=\"MIT LICENSE\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/AndriiDoroshko/SnappyShrimp/releases\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/release/AndriiDoroshko/SnappyShrimp.svg\" alt=\"Releases\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n**Snappy Shrimp** - is a library for snapshot testing. It is based on FBSnapshotTestCase library and actually, it does the same thing - it records a reference image of your view and verifies it every time you launch tests. But how much time does it takes to make tests on all possible devices and in all possible orientations? This library allows you to save your time by decreasing the number of necessary devices up to three - **iPhone**, **iPhone Plus** and **iPad** and you will see why.\n\n[Snappy Shrimp - New Snapshot Testing Experience](#snappy-shrimp---new-snapshot-testing-experience)\n1. [Features](#features)\n\t1. [iPhone, iPhone SE and iPhone Plus examples](#iphone-iphone-se-and-iphone-plus-examples)\n\t2. [iPad with multitasking support examples](#ipad-with-multitasking-support-examples)\n\t3. [iPhone X Example](#iphone-x-examples)\n2. [Requirements](#requirements)\n3. [Install](#install)\n\t1. [Using Carthage](#using-carthage)\n\t2. [Using Cocoapods](#using-carthage)\n4. [Configuring](#configuring)\n5. [How to write tests](#how-to-write-tests)\n6. [Snapshot Testing example](#snapshot-testing-example)\n7. [Automation example](#automation-example)\n8. [Why you need three devices instead one](#why-you-need-three-devices-instead-one)\n9. [Specific notes about snapshot testing](#specific-notes-about-snapshot-testing)\n10. [Contributions](#contributions)\n\n## Features\n\nThings that we've improved to make snapshot testing experience much better:\n- All devices are presented programmatically, including `actual sizes` and `trait collections`;\n- We don't use `Host Application`, so it makes our tests run faster;\n- Improved images naming, by adding to the image name: `device`, `orientation` and `os version`;\n- Implemented `iPhone X` safe areas and masks to capture snapshots exactly as it looks like on a real device;\n- You're able to see how your app looks like in all orientations and in all multitasking modes for iPads;\n\n### iPhone, iPhone SE and iPhone Plus examples\n\n\u003cimg height=\"480\" alt=\"testexample_iphone_8_plus_portrait_ios_11 2 3x\" src=\"https://user-images.githubusercontent.com/31652265/37855836-09be85e0-2efa-11e8-8fb5-66f6e6d486be.png\"\u003e \u003cimg height=\"420\" alt=\"testexample_iphone_8_portrait_ios_11 2 2x\" src=\"https://user-images.githubusercontent.com/31652265/37855837-09dea33e-2efa-11e8-834c-bcae085aaa6d.png\"\u003e \u003cimg height=\"340\" alt=\"testexample_iphone_se_portrait_ios_11 2 2x\" src=\"https://user-images.githubusercontent.com/31652265/37855838-09fdde48-2efa-11e8-85b6-ec5399cbc04a.png\"\u003e\n\n### iPad with multitasking support examples\n\n\u003cimg height=\"530\" alt=\"testexample_ipad_pro12_portrait_fullscreen_ios_11 2 2x\" src=\"https://user-images.githubusercontent.com/31652265/37855639-f772c442-2ef8-11e8-9f0d-fcc9f0ff49a4.png\"\u003e \u003cimg height=\"530\" alt=\"testexample_ipad_pro12_portrait_two_third_ios_11 2 2x\" src=\"https://user-images.githubusercontent.com/31652265/37855641-f7b37802-2ef8-11e8-92cf-52614a905ab3.png\"\u003e \u003cimg height=\"530\" alt=\"testexample_ipad_pro12_portrait_splitview_one_third_ios_11 2 2x\" src=\"https://user-images.githubusercontent.com/31652265/37855640-f79363c8-2ef8-11e8-9c4c-d031495287a7.png\"\u003e\n\n### iPhone X examples\n\n\u003cimg src=\"https://user-images.githubusercontent.com/31652265/37720874-df3e1602-2d30-11e8-9afc-3088ac147b1e.png\" width=\"250\" alt=\"Portrait\"/\u003e \u003cimg src=\"https://user-images.githubusercontent.com/31652265/37720866-dd2479b0-2d30-11e8-83b5-f082aceb4d98.png\" width=\"600\" alt=\"Landscape\" /\u003e\n\n## Requirements\n\n- iOS 9.0+\n- Xcode 9.0+\n- Swift 3.2+\n\n## Install\n\nWe use [Carthage](https://github.com/Carthage/Carthage) to install our framework. \nFollow the link if you don't know how to install Carthage.\n\n### Using Carthage\n\n1. Create `Cartfile` in your project;\n2. Add this repo to the file:\n```\ngithub \"AndriiDoroshko/SnappyShrimp\"\n```\n3. Use to get our library:\n```\ncarthage update --platform iOS\n```\n4. Add both frameworks to `Build Settings/Link Binary With Libraries`\n5. In your test target add the `Run Script`\n\nShell: `/bin/sh`\n```\n/usr/local/bin/carthage copy-frameworks\n```\nInput Files:\n```\n$(SRCROOT)/Carthage/Build/iOS/FBSnapshotTestCase.framework\n$(SRCROOT)/Carthage/Build/iOS/SnappyShrimp.framework\n```\n\n### Using Cocoapods\n\n1. Create Podfile\n2. Add the following line to it:\n```\npod 'SnappyShrimp'\n```\n3. Install this and other dependencies in your podfile using:\n```\npod install\n```\n\n## Configuring\n\n1. Create two schemes with your test target - first for `testing`, second for `recording`.\n2. Add evnironmental variables to your test schemes: \n- `FB_REFERENCE_IMAGE_DIR` - folder for reference images - `$(SOURCE_ROOT)/Tests/ReferenceImages` e.g;\n- `IMAGE_DIFF_DIR` - folder for failed and difference images - `$(SOURCE_ROOT)/Tests/FailureDiffs` e.g..\n- `RECORD_MODE` - variable to decide if tests should run in record mode. In `Record` scheme, set this value as `TRUE`, to record new references.\n3. In case you want to have different snapshots on screens with different display gamut (`P3` and `sRGB`), you should set `isGamutSupportEnabled` value to true.\n4. If you want your custom implementation of `record mode` using , just setup the `recordMode` variable.\n\nExample of the setup method:\n```swift\noverride open func setup() {\n\tsuper.setup()\n\trecordMode = #?@!\u0026\n\tisGamutSupportEnabled = #?@!\u0026\n}\n```\nNote: this is our implementation of Snapshot tests implementation. After install, you're free to configure it as you want.\n\n## How to write tests\n\n1. Add new **Unit test** target;\n2. Create new class inherited from `SnapshotTest`;\n3. Inside the class, create `test...()` method;\n4. Create and setup your `ViewController` for testing;\n5. Use method `verify`, that needs your `controller` and a `Presentation` object, that describes a device.\n \nPresentations of all devices are specified in `Device` enum. Here's an example\n\n```swift\nverify(controller, for: Device.iPadPro9.portrait.oneThird)\n```\n\nThat's how the method looks like\n```swift\nverify(controller: UIViewController, \n\tfor presentation: Presentation)\n```\nWhere:\n- `controller` - your view controller that you want to test;\n- `presentation` - contains information about device, including size, trait colections, masks, safe areas and name;\n\nTo create snapshot with custom traits and size, just create a `Presentation` object on your own.\n\n### Example:\n```swift\npublic let smallViewController = Presentation(\n            name: \"Custom small window\",\n            size: CGSize(width: 250, height: 375),\n            traitCollection: UITraitCollection(\n                traitsFrom: [Display.InterfaceIdiom.phone,\n                             Display.SizeClass.Vertical.compact,\n                             Display.SizeClass.Horizontal.compact,\n                             Display.Scale.x2]))\n```\n\n## Snapshot Testing example\n\n\u003e [Example of using Snappy Shrimp framework](https://github.com/AndriiDoroshko/SnappyShrimp/tree/master/SnappyShrimpTests)\n\nOur example of snapshot testing has two schemes - one for recording, another one is for testing. We've picked this way to make things faster and easier.\n\nTo run our test example, we're using [Fastlane](https://github.com/fastlane/fastlane).\nIt allows you to run testing or recording with a simple command\n```\nfastlane test\n```\nor\n```\nfastlane record\n```\nInside the Fastfile everything is simple. A `scan` action with required scheme and devices.\n```ruby\n  lane :test do\n    scan(\n      scheme: 'SnappyShrimpTests',\n      devices: ['iPhone 8', 'iPhone 8 Plus', 'iPad Pro (12.9-inch)']\n    )\n  end\n  lane :record do\n    scan(\n      scheme: 'SnappyShrimpRecord',\n      devices: ['iPhone 8', 'iPhone 8 Plus', 'iPad Pro (12.9-inch)']\n    )\n  end\n```\nThis is an example of the class for snapshot testing. All you need is to setup your controller and to call `verify` method with `Presentation` that you want to test.\n\n```swift\nimport SnappyShrimp\n\nclass SnappyShrimpTests: SnapshotTest {\n    \n    func testExample() {\n        let vc = ViewController()\n        \n        verify(vc, for: Device.iPhone8.landscape)\n        verify(vc, for: Device.iPhone8.portrait)\n        verify(vc, for: Device.iPhoneSE.portrait)\n        \n        verify(vc, for: Device.iPhone8Plus.landscape)\n        verify(vc, for: Device.iPhone8Plus.portrait)\n        \n        verify(vc, for: Device.iPadPro12.portrait.fullScreen)\n        verify(vc, for: Device.iPadPro12.portrait.oneThird)\n        verify(vc, for: Device.iPadPro12.portrait.twoThirds)\n        \n        verify(vc, for: Device.iPhoneX.portrait)\n        verify(vc, for: Device.iPhoneX.landscapeLeft)\n        verify(vc, for: Device.iPhoneX.landscapeRight)\n}\n```\n\n## Automation example\n\nWe've used snapshot testing to verify that our app looks exactly as we expect in all cases. But obviously, no one wants to run tests before pushing, or simply forgets, so we run these tests on the CI. But if the tests fail on the CI, you just can't take a look what exactly has happened there and you have to run tests on your own machine. \n\nSo we found a way for that, We upload those images out of Travis in cloud storage, and then, if that's a pull request, they're posted in PR comments, if no, they're comming directly to our slack channel.\n\nThings that we're using for that:\n\n- `Fastlane` - if you still don't use fastlane, you better start. It allows you to run tests much easier and has a lot of options for build and testing. \n\n- `AWS S3` - best storage for your files, but you can use any you want.\n\n- `Danger` - provides you with an ability to post comments, warnings, and failures to GitHub PR. It supports both `Swift` and `Ruby`, so you can write your own script, that will insert failed images into PR comments. With Danger, you will always have only one comment, that will be updated. If there will be no failurs, warnings or messages, it will remove comment.\n\n## Why you need three devices instead one\n\nThe main idea was to use only one device with iOS SDK for snapshot testing, when the controller will have all needed `trait collections`, including size classes, idiom, scale and so on. But in fact, you can't override device specific trait collections, like `scale`, `gamut`, `idiom`. So when you launch tests for iPhone Plus on an iPad, you may have wrong behavior, because it will have scale @2 instead of @3, same with the idiom. That is why you need at least three. If you want to test @1 scale (old iPads or iPhone 3GS) you should add more, obviously. \n\n## Specific notes about snapshot testing\n\nThere're some things that you should note from our own experience.\n\n**1. Always use the same devices for testing.**\n\nFirst of all, because we didn't add differences for devices with different gamut - SRGB and P3. So, when you run snapshot tests on iPhone 6 Plus and iPhone 7 Plus, you will have tests failed, but you will have empty difference images and both reference and failed images will look absolutely the same. But for the machine, there is a difference. So, if you see an empty diff in your folder, first of all, make sure that you're running on the same device, that was used when you were writing these refs.\n\n**2. Issues with empty diffs after layout updates**\n\nIf for the previous note there is an explanation, for the next one I haven't found one. We've had some issues when we've had empty diffs after we've changed view hierarchy. We've simply added an empty view, that served as a container and some of the tests have failed. The only way here - record new refs. The issue can be in the original framework's issue, or in the iOS SDK. Had no time to research that issue. Feel free to share your thoughts about that.\n\n## Contributions\n\nFeel free to contribute to make that framework even better. Here's small check list that you should read:\n\n- Read [Contributions](https://github.com/AndriiDoroshko/SnappyShrimp/tree/master/CONTRIBUTION.md) guide first;\n- Check already opened issues and requirements file if your issue is already mentioned, or in progress;\n- Open an issue;\n- Create a PR with your fixes or improvements, if you have some.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandriidoroshko%2Fsnappyshrimp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandriidoroshko%2Fsnappyshrimp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandriidoroshko%2Fsnappyshrimp/lists"}