前言吹一波
iPhone的自动化测试,只要有Mac条件,XCUITest就是绝配啦
(Apple爸爸的先天优势好吧)
XCUITest的基本知识参见:
https://www.jianshu.com/p/adb289c1d839
关键词:iOS UI自动化 Xcode 测试 Swift Mac
1.脱离iOS App源码进行UI自动化
「该部分手把手教学,再不行可能是基础知识匮乏,辛苦google吧」
可能能做出很多夸张的事情,看你发挥啦!
鉴于之前的一些Demo都是基于App源码本身添加target来展开UI自动化测试的,后来实验发现完全不用依赖源码。
但是结合源码的UITest可以方便增加accessbility属性来配合元素定位,也可以发现一些非主线程更新UI等危险操作的存在(还是有不少好处的)。
创建一个新的Xcode项目:
Xcode->File->New->Project(快捷按键 Shift+Command+N )
项目模板如果不太懂就选择Single View App吧。该项目作为UITest这个target的依赖,没有什么实质作用。
下一步注意包含Include UI Tests,项目名称和组织名称你开心就好。
完成后如图所示:
代码-Safari浏览器,载入百度网页的过程
let safariApp = XCUIApplication.init(bundleIdentifier: "com.apple.mobilesafari")
let wechatApp = XCUIApplication(bundleIdentifier: "com.tencent.xin")
let qqApp = XCUIApplication(bundleIdentifier: "com.tencent.mqq")
//如果要测试自己公司的App,那么问下开发bundle identifier就好了,上面的三个分别是iPhone自带的浏览器、腾讯微信、腾讯QQ程序
safariApp.launch()
app.buttons["URL"].tap()
//防止如果浏览器打开后有一个默认的网页,则点击输入框右边的叉号来清空
if (app.buttons["清除文本"].exists){
app.textFields["URL"].buttons["清除文本"].tap()
}
app.textFields["URL"].typeText("http://www.baidu.com")
//点击键盘上的确认按钮,也是前往按钮 app.buttons["前往"].tap()
//至此,完成了打浏览器,载入百度网页的过程
这不是官方推荐的操作,因为此时app对象不是默认的宿主app。也就是wait for app to idle等操作无法正确地合理地判断app状态了。
还是推荐在被测试的源码内集成XCUITest Target。
2.「多App交互」测试外部App登录(微信登录、微博登录、QQ登录)
交给XCUITest自动化,都是极速完成
建议打开XCUITest的脚本录制功能操作一遍来构成基本代码。
速度比手工都快速,各种app的交互成为可能,足见XCUITest的巨大潜力。
实例是网页调起QQ等软件进行登录的过程,同样,自己的App调起这些常用的App进行登录类似。
注意操作QQ、微信等其它app的时候使用上文代码中定义的qqApp、wechatApp等对象。
也就是说操作的不同的App都要是对应的XCUIApplication对象。
3.「important」查看XCUIElement的结构树(当前的UI元素树)
在断点处,lldb命令行执行:
po app.debugDescription()
如果查看不方便,将选中的部分复制到sublimeText等第三方文本编辑器
将\n 替换成换行Enter键,效果如下:
是Safari浏览器打开一个登陆网页之后的元素树的一部分。
4.万能点击
(不建议,但是极端情况可以解决问题)
如果遇到实在处理不了的情况,比如XCUITest元素树中都找不到某元素
可以考虑使用点击操作暂时绕过
【充电站】了解UI在iOS系统中的倍数渲染,2x、3x等
比如Xs Max这样的高分辨率肯定是3x渲染了。
icon_alipay.png → iPhone 早期的低分辨率手机(不考虑)
[email protected] → iPhone4/4S/5/5S/6/6S/7对应尺寸,这就是2倍图
[email protected] → iPhone6P/6SP/7P使用的尺寸,3倍图,也就是现在高端iPhone使用的图
举栗子:如果iphone Xs Max(UI图=3x机型)截图在Photoshop中测量出的要点击的点的位置是[x=30,y=18],则代码中tapAtPoint(x,y)的取值应该是[x=10,y=6]
下面这个函数Demo可以直接粘贴,然后调用,点击App内的某个坐标的点。
func tapCoordinate(in app:XCUIApplication, at xCoordinate: Double, and yCoordinate: Double) {
let normalized = app.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
let coordinate = normalized.withOffset(CGVector(dx: xCoordinate, dy: yCoordinate)) coordinate.tap()
}
比如这个图片:(实际像素尺寸为1240*212)
QQ 和 微信icon 的中心点在截图中的水平距离是290像素,代码中认为1倍距离,即距离为290/3