swift-snapshot-testing
swift-snapshot-testing copied to clipboard
assertSnapshot causes memory leak
Describe the bug
When using assertSnapshot
the view is not released at the end of the test
To Reproduce You can reproduce this with the attached project: SnapshotIssue.zip
final class SnapshotIssueTests: XCTestCase {
func testExample() {
let controller = UIStoryboard(name: "Main", bundle: Bundle(for: ViewController.self)).instantiateInitialViewController()!
trackForMemoryLeaks(controller)
assertSnapshot(matching: controller, as: .image)
}
}
private extension SnapshotIssueTests {
func trackForMemoryLeaks(_ instance: AnyObject, file: StaticString = #filePath, line: UInt = #line) {
addTeardownBlock { [weak instance] in
XCTAssertNil(instance, "Instance should have been deallocated. Potential memory leak!", file: file, line: line)
}
}
}
Expected behavior When snapshot test is done, the view should be released
Screenshots
Environment
- swift-snapshot-testing version: 1.9.0
- Xcode: 13.3.1
- Swift: 5
- OS: iOS 15.4
Does this issue persist when using SwiftUI views?
I have not tried with a SwiftUI view. But I can say that this doesn't happen with plain UIViews. It seems to affect only UIViewControllers.
I have had a similar issue with 1.10.0 where when the view is passed, the assert snapshot returns and when there is a view controller with a hard dependency on a UINavigationController and the UI navigation controls making the controller a child of the UINavigationController resolves or at least permits the snapshot test to return.
Do you have any way to workaround this issue? This seems to happen in my case with a SwiftUI view and TCA. The store is somehow still around after the test is finished and causes test failures coming from Unimplemented dependencies (which seem to have escaped the task local scope by then).
My chain of events ist basically
start of snapshot test
snapshot test passed
start of another test (testing the reducer's functionality using TestStores)
action received in store from snapshot test
Unimplemented: @Dependency(\.date)
@stephencelis I noticed you also use snapshot tests for the GameOverView
in isowords (which also has long running tasks added to a task group from the task
action). But you don't run in to issues because you don't create a ViewState
in the view store's observation closure which accesses a Dependency
inside its init. (This is how it used to look pre observation).