android客户端测试用例,测试开发笔记七(客户端测试平台)

01 | 自动遍历测试方法与常见技术介绍

背景

自动化测试成本高,周期长,只能覆盖主场景

业务量大,手工测试无法覆盖所有功能点

自动化遍历测试

code less:用例维护成本降低到最低

automate:尽可能的自动化覆盖回归业务

常见遍历工具与技术

google android原生monkey、app crawler

百度smartmonkey

腾讯newmonkey

vigossjjj smart_monkey

macaca的NoSmoke

头条zhangzhao maxim

seveniruby appcrawler

02 | android monkey测试工具

优点

速度非常快

编码特别少

缺点

就像一只猴子不受控制,随机发生、随机点击、随机输入

安装

android sdk自带

使用

基本配置(设置事件数量)

操作约束(指定app)

设置事件类型和频率

调试选项

adb shell monkey [options] 事件计数

命令

1.adb shell monkey 100对所有包随机操作

2.adb shell monkey -p com.xueqiu.android 100对指定包

3.adb shell monkey -p com.xueqiu.android -s 20 80重复刚才的操作

4.adb shell monkey -p com.xueqiu.android -vv -s 20 80详细日志

5.adb shell monkey -p com.xueqiu.android --throttle 5000 100每个事件延迟5000ms执行

6.adb shell monkey -p com.xueqiu.android --pct-touch 10 1000时间百分比

常用事件

1.--pct-touch触摸事件(点击)

2.--pct-motion动作时间(直线滑动)

3.--pct-trackball轨迹事件(移动、点击、曲线滑动)

4.--pct-majornav主要导航事件(回退按键、菜单按键)

03 | AppCrawler跨平台自动遍历测试

与其他框架额关系

appcrawler底层引擎

1.appium

2.adb

3.macaca

4.selenium

AppCrawler环境要求

appcrawler2.5

1.java8 appium 1.8.x

快速启动

启动appium

启动模拟器或连接真机

开始自动遍历

appcrawler --capability "appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias"

执行参数与配置文件

capbility设置:与appium完全一致

testcase:用于启动app后的基础测试用例

selectedList:遍历范围设定

triggerActions:特定条件触发执行动作的设置(如关闭广告)

执行参数比配置文件优先级高

testcase

testcase完整形态

1.given:所有的先决条件

2.when:先决条件成立后的行为

3.then:断言集合

testcase的简写形态

1.xpath:对应when里的xpath

2.action:对应when的action

action

back

monkey随机事件

执行代码

1.Thread.sleep(3000)

2.driver.swipe(0.9,0.5,0.1,0.5)

3.click

4.longTap

自动遍历支持

selectedList:需要被遍历的元素范围

firstList:优先被选中并执行的元素

lastList:最后被选中并执行的元素

tagLimitMax:同祖先的元素最多点击次数

backButton:当所有元素都被点击后默认后退控件定位

blackList:黑名单

maxDepth:遍历的最大深度(每点开一个activity,深度加1)

触发器triggerActions

需要特定次数的触发动作

通常用于处理弹框

1.xpath:指定具体按钮

2.action:动作

3.times:规则的使用次数

工作过程

信息的获取(把当前app的界面下载为xml结构)

获取待遍历元素

1.遍历范围 selectedList

2.过滤黑名单、小控件、不可见控件、blacklist

3.重排控件顺序 firstList lastList

4.跳过已点击+跳过限制点击的控件tagLimit

5.根据匹配的规则执行action

循环上面的步骤

日志

java -jar appcrawler-2.4.0-jar-with-dependencies.jar --capability "appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias"

当前目录生成大量丰富的图片日志

appcrawler.log 搜索 current index

生成配置文件模板

java -jar appcrawler-2.4.0-jar-with-dependencies.jar --demo 生成配置文件模板

demo.yml

---

pluginList: []

saveScreen: true

reportTitle: ""

resultDir: "20200518154719"

waitLoading: 500

waitLaunch: 6000

showCancel: true

