测试之家
  • 社区
  • 问答
  • 招聘
  • 社区学堂新
  • 开源项目
  • 活动
  • Wiki
  • 注册
  • 登录
会员
zhangzhao_lenovo
第 3170 位会员 / 2015-04-07
宇宙中心 @ 北京市西城区
14 篇帖子 • 556 条回帖
271 关注者
18 正在关注
398 收藏
zhangzhaoa
打赏支持
未设置 GitHub 信息.
  • 個人信息
  • 個人專欄
  • 帖子
  • 回帖
  • 收藏
  • 正在關注
  • 關注者
  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月15日

    所有文件又重新提交了。你再 clone 试试,应该是环境问题

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月15日

    没有 我看 wda,xctestwd 代码大致类似。 理论上 oc 的应该更快些,你那里速度慢 根本原因是用的 appium,中间经过了太多过程,比如网络请求

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月15日

    是的,需要占两个 bundle id

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月15日

    录屏我也还没有实现,仅仅是个想法。
    你说的 getpagesource 是哪个框架的 api? 在 44 楼发了个优化的方案,牺牲一些准确度来提升获取速度。

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月14日

    我测试这个是可以用,可能没公开。我当时搜 google 好像在某个 stackoverflow 里看到的。

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月14日

    注! 熊猫直播测试组 出品; 玩游戏关注熊猫直播

    已开源了 1.0.0.1002。 尚有瑕疵,望见谅。

    运行说明:

    1. build 配置 类似 wda
    2. 启动 server 前 执行 iproxy 8001 8001 做手机与 mac 的端口映射
    3. 在 xcode 中的 XCTestWDUITests target 里执行 run the test case 启动 server,开始监听 8001 端口
    4. 执行 ‘curl -X POST -H "xx" -d "xx" http ://127.0.0.1:8001/wd/hub/monkey’ ,开始执行 monkey

    配置:

    XCTestWDMonkeyController.swift 
            let monkey = Monkey(frame: app.frame)
            monkey.addDefaultXCTestPrivateActions()
            monkey.addXCTestTapAlertAction(interval: 100, application: app)
            monkey.addXCTestCheckCurrentApp(interval: 10, application: app)     # app后台或退出检测
            //monkey.addXCTestAppLogin(interval: 50, application: app)          # 登陆业务逻辑   50次事件加入1次业务关键点检查,无登陆逻辑可注释
            monkey.monkeyAround()
    
    MonkeyXCTestPrivate.swift 
    public func addDefaultXCTestPrivateActions() {
            addXCTestTapAction(weight: 35)              #随机点击事件  100-200ms/action
            //addXCTestElementTapAction(weight: 10)     #基于控件的点击事件   执行概率: 10/(35+10+5)   300-400ms/action
            addXCTestLongPressAction(weight: 1)
            addXCTestDragAction(weight: 1)
            addXCTestPinchCloseAction(weight: 1)
            addXCTestPinchOpenAction(weight: 1)
            addXCTestRotateAction(weight: 1)
        }
    

    注!事件序列如何实现:
    通过设置一个关键点 引入一个事件序列,当检测到出现关键点时插入自定义事件序列,并立即执行; 可按此原理实现自己的事件序列

    public func addXCTestAppLogin(interval:Int, application:XCUIApplication) {
            addAction(interval:interval){ [weak self] in
                do{
                    let session = try XCTestWDSessionManager.singleton.checkDefaultSessionthrow()     #检测到出现'登录'关键点时 插入
                    let root = session.application
                    if root != nil{
                        let usage = "xpath"
                        let tag = "//XCUIElementTypeOther[@name='登录']/XCUIElementTypeTextField"
                        let element = try? XCTestWDFindElementUtils.filterElement(usingText: usage, withvalue: tag, underElement: root!)
                        if let element = element {
                            if element != nil {
                                self?.addXCTestLoginAction(application: application)   #插入一个特殊事件序列
                            }
                            else{
                                return
                            }
                        }
                    }
                }catch{
                    return
                }
            }
        }
    
    public func addXCTestLoginAction(application:XCUIApplication) {     #该事件为一个原子事件序列,保证事件中不会插入其他事件
            addAction(){ [weak self] in
                do{
                    let session = try XCTestWDSessionManager.singleton.checkDefaultSessionthrow()
                    let root = session.application
                    if root == nil{
                        return
                    }
                    let usage = "xpath"
                    let username = "//XCUIElementTypeOther[@name='登录']/XCUIElementTypeTextField"
                    let passwd = "//XCUIElementTypeOther[@name='登录']/XCUIElementTypeSecureTextField"
                    let button = "//XCUIElementTypeOther[@name='登录']//XCUIElementTypeStaticText[@name='登录']"
                    var element = try? XCTestWDFindElementUtils.filterElement(usingText: usage, withvalue: username, underElement: root!)
                    if let element = element {
                        if let element = element {
                            NSLog("XCTestWDSetup->loginuser find?\(String(describing: element))<-XCTestWDSetup")
                            let value = "1111111111"
                            let rect = element.wdRect()
                            let point = CGPoint(x:rect["x"]!,y:rect["y"]!)
                            let locations = [point]
                            let semaphore = DispatchSemaphore(value: 0)
                            let numberOfTaps = 1
                            self!.sharedXCEventGenerator.tapAtTouchLocations(locations, numberOfTaps: UInt(numberOfTaps), orientation: orientationValue) {      #点击使用坐标,调用xctest私有api
                                semaphore.signal()
                            }
                            semaphore.wait()
    

    注! 屏幕中控件获取如何加快速度
    如果使用 app.descendants(matching: .xxx) 可以获取某种类型的控件集,但获取其中某个控件坐标时,xctest 内部会再次执行一次当前界面查找确保控件仍存在,该过程测试时间过长,超过 500ms 甚至 1s 更多。故此处进行了优化,缩短了时间 ;最终点击某个控件控制在 300-400ms

    static func xpathToList(_ root:XCElementSnapshot, _ xpathQuery:String) -> [CGPoint]? {
    
            var mapping = [String:XCElementSnapshot]()
            let xml = generateXMLPresentation(root,nil,nil,defaultTopDir,&mapping)?.xml
            if xml == nil
            {return nil}
    
            let tree = try? XMLDocument(string: xml!, encoding:String.Encoding.utf8)    #xml tree
            let nodes = tree?.xpath(xpathQuery)   #筛选生成对应节点
            var list = [CGPoint]()
            for node in nodes! {
                if mapping[node.attr("private_indexPath")!] != nil{
                    let x = (node.attr("x")! as NSString).floatValue
                    let y = (node.attr("y")! as NSString).floatValue
                    if (x <= 0) && (y <= 0)
                    {continue}
    
                    let snapshot = mapping[node.attr("private_indexPath")!]
                    let isvisible = try? snapshot?.isWDVisible()    #仅isvisible的才视为当前可见,加入到point队列
                    if isvisible == nil || isvisible! == false
                    {continue}
    
                    let w = (node.attr("width")! as NSString).floatValue
                    let h = (node.attr("height")! as NSString).floatValue
                    let cX = Int(x + w/2)
                    let cY = Int(y + h/2)
                    let point = CGPoint(x:cX,y:cY)
                    if list.contains(point) == false {
                        list.append(point)
                    }
                }
            }
            return list    #最终返回所选控件对应的坐标队列集
        }
    

    注! app 退出如何检测
    (坑点!!! app 切换或者闪退自身也需要时间,可能获取当前 pid 时 app 还未完成退出或切换操作)
    app 退出通过三种方式检测
    1) app 退出检测线程 每 500ms 执行一次, 检测耗时 50ms

    public func addXCTestCheckCurrentApp(interval:Int, application:XCUIApplication) {
            addCheck(interval:interval){ [weak self] in
                let work = DispatchWorkItem(qos:.userInteractive){
                    let isRunning = application.running   #获取当前是否在运行中
                    let current = Int(XCTestWDFindElementUtils.getAppPid())   #获取当前前台pid
                    if current != self?.pid || !isRunning{   #当切换到后台或已退出时,执行launch
                        application.launch() 
                        self?.sleep(5)
                        self?.pid = Int(XCTestWDFindElementUtils.getAppPid())
                    }
                }
                DispatchQueue.main.async(execute:work)  
            }
        }
    
    static func getAppPid() -> Int32{
            var activeApplicationElement:XCAccessibilityElement?
            activeApplicationElement = (XCAXClient_iOS.sharedClient() as! XCAXClient_iOS).activeApplications().first
            if activeApplicationElement == nil {
                activeApplicationElement = (XCAXClient_iOS.sharedClient() as! XCAXClient_iOS).systemApplication() as? XCAccessibilityElement
            }
            let pid = activeApplicationElement?.processIdentifier    #通过私有api 获取当前前台pid 
            if pid == nil{
                return 0
            }
            return pid!
        }
    

    上述检测方式 因为使用 xcaxclient 私有 api 和 launch 只能在主线程中执行,故只能通过定时方式检测并插入高优先级队列执行。而且要尽量缩短其耗时从而不会影响其他各点击事件的执行频率

    2) 低概率检测事件,获取 pid 前增加延迟

    public func addXCTestTapAlertAction(interval: Int, application: XCUIApplication) {
            addAction(interval: interval) { [weak self] in
                usleep(2000000)   #sleep 2s
                let isRunning = application.running
                let current = Int(XCTestWDFindElementUtils.getAppPid())
    

    3) 最后一关把控,当 resovle 前再检测一次

    func resolve() throws {
            self._application.query()
            let pid = self._application.processID
            let activeApplicationElement = (XCAXClient_iOS.sharedClient() as! XCAXClient_iOS).activeApplications().first
            let currentprocessID = activeApplicationElement?.processIdentifier     #@A@
            if pid != currentprocessID{    #最后把关 pid不同 则抛出异常
                throw OperationError.Error
            }
            #@B@
            self._application?.resolve()  
    
        }
    

    此处实现目前仍存在瑕疵,如果 app 在上述@A处仍在前台,@B处却切到后台,monkey 可能 crash,原因是此时 application 已不在 _application.resolve 崩溃。但当 xcode9 发布时应该就不存在问题了,新 api 提供了 state,可以线程检测当前状态
    (此崩溃仅会出现在 开启基于的控件点击)

    未来后续;
    1) 瑕疵修正
    2) 性能监控
    3) 崩溃分析
    4) 控件选择子 算法

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月11日

    404 那个发帖时链接多了个( ,不明所以。。
    这个仅仅是 api 简易说明。google 搜搜就有了

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月10日

    swift 的 https://github.com/zalando/SwiftMonkey/blob/master/SwiftMonkey/MonkeyXCTestPrivate.swift

    另外 oc 的 wda 提供了 https://github.com/facebook/WebDriverAgent/blob/master/PrivateHeaders/XCTest/XCEventGenerator.h

    https://bootstraponline.github.io/xcuitest/Xcode_7.2_7C68)/private_docs/html/Classes/XCEventGenerator.html(

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月07日

    xctestwd 里已有 api 取 title

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月05日

    取 title 辅助定位就行。appname 会引起个问题,那个函数要重写了

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月04日

    已完成 基于控件的点击,解析出所有控件,随机某个控件点其中心点 。每秒大概 3-4 个 action

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月04日

    log 的 就记录每个 action 后 点击什么页面什么位置。

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月04日

    重新 launcher 就调的 XCUIApplication.launch()
    但这样会重启 app,我希望能后台切回前台是最好的。
    见 官方 api
    https://developer.apple.com/documentation/xctest/xcuiapplication

    感觉应该用 activate() 但目前只是 beta 的

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月04日

    自己加了个接口。

    这个取得是 xml 里 节点属性 name

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月04日

    打个比方,会出现点击了 20 次 可能才截出 6,7 张图。 截图比较鸡肋,实际效果不如录像或者 log

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月04日

    截图没有细研究,目前调试看截图是异步的,跟不上 action 的速度

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月02日

    共勉

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年08月02日

    稍微改造下可以的。

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年07月31日

    补充一个业务流程

  • 请教全链路压测的概念 at 2017年07月30日

    我理解是 用线上真实数据在生产环境上回放流量 或加倍回放。

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年07月29日

    可以的。这个链路执行的时候 ,随机会暂停。执行完随机再继续。只要设置好各个链路的触发点即可。相对于单个链路中的行为不随机,而不同链路之间也是随机的

  • (已开源) 基于 XCTestWD,swiftmonkey 二次开发,实现无需插桩的 iOS monkey 自动化工具 fastmonkey at 2017年07月29日

    业务流程脚本? 比如登陆吗? 如果是跑 monkey 过程中插入一些特定业务逻辑是可以的。 业务逻辑实际就是原子性的一系列点击输入。 如果是按 case 跑目前还不支持 改造会比较大 但理论上也是可以的

  • Pro Flight YOKE 设备键位映射踩过的坑 at 2017年07月28日

    这工作环境略叼!

  • SwiftMonkey :iOS 上的 monkey at 2017年07月17日

    另外确实可以不需要源码,参考 wda 实现的方式,swiftmonkey 实现一个监听的 server
    xcode 执行 xcuitestcase 时先启一个 server,而后再往这个端口发指令,server 接受到指令后创建一个 session 并启动待测 app,然后调起 monkey

  • SwiftMonkey :iOS 上的 monkey at 2017年07月17日

    命令行启动 可以用 xcodebuild

  • 上一页
  • 1
  • 2
  • 3
  • …
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 下一页
  • 关于 / 活跃用户 / 中国移动互联网测试技术大会 / 反馈 / Github / API / 帮助推广
    TesterHome社区,测试之家,由众多测试工程师组织和维护的技术社区,致力于帮助新人成长,提高测试地位,推进质量发展。Inspired by RubyChina
    友情链接 WeTest腾讯质量开放平台 / InfoQ / 掘金 / SegmentFault / 测试窝 / 百度测试吧 / IT大咖说
    简体中文 / 正體中文 / English

    ©testerhome.com 测试之家   渝ICP备2022001292号
      渝公网安备 50022202000435号    版权所有 © 重庆年云聚力信息技术有限公司