自动化等测试的问题点
移动端业务问题
- 业务线众多
- 业务流程复杂
- 依赖传统券商一些资源
雪球app存在的问题
- 存在股票信息字段内容丢失或者数据异常
- 微信分享不可用
- 用户网络慢时发出请求后退出当前页面发现崩溃
- 某些界面在4.4和5.0的系统操作上体验不同
- 界面奔溃
解决方法
- 自动化解决
- 产品迭代快速
- 学习设计模式PO
- 手工解决
- 界面字段正确性:比如股票相关数据变化,共数十个字段
- 接口正确性:后端接口传输的变化和内容
- 专项测试回归难度大:内存泄漏、健壮性测试、弱网等测试过程中太多
- 回归工作量大:不回归又会漏测
改进策略
- 自动化测试
- 覆盖主要业务的right path
- 缩小规模尽量降低维护成本
- 手工测试
- 覆盖新功能测试
- 探索性测试
自动遍历测试
- code less:用例维护成本降低到最低
- automate:尽可能的自动化覆盖回归业务
appcrawler
开源地址:https://github.com/seveniruby/AppCrawler
appcrawler的底层引擎
- appcrawler的底层引擎
- appium(主要是他,所以速度不是特别快)
- adb
- selenium
- appium的底层引擎
- wda
- uiautomator2
appcrawler环境要求和简单运行参数
- java 1.8
- 要有appium
- 参数模式
- java -jar appcrawler --demo
- appcrawler --capability “appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias”
- 配置文件【推荐方法】
- java -jar appcrawler
- -c example.yml
- –capability ‘appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias’
- -o /tmp/xueqiu/1
- java -jar appcrawler.jar -vv -c demo3.yml 加-vv可以看到更多日志文件
执行参数与配置文件
- capability设置:与appium完全一致
- testcase:用于启动app后的基础测试用例
- selectedList:遍历范围设定
- triggerActions:特定条件触发执行动作的设置
- 注:执行参数比配置文件优先级高
capability设置例子
- “appPackage”:“com.xueqiu.android”,
- “appActivity”:“.view.WelcomeActivityAlias”,
- “noReset”:“true”,
- “dontStopAppOnReset”:“true”
自动化支持testcase这个好像很难
- testcase的完整形态
- given:所有的先决条件
- when:先决条件成立后的行为
- then:断言集合
- testcase的简写形态
- xpath:对应when里的xpath
- action:对应when的action
动作支持action
- ""只是截图记录
- back 退后
- backapp 回退到当前的app,默认等价于back行为,可定制
- monkey 随机事件
- xxx()
- Thread.sleep(3000)
- driver.swipe(0.9,0.5,0.1,0.5)
- click
- longTap
- 非以上所有行为是输入xx ddd
自动遍历
- 自动遍历的支持
- selectedList:需要被遍历的元素范围
- firstList:优先被点击
- lastList:最后被点击
- tagLimitMax:同祖先同类型的元素最多点击多少次
- backButtion:当所有元素都被点击后默认后退控件定位
- blackList:黑名单
- maxDepth:遍历的最大深度
- 自动遍历过程
- 信息的获取
- 把当前app的界面dump为xml结构
- 获取待遍历元素
- 遍历范围selectedList
- 过滤黑名单,小控件,不可见控件,blacklist
- 重排控件顺序,fistlist,lastlist
- 跳过已点击+跳过限制点击的控件tagLimit
- 根据匹配的规则执行action
- 循环上面的步骤
- 信息的获取
触发器
- 解决弹窗后,程序无法执行的问题,或者解决登录输入账号密码的问题
- triggerAcitons
- 需要特定次数的触发动作
- 通常用于处理弹窗框
- xpath:指定具体按钮
- action:动作
- times:规则的使用次数
appcrawler的日志
- 位置在appcrawler运行结束后生成的文件夹里面的appcrawler文件
- current index = 0 表示执行的第一个动作,0是初始值
- rlStack=Stack(UpdateDialogActivity) baseUrl=List() maxDepth=10 表示当前的页面是UpdateDialogActivity,还没达到最高的activity的栈10层,所以没关系
appcrawler最简单的运行方式
- 打开appium
- java -jar appcrawler.jar --capability “appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias”
- 有时候运行着就会自己报错了,搞不懂
appcrawler通过配置文件去运行
- java -jar appcrawler.jar --demo 生成一个配置的demo文件
- 如果运行报错,无法找到文件,因此建议在win10的管理者权限运行
- demo文件参数的小解析
- saveScreen: true 表示需要截图
- maxDepth: 10 执行activity的深度为10
- capability的设置如下
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
appPackage: "com.xueqiu.android"
appActivity: ".view.WelcomeActivityAlias"
- testcase
- name表示用例名字
- steps表示步骤,找到元素后点击即可
- 这里是指一开始进入app后,最优先的操作,可以缩小app的测试范围
testcase:
name: "TesterHome AppCrawler"
steps:
- xpath: "//*[@text='行情']"
action: click
- selectedList
- 当前testcase页面中,我们需要点击的范围是什么,可以有多个范围
selectedList:
- xpath: "//*[contains(@resource-id,'stock_index_quote_view_layout')]//*[@clickable='true']"
- xpath: "//*[contains(@resource-id,'content_recycler')]//*[@clickable='true']"
- firstList
- 从selectedList的各种范围内选取一个,优先执行
firstList:
- xpath: "//*[contains(@resource-id,'content_recycler')]//*[@clickable='true']"
- lastList
- 从selectedList的各种范围内选取一个,最后执行
- 执行:java -jar appcrawler.jar -c demo.yml
如果报错的话,看看vim开头是不是有乱码,把第一行的—删除也是ok的,然后把编码改成UTF-8
实战1:雪球一个小页面的自动遍历
- 打开app
- 点击我的
- 进行滑动,点击设置,因为设置在在底部
- 在设置页面完成自动化遍历
- 运用到testcase,selectlist默认不变才可以遍历设置的所有元素
demo.yml配置如下
- selectlist等配置不变,就变capability和testcase
- xpath包含全部元素直接写//,不需要写成"//"
- 滑动时driver.swipe(0.5,0.9,0.5,0.1),分别是对应屏幕的百分比,左上角坐标为0和0,右下角为1和1
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
appPackage: "com.xueqiu.android"
appActivity: ".view.WelcomeActivityAlias"
testcase:
name: "TesterHome AppCrawler"
steps:
- xpath: "我的"
action: click
- xpath: //*
action: driver.swipe(0.5,0.9,0.5,0.1)
- xpath: "设置"
action: click
实战2:雪球处理广告点击x和其他有x的界面点击
- 处理有些广告下的xx元素的点击
- 点击主页的雪球,点击左下角那支笔的图标
- 进入下一个界面,右下角有一个x,做到遇到x就自动点击,用triggerAcitons触发器来处理
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
appPackage: "com.xueqiu.android"
appActivity: ".view.WelcomeActivityAlias"
testcase:
name: "TesterHome AppCrawler"
steps:
- xpath: "雪球"
action: click
- xpath: "//*[contains(@resource-id,'post_status')]"
action: click
triggerActions:
- xpath: "//*[contains(@resource-id,'iv_close')]"
action: click
实战3:搜索一个阿里巴巴,股票,进入股票界面,优先点击某个区域,再点击其他特定区域
- 点击搜索框
- 搜索框输入alibaba
- 选择第二个阿里巴巴-SW
- 选择09988的股票,进入股票页
- 先点击下面的讨论、资金、咨询、公告、简况、财务,这里用到firstlist
- 然后再点击上半部分的分时、五日、日K、周k、月k、季k、年k、分钟,这样用到selectlist
- afterPageMax: 10 不然就无法遍历7个元素了
- tagLimitMax: 10 不然就无法遍历7个元素了
capability:
noReset: "true"
fullReset: "false"
appium: "http://127.0.0.1:4723/wd/hub"
appPackage: "com.xueqiu.android"
appActivity: ".view.WelcomeActivityAlias"
testcase:
name: "TesterHome AppCrawler"
steps:
- xpath: "//*[contains(@resource-id,'tv_search')]"
action: click
- xpath: "//*[contains(@resource-id,'search_input_text')]"
action: "alibaba"
- xpath: "//*[@text='阿里巴巴-SW']"
action: click
- xpath: "//*[contains(@resource-id,'stockCode') and @text='09988']"
action: click
selectedList:
- xpath: "//*[contains(@resource-id,'tab_indicator_view')]//android.widget.TextView"
- xpath: "//*[contains(@resource-id,'small_chart_stock_info_container')]//android.widget.TextView"
firstList:
- xpath: "//*[contains(@resource-id,'tab_indicator_view')]//android.widget.TextView"
afterPageMax: 10
tagLimitMax: 10