maxTime: 10800

maxDepth: 10

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: "//*[@text='行情']"

action: click

selectedList:

- xpath: "//*[contains(@resource-id,'single_line_wrapper')]//*[@clickable='true']"

- xpath: "//*[contains(@resource-id,'ll_main')]//*[@clickable='true']"

firstList:

- xpath: "//*[contains(@resource-id,'ll_main')]//*[@clickable='true']"

lastList:

- given: []

when: null

then: []

xpath: "//*[@selected='true']/..//*"

action: null

actions: []

times: 0

- given: []

when: null

then: []

xpath: "//*[@selected='true']/../..//*"

action: null

actions: []

times: 0

backButton:

- given: []

when: null

then: []

xpath: "Navigate up"

action: null

actions: []

times: 0

triggerActions:

- given: []

when: null

then: []

xpath: "share_comment_guide_btn"

action: null

actions: []

times: 0

xpathAttributes:

- "name"

- "label"

- "value"

- "resource-id"

- "content-desc"

- "instance"

- "text"

sortByAttribute:

- "depth"

- "list"

- "selected"

findBy: "default"

defineUrl: []

baseUrl: []

appWhiteList: []

urlBlackList: []

urlWhiteList: []

blackList:

- given: []

when: null

then: []

xpath: ".*[0-9]{2}.*"

action: null

actions: []

times: 0

beforeRestart: []

beforeElement:

- given: []

when: null

then: []

xpath: "/*"

action: "Thread.sleep(500)"

actions: []

times: 0

afterElement: []

afterPage: []

afterPageMax: 2

tagLimitMax: 2

tagLimit:

- given: []

when: null

then: []

xpath: "??"

action: null

actions: []

times: 1000

- given: []

when: null

then: []

xpath: "?§Ý"

action: null

actions: []

times: 1000

- given: []

when: null

then: []

xpath: "share_comment_guide_btn_name"

action: null

actions: []

times: 1000

assertGlobal: []

04 | 多设备管理平台STF

简介

OpenSTF是个手机设备管理平台

可以对手机进行远程管理、调试、远程手机桌面监控等操作

安装

拉取镜像

1.docker pull openstf/stf:lastest

2.docker pull sorccu/adb:lastest

3.docker pull rethinkdb:lastest

启动rethinkdb

docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090

启动stf

docker run -d --name stf --net host openstf/stf stf local --allow-remote

远程调试真机

真机打开调试模式,与STF在同一网段

adb -s 设备名 tcpip 5555 给设备开调试端口

adb -s RFCMC00LKZH shell ifconfig 查看设备的ip地址,若访问被拒绝,可在设备中直接查看

adb connect 192.168.0.xx:5555 重新连接设备

若设备没有连接可重启adb再连接

adb kill-server

adb start-server

adb connect 192.168.0.xx:5555

05 | slenium Grid方案

简介

slenium grid远程运行selenium test

在多个机器上并行运行selnium

优点

所有测试的入口

管理和控制浏览器运行的notes/环境

扩展

并行运行测试

跨平台测试

负载均衡

流程图

8deec62e426d

image.png

下载与使用

启动Hub

java -jar selenium-server-standalone-3.141.59.jar -role hub

启动Node

先配置nodeConfig.json文件

{

"capabilities":

[

{

"browserName": "firefox",

"marionette": true,

"maxInstances": 5,

"seleniumProtocol": "WebDriver"

},

{

"browserName": "chrome",

"maxInstances": 5,

"seleniumProtocol": "WebDriver"

},

{

"browserName": "internet explorer",

"platform": "WINDOWS",

"maxInstances": 1,

"seleniumProtocol": "WebDriver"

},

{

"browserName": "safari",

"technologyPreview": false,

"platform": "MAC",

"maxInstances": 1,

"seleniumProtocol": "WebDriver"

}

],

"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",

"maxSession": 5,

"port": -1,

"register": true,

"registerCycle": 5000,

"hub": "http://localhost:4444",

"nodeStatusCheckTimeout": 5000,

"nodePolling": 5000,

"role": "node",

"unregisterIfStillDownAfter": 60000,

"downPollingLimit": 2,

"debug": false,

"servlets" : [],

"withoutServlets": [],

"custom": {}

}

