UITestHelper 1.5.0

UITestHelper 1.5.0

测试已测试
语言语言 SwiftSwift
许可证 NOASSERTION
发布最新发布2019年2月
SPM支持 SPM

evermeer 维护。



UITestHelper

Issues Documentation Stars Downloads

Version Language Platform License

Git Twitter LinkedIn Website eMail

一般信息

当创建 UI 测试时,您会发现在很多情况下您会重复相同的代码片段。UITestHelper 库将尝试减少这种情况。此外,还提供了一些功能,可以提高代码对错误标识符的抵抗力。

在自己的应用中使用 UITestHelper

'UITestHelper' 通过依赖管理器 CocoaPods 提供。您必须使用 CocoaPods 版本 1.1 或更高版本。

下面是一个示例 Podfile。您需要在 UI 测试目标中添加 UITestHelper pod,如果想要使用 GlobalHelper 函数,还必须将 UITestHelper/App pod 添加到您的应用目标中。

source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
workspace 'UITestHelper'

target 'UITestHelperApp' do
  platform :ios, '9.0'
  pod 'UITestHelper/App'
end

target 'UITestHelperUITests' do
    platform :ios, '9.0'
    pod 'UITestHelper'
end

# This will make sure your test project has ENABLE_BITCODE set to NO 
post_install do |installer|
    installer.pods_project.targets.each do |target|
        if ['UITestHelperUITests'].include? target.name
            target.build_configurations.each do |config|
                config.build_settings['ENABLE_BITCODE'] = 'NO'
            end
        end
    end
end

指导

通过 .tryLaunch 启动并连接到您的应用

如果您使用的是 XCode 构建服务器并在模拟器上运行测试,那么可能会发生服务器过于繁忙导致您无法连接到模拟器的情况。为此,tryLaunch 函数内置了重试机制。默认情况下,它将重试 10 次(可以通过参数进行修改)。在 tryLaunch 之后,测试类中的所有测试都将有一个 app 变量,它指向已启动的 XCUIApplication。

tryLaunch 函数还接受一个 RawRepresentable 元素数组。通常这将是具有 String 作为其基础类型的 Enum。您的应用将与这些参数启动。在您的应用中,您可以对这些参数作出反应。在下面的例子中,可以看到应用是带有 MockNetworkResponses 参数启动的。然后,您的应用可以使用 isLaunchedWith 函数检测该值并启动网络模拟。

    // In your XCTestCase class:
    override func setUp() {
        super.setUp()
        self.tryLaunch([LaunchArguments.MockNetworkResponses])
    }

    // Somewhere in your application (if you have added the UITestHelper/App pod)
    if isLaunchedWith(LaunchArguments.MockNetworkResponses) {
        // Start the network mocking
    }

分组您的测试语句

为了使您的测试输出生成清晰的概述,您可以分组语句。组可以嵌套到您喜欢的程度。开始一个组就像

    group("Testing the switch") { activity in
        // Your test statements here will be grouped nicely in the test output.
    }

捕获屏幕截图

屏幕截图将始终添加到活动组中。如果您没有参数调用 takeScreenshot 函数,则它将仅创建默认屏幕截图组。您也可以指定 groupName,在创建新组时使用。您也可以为屏幕截图命名。

    group("Testing the switch") { activity in
        takeScreenshot(activity: activity, "First screenshot")
        takeScreenshot()
        takeScreenshot(groupName: "Screenshot group?")
        takeScreenshot("Last screenshot")
    }

使用枚举作为标识符

UITestHelper 为 RawRepresentalbe 提供了一个扩展,以便您可以直接从 enum 值获取 XCElement,前提是您也将该 enum 值设置为无障碍标识符。例如,您可以创建一个嵌套的 enum 如此

enum AccessibilityIdentifier {
    enum HomeScreen: String {
        case theLabel
        case theTextField
        case theButton
        case switch1
        case switch2
        case showButton
        case hideButton
    }
}

在您的 UIViewControllers 中,您可以将其设置了元素的访问标识符,如下所示

override func viewDidLoad() {
    super.viewDidLoad()
    theLabel ~~> AccessibilityIdentifier.HomeScreen.theLabel
    theTextField ~~> AccessibilityIdentifier.HomeScreen.theTextField
    theButton ~~> AccessibilityIdentifier.HomeScreen.theButton
    switch1 ~~> AccessibilityIdentifier.HomeScreen.switch1
    switch2 ~~> AccessibilityIdentifier.HomeScreen.switch2
    hideButton ~~> AccessibilityIdentifier.HomeScreen.hideButton
    showButton ~~> AccessibilityIdentifier.HomeScreen.showButton
}

