Assertion Failure: UI Testing Failure - Failure fetching attributes for element
Asked Answered
C

5

22

When UI testing in Xcode(7.2 and 7.3), my tests sometimes fail with a rather generic error:

Assertion Failure: UI Testing Failure - Failure fetching attributes for element

I tend to get this error when calling .hittable or .tap() on an element but I cannot tell why. I've checked that the elements I'm dealing with all have their accessibility settings correctly setup and that any container views that they are in don't have accessibilty enabled. Alas, this doesn't seem to resolve the problem.

The console log reveals:

UI Testing Failure - Failure fetching attributes for element <XCAccessibilityElement: 0x7e68ae50> pid: 89032, context: 4D9272C7-3024-4062-B0FA-E16EF426F17A, payload: {
    pid = 89032;
    "uid.elementID" = 1432;
    "uid.elementOrHash" = 2125772976;
}: Error Domain=XCTestManagerErrorDomain Code=13 "Error copying attributes -25202" UserInfo={NSLocalizedDescription=Error copying attributes -25202}

I've tried searching around and managed to find it's already been logged but there appears to be no current solution (radar link) even for Xcode 7.3.

It seems that sometimes if I restart the simulator/device this error doesn't happen but this isn't a nice solution.

Catercorner answered 22/4, 2016 at 15:42 Comment(3)
I had those ones too. Be sure to properly set expectations so that your view hierarchy reaches the state you're trying to test. This is extremely important when testing asynchronous events (i.e. tapping a button that gives a feedback after a network call).Atalanta
This is Apple's bug you can also show in Apple's link. Here some guys suggest some solution might be work for you. If any solution not work for you then report a bug to Apple. We can not do or find any solution in this type of situation.Kaveri
As of Xcode 9, you can use waitForExistence(timeout: TimeInterval) to wait for that element to come to existenceAsaasabi
M
4

You can temporarily use XCUICoordinate.tap() as an alternative. For example, replace button.tap() with button.coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.5)).tap().

I ran into the same issue, and the workaround works for me.

Melvinmelvina answered 23/5, 2016 at 9:36 Comment(1)
Nice one. Will try this one too. For now I used sleep(numberOfSeconds) before tap().Alexine
P
3

I have this problem. It has appeared after one fix, so I have figured out what may cause this in my case.

In my app I have 'main' screen. It's content is returned from server and cached on device. This screen leads user to different 'detailed' screens. Each time user is going back from detailed screen, viewDidAppeare method is called on main screen. In this method main screen asks for content. To provide content, 'Data Manager' needs either to fetch from DB or to request from server 2 different entities in strict order so it uses dispatch_group. Main screen receives notification about new content from dispatch_group_notify call, that is why it is asynchronous. To time, when dispatch_group_notify is executed, viewDidAppeare is finished and, as I understand, app goes to idle for some small time. UI Test engine might have already created accessibility elements tree.

When this situation takes place and test code calls tap on some element on main screen right after view appeared, old accessibility elements decease to exist (because view hierarchy has changed to that time), but tap method was called for element with particular elementID, etc. which doesn't exist to that time. As a result you have a crash.

Parmentier answered 9/6, 2016 at 10:35 Comment(2)
tl;dr Don't swap out UI elements with the same accessibilityIdentifier too quickly. If you've created a button reuse it, don't replace it. This seems much more severe with Xcode 9.Unregenerate
2018 and using XCode 9.2; this is still an issue. I am seeing XCUITest trying to tap/interact with elements on the screen that do not exist. Similarly to yourself, I inspected the elements returned via XCUIApplication().debugDescription and saw that it was trying to interact with a non existent id.Precatory
P
2

It seems like the automation code is at times, too fast, and although the snapshot of the accessibility hierarchy has your element, your query moves on too fast to the next instruction and the framework doesn't get a chance to act on the tap() method you're sending. I've been able to minimize this error by using Joe Masilotti's helper functions to wait for elements to first be hittable, and then adding a sleep() before tapping the element in question. Hope this helps.

Pallas answered 18/5, 2016 at 14:50 Comment(2)
Yeah, this is what I thought it might be at first as well. However, I still get this problem even when using Joe's useful methods combined with a nasty but liberal use of sleep(). I think that it's how the accessibility snapshot references its objects. I've spent many hours looking at this and it seems that sometimes it loses track and accidentally references the wrong underlying UI element. I've checked this by logging the memory addresses of elements and looking at those in the snapshot and it occasionally gets it wrong meaning that tap() is called on the wrong element, hence, the error.Catercorner
@Gordinium if you get around to file this bug, please share :)Pallas
D
2

I encountered this as well. In my case, the server is returning multiple typeahead search query results in quick succession. The target element pops up quickly, but is not consistently hittable until the final query. I solved this by waiting for existence of the element in the first query initially, via XCTWaiter. Then put a sleep to encompass the time of all the query results and then waiting for element being hittable. DO NOT use hittable for the first query result as this will fail because hittable also checks if elements can be tapped, but the UI is changing too quickly for the element to be tapped.

It would be better if you could trigger just the final query for testing purposes or via the code base. I also considered using UIPasteboard to avoid multiple typeahead queries, but, as far as I can tell, this is not available to XCTest.

Divided answered 14/11, 2017 at 21:36 Comment(0)
A
0

I tried waitForHittable() from http://masilotti.com/xctest-helpers/ but in my case I had to use sleep(seconds) before tapping.

Plus, don't think Joe Masilotti's methods are useless. They are great and I have added those in extension XCTest and extension XCUIElement. It is just that waitForHittable() didn't work just on first tap after main screen of my app loads.

Alexine answered 7/12, 2017 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.