在不同窗口执行以下命令,可启动多个node

java -jar selenium-server-standalone.jar -role node -nodeConfig nodeConfig.json

代码

注:若想并发执行,需用多线程

from selenium.webdriver import DesiredCapabilities

from selenium.webdriver import Remote

class TestGrid:

def test_grid(self):

hub_url = "http://127.0.0.1:4444/wd/hub"

capability = DesiredCapabilities.CHROME.copy()

for i in range(1,5):

driver = Remote(command_executor=hub_url,desired_capabilities=capability)

driver.get("https://www.baidu.com")

06 | 基于jenkins的自动化调度

持续集成

自动化冒烟测试

自动化用例运行

自动化遍历测试运行

兼容性测试

核心依赖资源

设备集群:真机、模拟器、云端设备

管理平台:STF,jenkins,selenium Grid

测试用例:遍历工具,测试工具

07 | app自动化测试平台实战1

参考资料

Monkey

基本语法

adb shell monkey [option]

monkey参数

monkey [-p ALLOWED_PACKAGE [-p ALLOWED_PACKAGE] ...]

[-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]

[--ignore-crashes] [--ignore-timeouts]

[--ignore-security-exceptions]

[--monitor-native-crashes] [--ignore-native-crashes]

[--kill-process-after-error] [--hprof]

[--pct-touch PERCENT] [--pct-motion PERCENT]

[--pct-trackball PERCENT] [--pct-syskeys PERCENT]

[--pct-nav PERCENT] [--pct-majornav PERCENT]

[--pct-appswitch PERCENT] [--pct-flip PERCENT]

[--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]

[--pct-permission PERCENT]

[--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]

[--pkg-whitelist-file PACKAGE_WHITELIST_FILE]

[--wait-dbg] [--dbg-no-events]

[--setup scriptfile] [-f scriptfile [-f scriptfile] ...]

[--port port]

[-s SEED] [-v [-v] ...] # 伪随机数生成器的seed值,相同seed值再次执行monkey,产生相同的事件序列

[--throttle MILLISEC] [--randomize-throttle]

[--profile-wait MILLISEC]

[--device-sleep-time MILLISEC]

[--randomize-script]

[--script-log]

[--bugreport]

[--periodic-bugreport]

[--permission-target-system]

COUNT

monkey命令

adb shell monkey -p com.xueqiu.android --throttle 500 -s 100 100

adb shell monkey -p com.xueqiu.android --throttle 500 --pct-touch 10 --pct-syskeys 90 100

maxim

下载安装

1.git clone https://github.com/zhangzhao4444/Maxim.git

2.将2个jar包推送到手机

adb push framework.jar /sdcard

adb push monkey.jar /sdcard

3.执行命令

adb shell CLASSPATH=/sdcard/monkey.jar:/sdcard/framework.jar exec app_process /system/bin tv.panda.test.monkey.Monkey -p com.panda.videoliveplatform --uiautomatormix --running-minutes 60 -v -v

4.调用关系cat /system/bin/monkey

# Script to start "monkey" on the device, which has a very rudimentary

# shell.

#

base=/system

export CLASSPATH=$base/framework/monkey.jar

trap "" HUP

exec app_process $base/bin com.android.commands.monkey.Monkey $*

appcrawler

生成配置文件

java -jar appcrawler-2.4.0-jar-with-dependencies.jar --demo

工作原理

1.从页面的中间元素开始遍历

2.然后从左往右遍历

3.遍历深度(打开的activity数量)超过最大值,执行返回操作

4.遍历同级元素(activity下的拥有相同父节点的元素)超过最大限定值,执行返回操作

demo.yml

testcase(前置操作)

testcase:

name: "TesterHome AppCrawler"

steps:

