kif-framework/KIF — pull request #423 by pnc (2014-06-30 17:32:51+00:00)
Title: Wrap all run loop spins in an autoreleasepool block

This increases the realism of KIF tests.

Normally, it appears `CFRunLoop` wraps each run loop iteration in an autorelease pool (via a symbol named `_wrapRunLoopWithAutoreleasePoolHandler`). However, since KIF explicitly spins the run loop from within `XCTestCase`'s internals, it looks like `CFRunLoop` notices that there's already a pushed run loop and does not push an additional one. As a result, objects that would normally be added to the run loop's autorelease pool and released at the end of the loop end up added to the `XCTestCase`'s pool instead, and then aren't deallocated until the end of the test.

Keeping these objects alive until the end of the test changes the behavior of the application significantly, particularly if the `dealloc` methods tear down notifications or similar callback chains. This longer life can lead to tests that don't match up with real-world behavior.

In our case, a call to `swipeViewWithAccessibilityLabel:inDirection:` was calling `[UITouchesEvent -_addTouch:forDelayedDelivery:]`, which eventually retains and autoreleases the presented `UINavigationController`'s `topViewController`. This meant the navigation controller and its children remained live until the end of the test, which did not accurately reflect the behavior of the app when not running from KIF.