发布于 2016-03-10 04:36:54 | 270 次阅读 | 评论: 0 | 来源: 分享

这里有新鲜出炉的精品教程,程序狗速度看过来!

Xcode 编程开发软件

Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X,iOS的应用程序。其运行于苹果公司的Mac操作系统下。


在下面的章节,我会谈论两个框架之间最大的区别。

灵活性

那么,我说干就干,开始为 ImagePickerSheetController 重写 UI 测试代码,我的开源项目之一。它本质上是在 iOS iMessage 选择图片的自定义操作表(action sheet)。

我第一个想重写的是一个非常基本的测试。简单地测试下当点击取消按钮时,控制器是否会撤回。


func testDismissal() {
    let imageController = ImagePickerSheetController()
    imageController.addAction(ImageAction(title: “Cancel”))
    rootViewController.presentViewController(imageController, animated: true, completion: nil)
    tester().tapViewWithAccessibilityLabel(“Cancel”)
    tester().waitForAbsenceOfViewWithAccessibilityIdentifier(ID)
}

虽然这看起来非常简单,但这使用 XCTest 不可能实现。问题是,Xcode 的 UI 测试不允许访问实际的应用。API 提供的只是充当个代理。试图直接检索一个视图而不是使用 XCUIElement,这是行不通的,XCUIElement 只是用来展示视图。

在 WWDC 开发工具实验室有人告诉我,XCTest 的主要目标是让应用更容易测试。使用这个框架还是很明智的,于是我开始重写我的一个叫 Crimson 的应用测试。

Crimson 键盘显示了字母“E”的不同声调。

经过几个基本测试后,我开始对“声调视图”进行操作。它显示了一个特定字母的不同声调。我想测试的是下面两点:

  • 当视图显示时,第一个字母,在这里是“e”,应被选中
  • 声调视图的颜色应与键一致

我初以为不可能写这测试。和之前一样,你不能只通过审查实际的视图来检查属性。在我仔细查阅文档一两分钟后,我偶然发现 XCUIElement 的实用属性 value


/*! The raw value attribute of the element. Depending on the element, the actual type can vary. */
var value: AnyObject? { get }

它所做的就是返回底层 UI 元素的 accessibilityValue。这让测试访问属性成为可能。所以,我需要唯一做的就是设置声调视图的 accessibilityValue


class AccentView: UIView {
    var selectedLetter: String {
        didSet {
            accessibilityValue = selectedLetter
        }
    }
}

直到我想检测颜色,这一切都进展顺利。由于 accessibilityValue 是字串类型而不是字典,它不可能再访问第二个属性。除此之外,accessibilityValue 就像是用户面对的 accessibilityIdentifier 一样。把 accessibilityValue 设置成模糊值,如一种颜色,是种非常不好的做法,而且完全违背了目的。

因此本次测试也是不可能实现的。虽然很容易检查元素的 frame 和 label 值,但它几乎不可能用来测试其他东西。

性能

为了比较两种框架的性能,我为示例项目写了 3 份测试。为了模拟一个合理的测试组,每个测试都执行 20 遍,使得总共有 60 个测试。

对于第一次测量,我实现了文档中的测试。对于 XCTest,这意味着我会在每次测试后重新运行该应用。KIF 不支持这样,这让它在第一个比较中显得比较快速。

第二次测量通过返回导航而不是重新运行,重置了目标应用的状态。

第三次测量,我又取消了所有的动画。

因为 Xcode 7 不断崩溃,我不得不将迭代的次数减少到 5,然后将结果乘以 4。

正如我们在第一次比较中看到的,为每个规格重新运行应用,使得该测试组极其缓慢。令人惊讶的是 UI 测试模版建议使用这种重置方式,而不是通过导航,因为在大多情况下,没必要使用这种方式。

第二次比较显示,在正常情况下,XCTest 比 KIF 稍微快一点。需要注意的是,在一个比较大的且每天需要多次评估的测试组中,10 秒就可以省下大量的时间。

最后的比较中,XCTest 让人眼前一亮。然而,并不是每个项目都可以禁用所有动画。试想一个带许多自定义过渡效果的项目,测试组还是应确认过渡的正常运行。

对此的解决方案就是,把测试组分成不同运行环境的类,以控制应用的配置。


class UITests: XCTestCase {
    private var launched = false
    let app = XCUIApplication()
    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        launchIfNecessary()
    }
    private func launchIfNecessary() {
        if !launched {
            launched = true
            app.launchEnvironment = [“animations”: “0”]
            app.launch()
        }
    }
    func testDetail() { ... }
    func testPopover() { ... }
    func testActionSheet() { ... }
}

然后,AppDelegate 根据运行环境进行配置。


class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        if NSProcessInfo.processInfo().environment[“animations”] == “0” {
            UIView.setAnimationsEnabled(false)
        }

        ...
        return true
    }
}

这可以大大减少你等待测试通过的时间。

总结

XCTest 可以让我们很容易编写简单的 UI 测试。而想要更高级的测试则是很困难甚至是不可能的。而 KIF 则更为灵活些。

然而,相比 KIF,XCTest 在查找 UI 元素上稍快些。在禁用动画的情况下,XCTest 是非常快。

虽然我希望 Xcode 内置的 UI 测试可以帮助我重写所有项目测试,但是我放弃了。我根本无法找到可以编写所有测试的方式。

干货



最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务