XCUIElement tap() 不工作
XCUIElement tap() not working
我有一个非常简单的 XCTestCase
实现,它测试按钮上的点击并期望出现警报控制器。问题是 tap()
方法不起作用。在关联按钮的 IBAction 中放置一个断点我意识到逻辑甚至没有被调用。
class uitestsampleUITests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launch()
}
func testButton() {
let button = app.buttons["Button"]
button.tap()
expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5.0, handler: nil)
}
}
此外,复制 button.tap()
指令使测试通过,如下所示:
func testButton() {
let button = app.buttons["Button"]
button.tap()
button.tap()
expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5.0, handler: nil)
}
我在 Xcode 7.3.1 中遇到了这个问题,我是不是遗漏了什么?这是一个错误吗?
我有类似的东西。对我来说,问题是我尝试挖掘的元素有时由于某种原因不是 hittable
。
来自 Apple 的文档:
Sends a tap event to a hittable point computed for the element.
因此,如果某个元素不是 hittable
,则点击操作不会做太多事情,这会破坏测试用例的逻辑。
为了解决这个问题,在我点击某些东西之前,我会等到相应的元素变得可点击。非常简单。
#import <XCTest/XCTest.h>
@interface XCUIElement (Tap)
- (void)tapInTestCase:(XCTestCase *)testCase;
@end
@implementation XCUIElement (Tap)
- (void)tapInTestCase:(XCTestCase *)testCase
{
// wait until the element is hittable
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"hittable == true"];
[testCase expectationForPredicate:predicate evaluatedWithObject:element handler:nil];
[testCase waitForExpectationsWithTimeout:5.0f handler:nil];
// and then tap
[self tap];
}
@end
所以一位 Apple 工程师回复了我的错误报告说:
The second possibility is that you are running into a problem that
sometimes occurs where the application finishes launching but the
splash screen doesn't immediately disappear and events dispatched to
the app are not handled properly.
To try to work around that issue, consider placing a small delay at
the beginning of your test (sleep(1) should be enough).
所以我做到了,现在可以了:
override func setUp() {
super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launch()
sleep(1)
}
对于可击中的 UIWebView
,在我通过坐标完成之前,水龙头不起作用:
extension XCUIElement {
func forceTap() {
coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
}
}
希望对大家有所帮助
P.S。也适用于不可点击的项目,例如标签等。
对我来说最可靠的方法是在元素没有被正确点击的地方添加sleep(1)
。使用值小于 1000
的 usleep
函数会导致不可靠的行为,例如正确的测试随机失败。
您可以 wait
在加载元素时,我创建了这个扩展:
import XCTest
extension XCUIElement {
func tap(wait: Int, test: XCTestCase) {
if !isHittable {
test.expectation(for: NSPredicate(format: "hittable == true"), evaluatedWith: self, handler: nil)
test.waitForExpectations(timeout: TimeInterval(wait), handler: nil)
}
tap()
}
}
这样使用:
app.buttons["start"].tap(wait: 20, test: self)
我有一个非常简单的 XCTestCase
实现,它测试按钮上的点击并期望出现警报控制器。问题是 tap()
方法不起作用。在关联按钮的 IBAction 中放置一个断点我意识到逻辑甚至没有被调用。
class uitestsampleUITests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launch()
}
func testButton() {
let button = app.buttons["Button"]
button.tap()
expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5.0, handler: nil)
}
}
此外,复制 button.tap()
指令使测试通过,如下所示:
func testButton() {
let button = app.buttons["Button"]
button.tap()
button.tap()
expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5.0, handler: nil)
}
我在 Xcode 7.3.1 中遇到了这个问题,我是不是遗漏了什么?这是一个错误吗?
我有类似的东西。对我来说,问题是我尝试挖掘的元素有时由于某种原因不是 hittable
。
来自 Apple 的文档:
Sends a tap event to a hittable point computed for the element.
因此,如果某个元素不是 hittable
,则点击操作不会做太多事情,这会破坏测试用例的逻辑。
为了解决这个问题,在我点击某些东西之前,我会等到相应的元素变得可点击。非常简单。
#import <XCTest/XCTest.h>
@interface XCUIElement (Tap)
- (void)tapInTestCase:(XCTestCase *)testCase;
@end
@implementation XCUIElement (Tap)
- (void)tapInTestCase:(XCTestCase *)testCase
{
// wait until the element is hittable
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"hittable == true"];
[testCase expectationForPredicate:predicate evaluatedWithObject:element handler:nil];
[testCase waitForExpectationsWithTimeout:5.0f handler:nil];
// and then tap
[self tap];
}
@end
所以一位 Apple 工程师回复了我的错误报告说:
The second possibility is that you are running into a problem that sometimes occurs where the application finishes launching but the splash screen doesn't immediately disappear and events dispatched to the app are not handled properly.
To try to work around that issue, consider placing a small delay at the beginning of your test (sleep(1) should be enough).
所以我做到了,现在可以了:
override func setUp() {
super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launch()
sleep(1)
}
对于可击中的 UIWebView
,在我通过坐标完成之前,水龙头不起作用:
extension XCUIElement {
func forceTap() {
coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
}
}
希望对大家有所帮助
P.S。也适用于不可点击的项目,例如标签等。
对我来说最可靠的方法是在元素没有被正确点击的地方添加sleep(1)
。使用值小于 1000
的 usleep
函数会导致不可靠的行为,例如正确的测试随机失败。
您可以 wait
在加载元素时,我创建了这个扩展:
import XCTest
extension XCUIElement {
func tap(wait: Int, test: XCTestCase) {
if !isHittable {
test.expectation(for: NSPredicate(format: "hittable == true"), evaluatedWith: self, handler: nil)
test.waitForExpectations(timeout: TimeInterval(wait), handler: nil)
}
tap()
}
}
这样使用:
app.buttons["start"].tap(wait: 20, test: self)