代码之家  ›  专栏  ›  技术社区  ›  Wazza

测试显示和消失的动画标签的文本

  •  7
  • Wazza  · 技术社区  · 7 年前

    private func registerNewUser(email: String, password: String, confirmationPassword: String) {
        if password == confirmationPassword {
            firebaseData.createUser(email: email, password: password, completion: { (error, _ ) in
                if let error = error {
                    self.showToast(in: self.view, with: error.localizedDescription)
                } else {
                    self.showToast(in: self.view, with: "Registered succesfully")
                    self.signInUser(email: email, password: password)
                }
            })
        } else {
            //raise password mismatch error
            print("password mismatch error")
        }
    }
    
    func showToast(in toastSuperView: UIView, with text: String) {
        let toastLabel = ToastLabel()
        toastLabel.text = text
        toastSuperView.addSubview(toastLabel)
        layoutToastLabel(toastLabel)
        animateToastLabel(toastLabel)
    }
    
    private func layoutToastLabel(_ toastLabel: ToastLabel) {
        toastLabel.centerYToSuperview()
        toastLabel.pinToSuperview(edges: [.left, .right])
    }
    
    private func animateToastLabel(_ toastLabel: ToastLabel) {
        UIView.animate(withDuration: 2.5, delay: 0, options: .curveEaseOut, animations: {
            toastLabel.alpha = 0.0
        }, completion: { _ in
            toastLabel.removeFromSuperview()
        })
    }
    

    我只是想测试从firebase收到的错误文本是否在用户输入一封已经收到的电子邮件后出现。

    func testRegisteringWithUsedEmailDisplaysFirebaseError() {
        let email = registeredEmail
        let password = "password"
    
        welcomeScreenHelper.register(email: email,
                                     password: password,
                                     confirmationPassword: password,
                                     completion: {
    
            let firebaseErrorMessage = "The email address is already in use by another account."
            XCTAssert(self.app.staticTexts[firebaseErrorMessage].exists)
        })
    }
    
    func register(email: String, password: String, confirmationPassword: String, completion: (() -> Void)? = nil) {
        let emailTextField = app.textFields[AccesID.emailTextField]
        let passwordTextField = app.secureTextFields[AccesID.passwordTextField]
        let confirmPasswordTextField = app.secureTextFields[AccesID.confirmPasswordTextField]
        let registerButton = app.buttons[AccesID.registerButton]
    
        emailTextField.tap()
        emailTextField.typeText(email)
        passwordTextField.tap()
        passwordTextField.typeText(password)
        registerButton.tap()
        confirmPasswordTextField.tap()
        confirmPasswordTextField.typeText(confirmationPassword)
        registerButton.tap()
    
        completion?()
    }
    

    当我使用其他工具,如Expection和XCTWaiter时,尽管文本和标签明显出现,但测试仍然没有通过。我从来没有做过这样的测试,所以我不确定我可能会出什么问题,我是否需要做一些不同的事情来测试动画视图或其他东西。

    因此,我可以看到,在播放了一段时间后,当我点击registerButton时,土司会像它应该的那样出现,但测试不会继续,直到它再次消失。我觉得这很奇怪,因为它并没有严格地附加到registerButton作为它自己的视图。

    更新2:

    我的测试更新如下:

    func testRegisteringWithUsedEmailDisplaysFirebaseError() {
    
        welcomeScreenHelper.register(email: registeredEmail,
                                     password: password,
                                     confirmationPassword: password,
                                     completion: {
    
            let firebaseErrorMessage = "The email address is already in use by another account."
    
            let text = self.app.staticTexts[firebaseErrorMessage]
            let exists = NSPredicate(format: "exists == true")
    
            self.expectation(for: exists, evaluatedWith: text, handler: nil)
            self.waitForExpectations(timeout: 10, handler: nil)
            XCTAssert(self.app.staticTexts[firebaseErrorMessage].exists)
        })
    }
    

    override func setUp() {
        app.launch()
        UIView.setAnimationsEnabled(false)
        super.setUp()
    }
    
    override func tearDown() {
        if let email = createdUserEmail {
            firebaseHelper.removeUser(with: email)
        }
        UIView.setAnimationsEnabled(true)
        super.tearDown()
    }
    

    但到目前为止没有运气。我仍然可以在 func register

    1 回复  |  直到 7 年前
        1
  •  4
  •   Alexey Kozhevnikov    7 年前

    在这种测试中,您需要解决几个问题:

    1. DispatchQueue.async 你应该使用 XCTestCase.expectation
    2. UIView.animate UIView.setAnimationsEnabled(false) 并在测试完成后将其启用,这样期望就不会等待动画完成。你可以在 XCTestCase.setUp XCTestCase.tearDown
    3. firebaseData XCTestCase。预料

    所以使用 XCTestCase。预料 + UIView。setAnimationsEnabled(false) XCTestCase。预料 如果超时足够高,也应该可以工作。

    func test() {
        let exp = expectation(description: "completion called")
        someAsyncMethodWithCompletion() {
            exp.fulfill()
        }
        waitForExpectations(timeout: 1) { _ in }
        // assert here
    }
    

    因此,您的测试方法应该是:

    func testRegisteringWithUsedEmailDisplaysFirebaseError() {
        let exp = expectation(description: "completion called")
        welcomeScreenHelper.register(email: registeredEmail,
                                     password: password,
                                     confirmationPassword: password,
                                     completion: { exp.fulfill() })
        self.waitForExpectations(timeout: 10, handler: nil)
        let firebaseErrorMessage = "The email address is already in use by another account."
        XCTAssert(self.app.staticTexts[firebaseErrorMessage].exists)
    }