UIView.animateWithDuration: анимации: завершение: отменяется в XCTest - PullRequest
2 голосов
/ 20 мая 2019

Я пытаюсь провести модульное тестирование расширения на 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) всегда терпит неудачу.Кроме того, операторы log выводят:

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

Таким образом, анимация в основном убивается немедленно.

1 Ответ

1 голос
/ 21 мая 2019

Чтобы анимация завершилась с правильным флагом, представление должно быть в видимом окне UIW.

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

С этим ваш тест пройден успешно. Не забудьте

view.removeFromSuperview()

убрать.

Теперь, когда он работает, вы можете сэкономить время, уменьшив продолжительность. Я получил тест до 23 мс, используя duration: 0.001

...