UIView.animateWithDuration:animations:completion:在XCTest中被取消

时间:2019-05-20 08:59:58

标签: ios swift animation uiview xctest

我正在尝试对UIView上扩展名为animateWithDuration:animations:completion:的扩展进行单元测试。

不幸的是,测试用例中的所有动画都会立即被取消,因此完成模块的isFinished参数始终为false

有人知道如何在测试用例中制作动画吗?

这是我的游乐场代码:

import UIKit
import XCTest

extension UIView {
    func fadeOut(duration: TimeInterval, completion: ((Bool) -> Void)?) {
        UIView.animate(withDuration: duration,
                       animations: {
                            self.alpha = 0.0
                       },
                       completion: { isFinished in
                            self.isHidden = isFinished

                            completion?(isFinished)
                       })
    }
}

class UIViewTests: XCTestCase {

    func testFadeView() {
        // Given
        let expectation = self.expectation(description: "Expect completion handler to be called.")

        let view = UIView()
        view.alpha = 1.0

        // When
        print("Date before", Date())
        view.fadeOut(duration: 1.0) { (isFinished) in
            print("Date completed", Date())
            print("isFinished", isFinished)

            expectation.fulfill()
        }

        // Then
        wait(for: [expectation], timeout: 1.1)

        XCTAssertTrue(view.isHidden) // <- this assertion always fails, cause `isFinished` inside the completion handler is always `false`.
        XCTAssertEqual(view.alpha, 0.0, accuracy: CGFloat.ulpOfOne)
    }
}

UIViewTests.defaultTestSuite.run()

断言XCTAssertTrue(view.isHidden)总是失败。此外,日志语句输出:

Date before 2019-05-20 23:30:35 +0000
Date completed 2019-05-20 23:30:35 +0000

所以基本上动画会立即被杀死。

1 个答案:

答案 0 :(得分:1)

要使动画带有正确的标记,视图需要在可见的UIWindow中显示。

let actualWindow = UIApplication.shared.keyWindow
actualWindow.addSubview(view)

以此,您的测试成功。别忘了

view.removeFromSuperview()

进行清理。

现在它正在运行,您可以通过减少持续时间来节省时间。我使用duration: 0.001

将测试降低到23ms