Snapshot testing Comparison is almost the silver bullet for pixel perfection and a very effective way in gaining more coverage for your code test a much neater [also make more sense] to test UI Components and the good thing about it is it can be used as a part of a UITest or UnitTest.
The most two popular snapshot testing libraries available [iOSSnapshotTestCase] which was written at Facebook and now maintained by Uber and Alan zeino and the other one by pointfree [swift-snapshot-testing] both are awesome and very useful libraries, however today I will be explaining my concepts through the usage of "swift-snapshot-testing" as it is in my humble opinion more powerful than [iOSSnapshotTestCase] due to the fact that it can compare more than just the image layer (e.g. the view hierarchy and URL requests), more about its abilities it here.
If you have a class for custom button and you want to test the button in "off" state will always be rendered the same, lets consider the following code for the button:
now lets write the snapshot test
We first need to create the button, I wrote this simple button class
if you check the code, you will notice that it is a very simple button with two states (on and off) through an `enum` `ButtonState` and it gets its rendering state via the `viewModel` `CustomButtonViewModel`.
It will be also helpful to have a viewController with helper methods to add pre-defined buttons as needed, checkout this one
awesome now if you run you will get the following view
Not that complicated, but super enough to meet its purpose for now.
moving on to write the actual test, lets create test class file with `SnapshotTesting` framework imported, notice that there is no need to conform to specific protocol or be subclassed, check the code below with the simple test case written
The api is straight forward, no need also to record as the record will be automatically done in case an image is not found for comparison and fails the first time, note that the code will be compared with , however if you always want the comparison to be done against certain devices or size classes regardless of the running one, for example on `iPhone X`
another very powerful feature of the library, is that it also can assert against the view hierarchy, which has a similar api, I am fond of that as it can spot many bugs easily, also when upgrading the iOS where in many occasions a fuck up happens in rendering due to Layout API changes
now imagine that there is a failure, it can be easily detected within the xCode as they are reported via XCTAttachements
It doesn't make sense to write about all of the api here, it is well documented, my favorite strength point is that
the images are stored in the same path regardless of the scheme, for me this is a great win since I had to hard code/ change default paths in workspace projects, in-order to have a scheme which runs all the tests
In conclusion, with such easy API , it became easier than ever to integrate such tests into your project and to be part of the testing strategy you have, I would even go more and say that it might be the minimum test you should write in your project, in case there was a tight timeline.
So How to put a test plan :
1 - Unit Tests [for models/ functions] .
2- Standalone ScreenShots [UIViewController, CustomComponents]
3- UI Tests [Mixed Mode between functionality and screenshots] for UAT & Regression Automation
In a following article I will write my vision of how to combine UITests and Screenshot testing to cover functionality and pixel perfection at the same time or requests generation.