Can I use Xcode UI Testing in an application using SpriteKit?

I want to use user interface testing for a game using SKSpriteKit .

Since my first attempts did not work, I wonder if it is possible to use Xcode UI Testing with SpriteKit.

+5
source share
3 answers

The basic idea is to create accessibility material for the elements you want to test in the user interface. It means:

  • List of all available items contained in the scene.

  • Set options for each of these elements, especially the data frame .

Step by step

This answer is for Swift 3 and is mainly based on Availability (voice) using the Sprite Kit

Let's say I want to make a SpriteKit button called tapMe .

List of available items.

Add an array of UIAccessibilityElement to the scene.

  var accessibleElements: [UIAccessibilityElement] = [] 

Scene life cycle

I need to update two methods: didMove(to:) and willMove(from:) .

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

Since the scene is an availability controller, in the declared documentation, it should return False in isAccessibilityElement .

and

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

Override UIAccessibilityContainer Methods

3 methods: accessibilityElementCount() , accessibilityElement(at index:) and index(ofAccessibilityElement . Let me introduce the initAccessibility() method, which I will describe below.

 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) } } 
  • Create UIAccessibilityElement for tapMe
  • Calculate frame data in device coordinates. Do not forget that the beginning of the frame is the top / left corner for UIKit
  • Set data for UIAccessibilityElement
  • Add this UIAccessibilityElement list of all available items in the scene.

tapMe is now available in terms of user interface testing.

References

+3
source

According to the Apple Developer Forum discussion , the integration of UITest with SpriteKit is currently not possible:

This is probably not possible at the moment, but maybe it could be

Update 2017-02-19

According to @ChrisLivdahl's comment, this can be achieved with UIAccessibility - Session 406, UI Testing in Xcode, WWDC 2015 .

The idea is to make the required UI element Testable.

+3
source

I implemented a project based on your wonderful answer (@Domsware), and I confirmed that this trick works well for both the Xcode UI Testing Framework and KIF .

Hope this example helps anyone interested in this topic :)

+1
source

Source: https://habr.com/ru/post/1238293/


All Articles