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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以使用SpriteKit在应用程序上使用Xcode UI Testing?相关的知识,希望对你有一定的参考价值。

我想使用SKSpriteKit对游戏进行UI测试。

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

答案

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

  1. 列出场景中包含的所有可访问元素
  2. 配置每个元素的设置,尤其是framedata。

一步步

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

假设我想让名为tapMe的SpriteKit按钮可访问。

List of accessible elements.

在场景中添加UIAccessibilityElementto数组。

 var accessibleElements: [UIAccessibilityElement] = []

Scene's cycle life

我需要更新两种方法:didMove(to:)and willMove(from:)

override func didMove(to view: SKView) {
    isAccessibilityElement       = false
    tapMe.isAccessibilityElement = true
}

由于场景是可访问性控制器,文档声明它必须将False返回到isAccessibilityElement

和:

override func willMove(from view: SKView) {
    accessibleElements.removeAll()
}

Override UIAccessibilityContainer methods

涉及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)!
}

Initialize accessibility for the Scene

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)

    }
}
  1. UIAccessibilityElement创建tapMe
  2. 计算设备坐标上的帧数据。别忘了frame的起源是UIKit的左上角
  3. 设置UIAccessibilityElement的数据
  4. 将此UIAccessibilityElement添加到场景中所有可访问元素的列表中。

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

参考

另一答案

根据Apple developer forum discussion,目前不可能将UITest与SpriteKit集成:

这可能目前不可能,但可能是这样

更新2017-02-19

根据@ChrisLivdahl的评论,这可以通过使用UIAccessibility - Session 406, UI Testing in Xcode, WWDC 2015来实现。

想法是使元素需要UI Testable。

另一答案

我根据你的(@ Domsware)真棒答案实现了example project,我已经证实这个技巧对Xcode UI Testing FrameworkKIF都有效。

希望这个例子对任何对这个主题感兴趣的人都有帮助:)

以上是关于是否可以使用SpriteKit在应用程序上使用Xcode UI Testing?的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit 的界面构建器

我必须在 SpriteKit 应用程序中包含非视网膜纹理吗?

从 SpriteKit 中的类播放音频

是否可以在Spritekit项目中以编程方式更改纹理色调?

如何混合 UIKit 和 SpriteKit?

是否可以围绕 SpriteKit 中的任意点旋转节点?