pointfreeco / swift-snapshot-testing

📸 Delightful Swift snapshot testing.

Home Page:https://www.pointfree.co/episodes/ep41-a-tour-of-snapshot-testing

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What's the way to use `assertSnapshot` in async test?

valeriyvan opened this issue · comments

Please look below example of async test. Test with XCTAssertEqual works as expected but same test with assertSnapshot crashes.

What's the way to use assertSnapshot in async test?

struct AsyncSequenceExample: AsyncSequence {
    typealias Element = Int

    func makeAsyncIterator() -> AsyncIterator {
        print()
        return AsyncIterator()
    }

    struct AsyncIterator: AsyncIteratorProtocol {
        var current = 1

        mutating func next() async throws -> Element? {
            print("enter")
            try await Task.sleep(nanoseconds: 100_000_000) // Simulate an asynchronous operation
            defer { current += 1 }
            guard Int.random(in: 0..<100_000_000) > 1_000_000 else {
                return nil
            }
            print(current)
            return current
        }
    }
}

class MyTests: XCTestCase {
    func testAsyncSequence() async throws {
        let asyncSequence = AsyncSequenceExample()

        var result: [Int] = []
        do {
            for try await element in asyncSequence {
                result.append(element)
            }
        } catch {
            XCTFail("Unexpected error: \(error)")
        }

        // This test works as expected
        // XCTAssertEqual(result, [1, 2, 3])

        // But this crashes
        assertSnapshot(of: result.description, as: .lines)

    }
}

The problem is the use of XCTWaiter.wait inside of verifySnapshot. Using the synchronous wait function in an asynchronous context is a known issue (that's why Apple introduced await fulfillment(of:).

Is this crash Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Current context must not be nil'? If so, I am hitting that issue too in an async test :/ is there any workaround that we can use until the library can be updated to support some sort of await assertSnapshot method?

Actually, I did find that marking all the async tests as @MainActor works, so there's that... still frustrating but I suppose it works now :/