xcuitestios-darkmodexctestcasedarkmodesnapshot-testing

Testing Dark Mode using snapshot testing


Any leads how can we use Snapshot testing to test darkmode implementation? Or any other testing strategy for dark mode on iOS.

When XCUITest is one of the options along with XCTest (unit-test). The problem with UITest in dark mode means for every app flow it needs to be run twice.

Will Unittest cases be enough to suffice testing needs for dark mode? Can you think of any use case which won't be covered using only unit testing for dark mode?


Solution

  • I use FBSnapshotTestCase to get light & dark snapshots in a unit test target:

    final class ViewControllerSnapshotTests: FBSnapshotTestCase {
        private var sut: ViewController!
    
        override func setUp() {
            super.setUp()
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            sut = storyboard.instantiateViewController(
                identifier: String(describing: ViewController.self)
            )
    
            usesDrawViewHierarchyInRect = true
            recordMode = false // set to true to record snapshots
        }
    
        override func tearDown() {
            sut = nil
            super.tearDown()
        }
    
        func test_light() {
            sut.overrideUserInterfaceStyle = .light
            FBSnapshotVerifyViewController(sut)
        }
    
        func test_dark() {
            sut.overrideUserInterfaceStyle = .dark
            FBSnapshotVerifyViewController(sut)
        }
    }
    

    This produced the following snapshots:

    test_dark@2x.png and test_light@2x.png

    The tricks were:

    The usual advantages of snapshot tests over UITests apply. Snapshots are slower than normal unit tests, but much faster than UITests because we don't have to navigate through the app to reach each view controller.

    How fast? Here's my timing, running on a 2015 MacBook Pro.

    Test Suite 'ViewControllerSnapshotTests' started at 2021-04-20 21:35:26.856
    Test Case '-[SOTests.ViewControllerSnapshotTests test_dark]' started.
    Test Case '-[SOTests.ViewControllerSnapshotTests test_dark]' passed (0.101 seconds).
    Test Case '-[SOTests.ViewControllerSnapshotTests test_light]' started.
    Test Case '-[SOTests.ViewControllerSnapshotTests test_light]' passed (0.029 seconds).
    Test Suite 'ViewControllerSnapshotTests' passed at 2021-04-20 21:35:26.987.
       Executed 2 tests, with 0 failures (0 unexpected) in 0.130 (0.131) seconds