问题
In the WWDC Session about UI Testing in Xcode you can learn that queries are evaluated when you actually synthesise properties or read values.
So when are queries evaluated? So they are not actually evaluated just when you create them.
They are evaluated on-demand or as they are needed. This means that with an element, the query will be evaluated when you synthesize events or read property values.
You can create the element but until you use it, the query won't be evaluated. Similarly if you create a query directly it will be evaluated when you get the number of matches or if you call one of the APIs that returns all the matches. It will have to be evaluated at that point and we will reevaluate queries when the UI changes. So you are always working with the most current view of the application rather than data from ten seconds ago or two minutes ago, depending on the length of your test. So in this way you can think of queries and elements being somewhat similar to URLs.
This is great to always be sure you're working with the latest state of the UI but it can be quite slow and prevent you from executing tests that need high speed. See the following:
CFTimeInterval startTime = CACurrentMediaTime();
XCUIElement *button = [[XCUIApplication alloc] init]/*@START_MENU_TOKEN@*/.scrollViews/*[[".windows[@\"\\n[FYB Debug]: Reachability Flag Status: -R t------ networkStatus\"].scrollViews",".scrollViews"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.otherElements.buttons[@"StartSDK_Button"];
[button tap];
[button tap];
[button tap];
[button tap];
[button tap];
CFTimeInterval endTime = CACurrentMediaTime();
NSLog(@"EXECUTION TIME = %f", endTime - startTime);
2017-04-20 11:04:03.381102+0800 XCTRunner[6368:854885] EXECUTION TIME = 5.619870
So I was wondering, is there a way to change that behaviour temporarily during the tests and query the element only once?
回答1:
I had a similar problem needing a very fast vertical swipe on a table view. Not finding a way to speed up events using the XCTest framework I ended up building a rather tricky workaround: instead of requesting the tap/swipe gestures via XCTest framework I'm sending requests to a customly developed mac app that is able to control the mouse pointer of the hosting machine. If you're testing on simulator only it will work just great and easy to use.
A sample test that will repeatedly tap an XCUIElement
func testMultipleTap() {
let app = XCUIApplication()
app.launch()
host.connect()
let btn = app.buttons["mybutton"]
let mouseClick = SBTUITunneledHostMouseClick(element: btn, completionPause: 0.05)
let mouseCliks = Array(repeating: mouseClick, count: 3)
host.execute(mouseCliks)
}
host
is the object that allows you to communicate with the mac application.
The project is available on GitHub.
来源:https://stackoverflow.com/questions/43509497/prevent-xcuielementquery-from-being-reevaluated