移动端测试

测试开发笔记七(客户端测试平台)

2020-05-21  本文已影响0人  提摩太_e9ec

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


背景

自动化遍历测试

常见遍历工具与技术

02 | android monkey测试工具


优点

缺点

安装

使用

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


与其他框架额关系

AppCrawler环境要求

快速启动

执行参数与配置文件

testcase

action

自动遍历支持

触发器triggerActions

工作过程

日志

生成配置文件模板

---
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


简介

安装

远程调试真机

adb kill-server
adb start-server
adb connect 192.168.0.xx:5555

05 | slenium Grid方案


简介

优点

流程图

image.png

下载与使用

启动Hub

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

启动Node

{
  "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": {}
}

代码

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的自动化调度


持续集成

核心依赖资源

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


参考资料

https://android.googlesource.com/platform/system/core/+/refs/tags/android-6.0.0_r5/adb/

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
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

https://github.com/zhangzhao4444/Maxim

# 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

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工具集

环境搭建

{
    "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解决的问题

安装方式

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

搭建局域网STF

docker run -d --name stf3 --net host openstf/stf stf local --allow-remote --public-ip 192.168.0.103
docker logs -f stf3 查看日志

搭建自动化调试

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设备

上一篇 下一篇

猜你喜欢

热点阅读