ashfurrow / Nimble-Snapshots

Nimble matchers for FBSnapshotTestCase.
https://medium.com/cocoaacademymag/unit-testing-uiview-with-nimble-snapshot-651a7c5a5e93
MIT License
317 stars 100 forks source link

One snapshot to test them all #211

Open Ripcord715 opened 3 years ago

Ripcord715 commented 3 years ago

Hello!

I'm a QA person trying to set Nimble-Snapshots up, and it's come to my attention that my devs like to run their unit tests with various device simulators (iPhone 11, iPhone X, iPad, etc.). I can't seem to figure out how to set it up so I can record one snapshot for a particular screen, and they can run their tests using any device simulator they like.

I've tried setting up a dynamic size test for a particular size, but if I record it on an iPhone 11 I must still test on an iPhone 11. The same for device agnostic snapshots.

Assuming this is even possible I realize I may have to at least have one snapshot for iOS 14, and one for iOS 13.6, but any help help you all can give this super novice dev would be greatly appreciated.

Thank you very much, and apologies if this isn't the correct place to ask this.

ashfurrow commented 3 years ago

Hi there, and thanks for the question. This is the exact right place.

So let's see if I understand – the question is how developers can run their unit tests across many different device simulators and get a reliable answer? It's a tricky problem because, just like iOS versions, the emulated hardware can create snapshot differences. At Artsy, we rely on using the same device simulator for unit testing (same iOS version and same device).

We try to do our best with this testing utility, which tries to mimic what an actual device would be. The code is Objective-C and we haven't used it for new tests in a while (we've moved to React Native).

https://github.com/artsy/eigen/blob/156ff472a15ee63493a60344e30f4bee3a532f3e/Artsy_Tests/Supporting_Files/ARTestContext.m

Here is an example use:

https://github.com/artsy/eigen/blob/156ff472a15ee63493a60344e30f4bee3a532f3e/Artsy_Tests/View_Controller_Tests/Components/ARSerifNavigationViewControllerSpec.m#L26-L59

I hope that helps! I would highly recommend your dev team all use the same simulator and test device for local unit tests, though. It's the best way to get reliable results.

karpelcevs commented 3 years ago

@MrRipcord

One of the things you could try is have an extension such as this:

extension XCTestCase {
    var sanitizedName: String? {
        let characterSet = CharacterSet(charactersIn: "[]+-")
        return self.name.components(separatedBy: characterSet).joined()
    }

    func versionedName(name: String?) -> String? {
        if let testName = name {
            return "\(testName)_\(phoneName())"
        }

        return nil
    }
}

and phoneName() can be device ID the way you want. Then you can just run tests with multiple targets and snapshots won't be overridden.