SnapshotKit provides a set of wrappers around FBSnapshotTestCase to make it easier to test common use-cases for iOS apps.
This project is currently in an early state and the public interface is likely to change as it matures. Please provide and feedback or suggestions on what would work best for your use-case.
In particular, the projects I have been using this with so far are iPhone-only, so I have not yet added a built-in interface iPad sized screenshots.
I'd also like to provide a better interface for specifying which devices sizes you care about. For example, for apps supporting iOS 10 and later, there's really no need to be running screenshot tests against the iPhone 4s device size, although that size is still included with allPhoneSizes
right now. Potentially this would look something like adding the ability to say snapshot.registerSizes([.iPhone5, .iPhone6, .iPhone6plus])
from the test class's setUp
.
I'm not convinced that I'm satisfied with the naming convention of the screenshots that are currently generated, and need to evaluate whether additional controls need to be exposed for overriding the defualt behavior of screenshot naming.
The easiest way to install SnapshotKit is with CocoaPods:
Once I get a little further along, I'll officially publish to the pod repo, but for now you can point directly to this repo.
pod 'SnapshotKit', :git => '[email protected]:johntmcintosh/SnapshotKit.git', :branch => 'master'
Make your test class a subclass of SnapshotKitTestCase
and you will have access to a new snapshot
property on the test class. This contains an instance of SnapshotKitTestController
which provides the wrappers for the snapshot tests.
let view = CustomView()
// Basic usage
snapshot.verify(view)
// Automatically test the view on all phone all phone sizes
snapshot.allPhoneSizes().verify(view)
// Test a view that's auto-sized to its content
snapshot.sizeToFit().verify(view)
// Test a fixed width with auto-expanding height
snapshot.fixed(width: 400.0).verify(view)
// Test a fixed height with auto-expanding width
snapshot.fixed(height: 400.0).verify(view)
// Test the view at a fixed size
snapshot.fixed(size: CGSize(width: 400.0, height: 200.0)).verify(view)
Also works with view controllers:
let vc = CustomViewController()
// Test a view controller
snapshot.allPhoneSizes().verify(vc)
// Test a view controller, but shorten by the height of a navigation bar
snapshot.allPhoneSizes().excludeNavigationBar().verify(vc)
Start by making your test file a subclass of SnapshotKitTestCase
rather than FBSnapshotTestCase
.
@testable import MyApp
import SnapshotKit
import XCTest
class CustomViewTests: SnapshotKitTestCase {
...
}
Next, control the recording mode just as you do with FBSnapshotTestCase (SnapshotKitTestCase is a subclass of FBSnapshotTestCase).
override func setUp() {
super.setUp()
recordMode = true
}
Finally, write your test cases. In this example,
func testStandardContent() {
let view = CustomView.makeWithStandardContent()
snapshot.allPhoneSizes().excludeNavigationBar().verify(view)
}
func testExtremeOverflow() {
let view = CustomView.makeWithOverflowContent()
snapshot.allPhoneSizes().excludeNavigationBar().verify(view)
}
See example of a full test file and the generated snapshots.
If I have something like a table cell that needs to be tested with the same configuration multiple times, I like to add an extension on SnapshotKitTestController
to be able to quickly apply that configuration on all tests:
extension SnapshotKitTestController {
func feedItemSize() -> SnapshotKitTestController {
return fixed(size: CGSize(width: 375.0, height: 51.0))
}
}
class FeedItemViewTests: SnapshotKitTestCase {
func testStandardContent() {
let view = FeedItemView.makeWithStandardContent()
snapshot.feedItemSize().verify(view)
}
func testImageContent() {
let view = FeedItemView.makeWithImageContent()
snapshot.feedItemSize().verify(view)
}
}
I have found it helpful to add some extensions to my test cases to remove some duplicate code from the cases themselves. For example, when I'll be using a similar view in multiple test cases, I'll add an extension on that view for generating the test instances.
extension CustomView {
static func makeWithStandardContent() -> CustomView {
let view = CustomView()
view.text = "Lorem ipsum dolor."
return view
}
static func makeWithOverflowContent() -> ScannerOverlayView {
let view = CustomView()
view.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum quis turpis eget elit porta efficitur at vel ante. Proin sit amet ipsum eget nibh varius accumsan eu ut leo."
return view
}
}
SnapshotKit requires iOS 9.0 or higher.
SnapshotKit was created by John McIntosh.
SnapshotKit is available under the MIT license. See the LICENSE file for more info.