Xcode swift UI Testing compare two screenshots

2.8k views Asked by At

Basically what I have is a list of items and i can create a new item in that list using a button.

Now I want to test whether the item is added in the list when button is clicked or not.

While creating a test case for this, i thought of taking screenshots before and after tapping button and comparing them to know if item is added. But now i am stuck as how to compare two screenshots.

PS: List is complex and items may contain different data.

private func takeScreenshot() -> XCUIScreenshot{
    return XCUIScreen.main.screenshot()
}


private func testElements(){
    let app = XCUIApplication()
    app.buttons["List Items"].tap()
    app.tables["OuterTable"].cells.allElementsBoundByIndex.first?.tap()
    let createBar = app.otherElements["createBar"]
    let button = app.buttons["CreateButton"]
    let initialScreenshot = takeScreenshot()
    button.tap()
    let newScreenshot = takeScreenshot()
    //Compare initialScreenshot and new Screenshot
}

PS: List is displayed in bottom up manner just like you see chats new items would be added at bottom.

2

There are 2 answers

1
bandejapaisa On

There is a library called iOSSnapshotTestCase(FBSnapshotTestCase) that does just this. Once a Facebook project, now an Uber project.

iOSSnapshotTestCase

It is setup to take screenshots of your views/view controllers and then on subsequent test runs, it will compare your views with the saved snapshot image, and produce an output image showing any differences.

I've read from https://www.objc.io/issues/15-testing/snapshot-testing/ that:

"It makes the comparison by drawing both the view or layer and the existing snapshot into two CGContextRefs and doing a memory comparison of them with the C function memcmp()."

0
Jochen Holzer On

You can compare the raw data of the screenshot images using the pngRepresentation property:

let expectedResult = initialScreenshot.pngRepresentation == newScreenshot.pngRepresentation

XCTAssert(expectedResult, "the screenshots don't match")