2016-04-22 109 views
22
属性

的Xcode(7.2和7.3) UI测试,我的测试有时会具有相当一般性错误:声明失败:UI测试失败 - 未能取的元素

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

我倾向于在元素上调用.hittable.tap()时出现此错误,但我无法说明原因。我已经检查过我处理的元素都具有正确的可访问性设置,并且它们所在的任何容器视图都没有启用可访问性。唉,这似乎不能解决问题。

控制台日志显示:

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} 

我试着摸索和管理,发现它已经被记录,但似乎没有当前解决方案(radar link)甚至的Xcode 7.3。

似乎有时如果我重新启动模拟器/设备,这个错误不会发生,但这不是一个好的解决方案。

+0

我也有那些。确保正确设置期望值,以便您的视图层次结构达到您要测试的状态。在测试异步事件时(即在网络调用之后点击一个提供反馈的按钮),这一点非常重要。 –

+0

这是苹果的错误,你也可以在苹果的[链接](https://forums.developer.apple.com/thread/6437)中显示。这里有些人建议一些解决方案可能适合你。如果有任何解决方案对您不适用,请向Apple报告错误。在这种情况下,我们无法做到或找到任何解决方案。 – iMHitesh

+1

从Xcode 9开始,你可以使用'waitForExistence(timeout:TimeInterval)'来等待这个元素的存在 – onmyway133

回答

2

看起来自动化代码有时候太快了,虽然可访问性层次结构的快照有你的元素,但是你的查询过快地移动到下一条指令,并且框架没有机会按照您发送的tap()方法行事。我已经能够通过使用Joe Masilotti的helper functions来等待元素首先被击中,然后在点击相关元素之前添加sleep(),从而最小化这个错误。 希望这有助于。

+3

是的,这也是我认为它可能在一开始。但是,即使使用Joe的有用方法,并结合使用'sleep()'的讨厌但自由的使用方法,我仍然会遇到这个问题。我认为这是可访问性快照如何引用其对象。我花了好几个小时看着这个,看起来有时它会失去踪迹,并且意外地引用了错误的底层UI元素。我已经通过记录元素的内存地址并查看快照中的内容来检查此问题,偶尔会发现它错误,这意味着tap()会在错误的元素上调用,因此会导致错误。 – Gordonium

+0

@Gordinium如果你想知道这个bug,请分享:) – Citronex

4

您可以暂时使用XCUICoordinate.tap()作为替代。例如,将button.tap()替换为button.coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.5)).tap()

我遇到了同样的问题,解决方法适用于我。

+0

不错的。也会尝试这一个。现在我在tap()之前使用了sleep(numberOfSeconds)。 –

3

我有这个问题。它出现在一次修复之后,所以我已经找出了可能导致这种情况的原因。

在我的应用程序中,我有'主'屏幕。它的内容从服务器返回并缓存在设备上。这个屏幕引导用户到不同的'详细'屏幕。每次用户从详细画面返回时,在主画面上调用viewDidAppeare方法。在这个方法主屏幕要求内容。为了提供内容,'数据管理器'需要从数据库中获取数据,或者按照严格的顺序从服务器2请求不同的实体,因此它使用dispatch_group。主屏幕接收来自dispatch_group_notify调用的关于新内容的通知,这就是为什么它是异步的。到时候,当执行dispatch_group_notify时,viewDidAppeare已完成,据我了解,应用程序会闲置一段时间。 UI测试引擎可能已经创建了可访问性元素树。

当这种情况发生和测试代码调用tap主屏幕上的一些元素后,右视图出现,旧的无障碍元素死亡存在(因为视图层次结构已更改为时间),但tap方法要求与元素特别是当时不存在的elementID等。因此你有一个崩溃。

+0

'tl; dr'不要太快用相同的'accessibilityIdentifier'换出UI元素。如果您创建了一个按钮来重用它,请不要替换它。这在Xcode 9中似乎更加严重。 – arsenius

1

我也遇到过这个问题。就我而言,服务器正在快速连续返回多个typeahead搜索查询结果。目标元素会很快弹出,但在最终查询之前并不一致。我通过XCTWaiter通过最初等待第一个查询中元素的存在来解决此问题。然后进行睡眠以涵盖所有查询结果的时间,然后等待元素可以被击中。不要使用hittable作为第一个查询结果,因为这会失败,因为hittable也会检查是否可以挖掘元素,但UI变化太快而无法挖掘元素。

如果您只是为了测试目的或通过代码库触发最终查询,那将会更好。我还考虑过使用UIPasteboard来避免多个typeahead查询,但据我所知,这不适用于XCTest。

0

我尝试从http://masilotti.com/xctest-helpers/ waitForHittable(),但在我的情况下,我不得不使用睡眠(秒)之前攻丝。

另外,不要认为乔马斯洛蒂的方法是无用的。他们很棒,我已经添加了扩展XCTest和扩展XCUIElement。只是在我的应用程序主屏幕加载后,waitForHittable()仅在第一次点击时无法工作。