- xpath: "我的"

action: click

- xpath: //*

action: driver.swipe(0.5,0.9,0.5,0.1)

- xpath: "设置"

action: click

triggeraction(去掉广告,处理弹窗)

triggerActions:

- xpath: "//*[@resource-id='com.xueqiu.android:id/iv_close']"

action: click

selectedList

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: "//*[@resource-id='com.xueqiu.android:id/tv_search']"

action: click

- xpath: "//*[@resource-id='com.xueqiu.android:id/search_input_text']"

action: "alibaba"

- xpath: "阿里巴巴-SW"

action: click

- xpath: "//*[@resource-id='com.xueqiu.android:id/stockCode' and @text='09988']"

action: click

selectedList:

- xpath: "//*[@resource-id='com.xueqiu.android:id/tab_indicator_view']//android.widget.TextView"

- xpath: "//*[@resource-id='com.xueqiu.android:id/small_period_container']//android.widget.TextView"

firstList:

- xpath: "//*[@resource-id='com.xueqiu.android:id/tab_indicator_view']//android.widget.TextView"

08 | app、web自动化测试平台实战2

selenium工具集

selenium remote control:selenium 1.0版本

selenium webdriver:selenium 2.0版本

selenium server

selenium client

selenium IDE

selenium Grid:分布式管理设备和脚本运行

环境搭建

selenium-server

1.下载地址:https://www.selenium.dev/downloads/

2.启动hub

java -jar selenium-server-standalone-3.141.59.jar -role hub

3.访问http://192.168.1.100:4444/grid可在页面上查看注册到hub上的结点设备

4.配置appnode.json(配置说明可参考https://www.cnblogs.com/yyoba/p/11304034.html

)

{

"capabilities": [{

"deviceName": "127.0.0.1:62001",

"version": "4.4.2",

"maxInstances": 1,

"platform": "ANDROID",

"browserName": ""

}],

"configuration": {

"cleanUpCycle": 2000,

"timeout": 30000,

"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",

"hub": "127.0.0.1:4444/grid/register",

"url": "http://127.0.0.1:5723/wd/hub",

"host": "127.0.0.1",

"port": 5723,

"maxSession": 1,

"register": true,

"registerCycle": 5000,

"hubPort": 4444,

"hubHost": "127.0.0.1",

"hubProtocol": "http"

}

}

5.启动node结点

appium -p 5723 --nodeconfig appiumnode.json

adb -s 设备编号 若链接多台设备,可用"-s"指定设备编号

adb -s 设备编号 shell am start -n package/activity

6.代码

import os

from appium import webdriver

class TestGrid:

def setup(self):

caps = {}

caps['platformName'] = 'Android'

caps['platformVersion'] = '6.0'

caps['appPackage'] = 'com.xueqiu.android'

caps['appActivity'] = '.view.WelcomeActivityAlias'

caps['noRest'] = True

# udid = os.getenv("udid")

caps['udid'] = "127.0.0.1:7555"

# caps['udid'] = udid

self.driver = webdriver.Remote("http://192.168.1.100:4444/wd/hub", caps)

self.driver.implicitly_wait(10)

def teardown(self):

self.driver.quit()

def test_search(self):

self.driver.find_element_by_id("com.xueqiu.android:id/tv_search").click()

self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text").send_keys("alibaba")

7.遍历本机设备

#!/bin/bash

for i in $(adb devices | grep "devices" | awk '{print $1}')

do

echo "start:{$i}"

udid=$i pytest test_search.py &

done

09 | 自动化测试平台实战3-STF

STF解决的问题

远程设备手动调试

远程设备自动化调试

安装方式

mac

brew install rethinkdb graphicsmagick zeromq protobuf yasm pkg-config

linux:docker

拉取镜像

docker pull openstf/stf:latest

docker pull sorccu/adb:latest

docker pull rethinkdb:latest

启动容器(rethinkdb,openstf)

docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090

docker run -d --name stf --net host openstf/stf stf local --allow-remote

关闭容器