在您的测试中,您可以使用这些内容:

func testEnumWithIdentifiersReusedForInteractingWithXCUIElement() {
    HomeScreen.showButton.tap()
    HomeScreen.hideButton.tap()
}

当标识符被重复使用时,例如在集合或表中,您可以枚举枚举元素。

    // pressing the last theButton
    let i = HomeScreen.theButton.count 
    HomeScreen.theButton[i - 1].tap()
}

然后您可以直接在枚举值上使用以下所有函数。

等待一个元素

当创建测试时,通常需要考虑元素是否可访问。为此,创建了各种辅助函数。app 将是您启动的 XCUIApplication。默认情况下,此功能最多将等待 10 秒。这可以通过参数来更改。waitUntilExists 将返回元素,但它可能仍然不可用 (.exists = false)。如果您想根据该存在性进行断言,则可以使用 .waitUntilExistsAssert 函数。

    // Using the enum:
	XCTAssert(HomeScreen.theLabel.waitUntilExists().exists, "label should exist")
	HomeScreen.theLabel.waitUntilExistsAssert()
    // Or just accessing the elements the old fashioned way:
	app.buttons["Second"].waitUntilExists().tap()
	app.buttons["Button"].waitUntilExists(3).tap()

选择存在的元素

使用 .or 函数,您可以获取 2 个元素中的任意一个。如果两个都不存在,则返回第一个元素,并且 .exists 将为 false。如果您想在这种情况下使用断言,则可以使用 .orAssert 函数。

	HomeScreen.theLabel.or(HomeScreen.theTextfield).tap()
	HoeScreen.theLabel.orAssert(HomeScreen.theTextfield)

根据存在性条件编写代码

如果元素存在,则执行一些代码。默认等待时间也为 10 秒,可以设置为参数。

	// Only execute the closure if the element is there.
	HomeScreen.theButton.ifExists { $0.tap() } // The button exist, so we do tap it
	HomeScreen.hideButton.ifExists(2) { $0.tap() } 

如果元素不存在,则执行一些代码。默认等待时间也为 10 秒,可以设置为参数。

    // The button does not exist, so we don't tap it, we do something else
	app.alerts.buttons["Hide"].ifNotExist(2) {
		app.buttons["Third"].waitUntilExists().tap()
	}

如果元素不存在,并且在代码假设执行后将存在。在下面的代码中,如果隐藏按钮不存在,则按显示按钮,这将使隐藏按钮出现,然后按下隐藏按钮。

	HomeScreen.hideButton.ifNotExistwaitUntilExists(2) {
		HomeScreen.showButton.waitUntilExists().tap()
	}.tap()
}

在文本字段中输入字段

确保文本字段已存在,然后触摸它并输入文本。

	HomeScreen.theTextField.tapAndType("testing")

开关通断

无论开关当前状态如何,它将被切换到指定的状态。

HomeScreen.switch1.setSwitch(false)

许可协议

UITestHelper 可在 MIT 3 许可下使用。详情请参阅 LICENSE 文件。

我的其他库

也请查看我的其他公开的 iOS 库

  • EVReflection - 基于反射的对象映射(Dictionary、CKRecord、JSON 和 XML),并扩展了 Alamofire 和 Moya,支持 RxSwift 或 ReactiveSwift
  • EVCloudKitDao - 简化访问 Apple 的 CloudKit
  • EVFaceTracker - 根据您的设备与您的面部之间的距离和角度计算,以模拟 3D 效果
  • EVURLCache - 一个 NSURLCache 子类,用于处理所有使用 NSURLRequest 的网络请求
  • AlamofireOauth2 - 使用 Alamofire 的 OAuth2 实现
  • EVWordPressAPI - 使用 AlamofireOauth2、AlomofireJsonToObjects 和 UITestHelper 实现 WordPress (Jetpack) API(开发中)
  • PassportScanner - 扫描护照的 MRZ 码并提取姓名、姓氏、护照号码、国籍、出生日期、到期日期和个人号码
  • AttributedTextView - 最简单的方式创建一个支持多个链接(url、hashtags、提及)的 attributed UITextView
  • UITestHelper - UI 测试辅助函数