iOS Swift:提升TableView Cell中UI测试按钮点击稳定性
问题:提升iOS Swift中TableView单元格内按钮UI测试稳定性
本地重复运行100次均稳定通过的UI测试,在CI环境下出现Flaky(不稳定)问题。测试流程为点击TableView中第一个Pay按钮触发弹窗,随后断言弹窗存在,但CI中偶尔会出现tap()操作无法触发按钮的情况,导致弹窗未出现,最终断言失败。怀疑问题根源在AccountDetailsScreen.swift中payButton的声明逻辑。
相关代码
AccountDetailsUITests.swift
import XCTest class AccountDetailsTests: UITestBaseTestCase { func testAccountDetailsAlertForPayButton() throws { try setupAndPrepare() TransactionsFlow().showTransactions(for: Fixtures.account) let accountDetailsScreen = AccountDetailsScreens.TransactionsList().waitUntilReady() sleep(forTimeInterval: 0.3) accountDetailsScreen.payButton.tap() assertElementExists(accountDetailsScreen.payAlertView, timeout: 10) accountDetailsScreen.oKAlertButton.tap() } }
AccountDetailsScreen.swift
import XCTest class AccountDetailsScreens: BaseScreen { // Other Code class TransactionsList: BaseScreen { var payButton: XCUIElement { app.cells.containing(.button, identifier: "TilePayButton").firstMatch.buttons["TilePayButton"] } lazy var oKAlertButton = app.alerts.buttons["okayButtonCollectionAlertAccountDetails"] lazy var payAlertView = app.alerts["payAlertView"] } }
优化方案
1. 修正payButton定位逻辑
原嵌套查找方式(先找含按钮的cell再取按钮)容易出现匹配偏差,可简化定位逻辑:
var payButton: XCUIElement { // 直接定位可见区域内的第一个Pay按钮 app.buttons["TilePayButton"].firstMatch }
若需限定在cell内,可优化为:
var payButton: XCUIElement { let firstCell = app.cells.firstMatch XCTAssertTrue(firstCell.waitForExistence(timeout: 5)) return firstCell.buttons["TilePayButton"] }
2. 替换固定等待为显式等待
测试中的sleep(forTimeInterval: 0.3)是固定等待,CI环境资源波动时可能不足以让元素就绪,替换为等待按钮可交互:
let payButton = accountDetailsScreen.payButton // 等待按钮存在且可点击 XCTAssertTrue(payButton.waitForExistence(timeout: 5)) XCTAssertTrue(payButton.isHittable) payButton.tap()
3. 增强点击可靠性
若直接tap()偶尔失效,可尝试坐标点击或添加重试逻辑:
// 方案1:点击按钮中心坐标 payButton.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap() // 方案2:最多重试3次点击 var alertAppeared = false for _ in 1...3 { payButton.tap() if accountDetailsScreen.payAlertView.waitForExistence(timeout: 2) { alertAppeared = true break } } XCTAssertTrue(alertAppeared, "点击Pay按钮后弹窗未出现")
4. 完善屏幕就绪判断
确保waitUntilReady()真正等待按钮加载完成,可在TransactionsList类中重写该方法:
override func waitUntilReady() -> Self { super.waitUntilReady() XCTAssertTrue(payButton.waitForExistence(timeout: 10)) return self }
内容的提问来源于stack exchange,提问作者rainerwolfram
相关产品推荐
相关产品推荐