docker stop stf

windows不建议安装

搭建局域网STF

docker run -d --name stf3 --net host openstf/stf stf local --allow-remote --public-ip 192.168.0.103

docker logs -f stf3 查看日志

搭建自动化调试

获取token

STF - Setting - keys:新建keys

调用接口

1.获取用户信息:

curl -H 'Authorization: Bearer 4eea142d8c4a4fee9f8426e7eb7602422ea04144589143a9b9bc60bc8dddc35e' http://localhost:7100/api/v1/user | jq .

2.获取所有设备信息,并进行重要字段提取

curl -H "Authorization: Bearer $token" http://localhost:7100/api/v1/devices | jq -c '.devices[] | [.serial,.present,.remoteConnectUrl]'

3.获取所有可用的设备

curl -H "Authorization: Bearer $token \

" http://localhost:7100/api/v1/devices |

jq -c '.devices[]|[.serial,.present,.remoteConnectUrl]'|

grep true | awk -F \" '{print $2}'

4.stf.sh

#!/usr/bin/env bash

set -uxo pipefail

STF_TOKEN=xxx

STF_URL=xxx

DEVICE_SERIAL=xxx

if [ "$DEVICE_SERIAL" == "" ]; then

echo "Please specify device serial using ENV['DEVICE_SERIAL']"

return 1

fi

if [ "$STF_URL" == "" ]; then

echo "Please specify stf url using ENV['STF_URL']"

return 1

fi

if [ "$STF_TOKEN" == "" ]; then

echo "Please specify stf token using using ENV['STF_TOKEN']"

return 1

fi

function get_device

{

curl -H "Authorization: Bearer $STF_TOKEN \

"$STF_URL/api/v1/devices | \

jq -c '.devices[]|[.serial,.present,.remoteConnectUrl]'| \

grep true | awk -F \" '{print $2}'

}

# 授权

function add_device

{

response=$(curl -X POST -H "Content-Type: application/json" \

-H "Authorization: Bearer $STF_TOKEN" \

--data "{\"serial\": \"$DEVICE_SERIAL\"}" $STF_URL/api/v1/user/devices)

success=$(echo "$response" | jq .success | tr -d '"')

description=$(echo "$response" | jq .description | tr -d '"')

if [ "$success" != "true" ]; then

echo "Failed because $description"

return 1

fi

echo "Device $DEVICE_SERIAL added successfully"

}

# 将设备拉到本地

function remote_connect

{

response=$(curl -X POST \

-H "Authorization: Bearer $STF_TOKEN" \

$STF_URL/api/v1/user/devices/$DEVICE_SERIAL/remoteConnect)

success=$(echo "$response" | jq .success | tr -d '"')

description=$(echo "$response" | jq .description | tr -d '"')

if [ "$success" != "true" ]; then

echo "Failed because $description"

return 1

fi

remote_connect_url=$(echo "$response" | jq .remoteConnectUrl | tr -d '"')

adb connect $remote_connect_url

echo "Device $DEVICE_SERIAL remote connected successfully"

}

function remove_device

{

response=$(curl -X DELETE \

-H "Authorization: Bearer $STF_TOKEN" \

$STF_URL/api/v1/user/devices/$DEVICE_SERIAL)

success=$(echo "$response" | jq .success | tr -d '"')

description=$(echo "$response" | jq .description | tr -d '"')

if [ "$success" != "true" ]; then

echo "Failed because $description"

return 1

fi

echo "Device $DEVICE_SERIAL removed successfully"

}

5.同时启动多台设备

function get_device

{

curl -H "Authorization: Bearer $STF_TOKEN" $STF_URL/api/v1/devices | jq -c '.devices[]|[.serial,.present,.remoteConnectUrl]'

}

function get_remote_device

{

get_device | grep true | awk -F \" {'print $4'}

}

function run

{

get_remote_device|while read line; do { nohup adb -s $line shell monkey 1000 &};done

}

启动本地emulator设备

emulator -list-avds

emulator @设备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值