是否可以使用SpriteKit在应用程序上使用Xcode UI Testing?

Dom*_*ial 5 accessibility uiaccessibility sprite-kit swift xcode-ui-testing

我想使用的UI测试SKSpriteKit.

由于我的第一次尝试不起作用,我想知道是否可以使用SpriteKit进行Xcode UI测试.

Dom*_*ial 5

主要思想是为要进行UI测试的元素创建辅助功能材料.那是意味着:

  1. 列出场景中包含的所有可访问元素

  2. 配置每个元素的设置,尤其是frame数据.

一步步

这个答案适用于Swift 3,主要基于Sprite Kit的Accessibility(Voice Over)

假设我想让SpriteKit按钮名为tapMeaccessible.

可访问元素列表.

添加一个UIAccessibilityElement到Scene 的数组.

 var accessibleElements: [UIAccessibilityElement] = []
Run Code Online (Sandbox Code Playgroud)

场景的循环寿命

我需要更新两个方法:didMove(to:)willMove(from:).

override func didMove(to view: SKView) {
    isAccessibilityElement       = false
    tapMe.isAccessibilityElement = true
}
Run Code Online (Sandbox Code Playgroud)

由于场景是可访问控制,文档说,它必须返回FalseisAccessibilityElement.

和:

override func willMove(from view: SKView) {
    accessibleElements.removeAll()
}
Run Code Online (Sandbox Code Playgroud)

覆盖UIAccessibilityContainer方法

3种方法涉及:accessibilityElementCount(),accessibilityElement(at index:)index(ofAccessibilityElement.请允许我介绍一下initAccessibility()我稍后会介绍的方法.

override func accessibilityElementCount() -> Int {
    initAccessibility()
    return accessibleElements.count
}

override func accessibilityElement(at index: Int) -> Any? {

    initAccessibility()
    if (index < accessibleElements.count) {
        return accessibleElements[index]
    } else {
        return nil
    }
}

override func index(ofAccessibilityElement element: Any) -> Int {
    initAccessibility()
    return accessibleElements.index(of: element as! UIAccessibilityElement)!
}
Run Code Online (Sandbox Code Playgroud)

初始化场景的辅助功能

func initAccessibility() {

    if accessibleElements.count == 0 {

        // 1.
        let elementForTapMe   = UIAccessibilityElement(accessibilityContainer: self.view!)

        // 2.
        var frameForTapMe = tapMe.frame

        // From Scene to View
        frameForTapMe.origin = (view?.convert(frameForTapMe.origin, from: self))!

        // Don't forget origins are different for SpriteKit and UIKit:
        // - SpriteKit is bottom/left
        // - UIKit is top/left
        //              y
        //  ??????       ?
        //  ?    ?       ?   x
        //  ??????       ????
        //
        //                   x
        //  ??????       ????
        //  ?    ?       ?
        //  ??????     y ?
        //
        // Thus before the following conversion, origin value indicate the bottom/left edge of the frame.
        // We then need to move it to top/left by retrieving the height of the frame.
        //


        frameForTapMe.origin.y = frameForTapMe.origin.y - frameForTapMe.size.height


        // 3.
        elementForTapMe.accessibilityLabel   = "tap Me"
        elementForTapMe.accessibilityFrame   = frameForTapMe
        elementForTapMe.accessibilityTraits  = UIAccessibilityTraitButton

        // 4.
        accessibleElements.append(elementForTapMe)

    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 创建UIAccessibilityElementtapMe
  2. 计算设备坐标上的帧数据.别忘了它frame的起源是UIKit的左上角
  3. 设置数据 UIAccessibilityElement
  4. 将其添加UIAccessibilityElement到场景中所有可访问元素的列表中.

现在tapMe可以从UI测试角度访问.

参考