1.测试设备

adb shell start -n 要启动的页面:这样可以把你要启动的页面启动起来

start session是创建一个新的session

使用应用宝官网下载到电脑

安装应用:adb install -r xxx.apk

或者通过拖拽到模拟器中

 

多个模拟器或手机安装应用,使用以下命令:

如何安装openresty 如何安装应用宝_如何安装openresty

adb uninstall …卸载 

2.app文件

  • 下载安装

三种方式:

  1. 去应用商店或者app store下载安装
  2. 去网上下载(比如应用宝等平台),然后拖拽到手机上
  3. 将下载下来的应用,使用命令安装:

adb install **.apk

  • 卸载

卸载方式:

  1. 直接在模拟器上卸载,长按应用,拖拽删除
  2. 使用命令卸载:

adb uninstall  apk的包名

例如企业微信:

adb uninstall com.tencent.wework

3. Appium Desktop

点击 Start Server 启动服务

配置DesireCapability

{
    "platformName": "android”,
    "deviceName": "emulator-5554”, 
    "appPackage": "com.tencent.wework”, 
    "appActivity": ".launch.LaunchSplashActivity”, 
    "autoGrantPermissions": "true", #这个参数为true的时候 noReset参数不生效 
    "noReset": "true" #noReset 防止清除app的数据
}

adb 常用命令

adb devices

adb logcat | grep -i Displayed

adb shell am start -n 启动 activity

com.tencent.wework/.launch.LaunchSplashActivity

com.tencent.wework/.launch.WwMainActivity

注意:启动页与直接启动主页是不同的。 理论上任何一个页面都可以直接进去,但开发做了限制,不允许这么操作。只能从启动页开始,模拟真实用户使用场景。

 3.分析常用端口的意义

如何安装openresty 如何安装应用宝_端口号_02

self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
 0.0.0.0等同于localhost,是与脚本中的端口号是一致的,4723是seerver端与客户端建立连接的端口
UIAutomator2
Server APK

手机端(UI)会默认开启一个端口号,接收server端发送的请求,可以通过查看日志可以看到端口号是8200,只不过平时没有注意,也不用去配置它


如何安装openresty 如何安装应用宝_拖拽_03

5037

adb概念 是android跟pc端建立连接的一条指令 android debug bridge,通过它电脑就可以操纵手机的

底层,adb client就是我们输入的adb命令


如何安装openresty 如何安装应用宝_android_04


如何安装openresty 如何安装应用宝_拖拽_05

adb server与客户端进行通讯的端口5037

server通过usb跟手机连接,手机里有adbd这样一个服务,它可以跟adb server建立一个连接,adb connect 端口号,这个端口号是可以修改的

800*的都是chromedriver即webview进行通讯的端口号

所以一定要注意端口号是干嘛的

4.元素定位


如何安装openresty 如何安装应用宝_android_06

小技巧:appium desktop还可以保存之前的设置

定位元素的时候,如果名字一致怎么解决,通过兄弟节点查找到通讯录,By.XPATH和MobileBy都可以使用,当查找ID、或者xpath时

对于列表页内容很多需要滑动查询的时候,比如企业微信添加联系人,当联系人很多的时候,添加成员按钮在页面底部

可以通过滚动查找

'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("添加成员").instance(0))'

 

定位元素的原则, 如果有ID就一定使用ID

强制的等待不建议多加,但是平时调试啥的还是可以加个1s2s的


如何安装openresty 如何安装应用宝_android_07

 

例如查找姓名的输入框元素, 通过姓名去查找对应的元素是比较合理的,而不是通过输入框中的text=必填,姓名和必填是兄弟节点的关系

使用@text查找xpath中的姓名找不到,可以用contains⚠️❗️👍

因为这个姓名 开发后面多写了一个空格,就是姓名(空格),所以可以使用contains容易查找到

最后定位元素的的表达式如下:另外注意元素里面是单引号,外面要使用双引号,不然会报错!!

"//*[contains(@text,'姓名')]/..//*[@resource-id='com.tencent.wework:id/ase']"

两个点是代表他的父节点,就是查找父节点的子节点为id=。。。的元素

性别也是同样的方式去查找

appium中有一个官方文档可以去查看如何具体的使用, new UiSelector.text或者.resource-id .contains(text)等,可以查看文档中的使用方法

添加成功toast,一闪而过,是系统给的提示消息,打印pagesource,可以发现在xml文件最后,也就是最后在dom树中插入了

一个wiget toast,所以可以通过他的class属性去获取它或者使用xpath定位方式


如何安装openresty 如何安装应用宝_如何安装openresty_08

  

toast = self.driver.find_element(MobileBy.XPATH, "//*[@class='android.widget.Toast']").text
assert '添加成功' in toast

 

 如果屏幕中有多个相同的text,是默认定位第一个吗?是的

5.获取到当前页面activity

第一种方式:使用appium desktop


如何安装openresty 如何安装应用宝_拖拽_09

还有一种方式获取到当前页面activity

如何安装openresty 如何安装应用宝_如何安装openresty_10

断言这个activity就是当前运行的activity


如何安装openresty 如何安装应用宝_端口号_11

6.排错

通过行数查找出错位置,添加打印信息,期望值和实际值不一样才会出错,为什么不一样,哪儿不一样,通过打印一目了然,如果提供的信息仍旧查找不出错误来,我们可以结合服务端来查看报错信息


如何安装openresty 如何安装应用宝_拖拽_12

点击报错的行数,就可以直接定位到哪一行报错

7.参数化用例

由于参数化每执行一个参数会重新启动一次,因此为了使他不重新启动再改造一下,这里改成类方法, 然后在teardown中添加点击返回按钮,返回至通讯录页面

代码如下:

from time import sleep

from appium import webdriver
import yaml
import pytest
from appium.webdriver.common.mobileby import MobileBy


class Test_addmem():
    def setup_class(self):
        desired_caps = {}
        desired_caps['platformName'] = 'android'
        desired_caps['platformVersion'] = '6.0'
        desired_caps['deviceName'] = 'emulator-5554'
        desired_caps['appPackage'] = 'com.tencent.wework'
        desired_caps['appActivity'] = '.launch.LaunchSplashActivity'
        desired_caps['noReset'] = 'true'
        desired_caps['dontStopAppOnReset'] = 'true'
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
        self.driver.implicitly_wait(5)


    def setup(self):
        pass

    def teardown(self):
        self.driver.find_element(MobileBy.ID, 'com.tencent.wework:id/gpp').click()

    def teardown_class(self):
        self.driver.quit()
    #注意这里参数必须要加双引号,加单引号会报错
    @pytest.mark.parametrize("mobile,name,sex", [('17801153312', '测试账号12', '男'), ('17801153311', '测试账号11', '女')])
    def test_search(self, mobile, name, sex):
        # 查找通讯录
        el1 = self.driver.find_element_by_xpath("//*[@text='通讯录']")
        el1.click()
        # 添加成员
        el2 = self.driver.find_element_by_android_uiautomator(
            'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("添加成员").instance(0))')
        el2.click()
        # self.driver.find_element_by_id('com.tencent.wework:id/c56')

        self.driver.find_element(MobileBy.ID, 'com.tencent.wework:id/c56').click()
        sleep(2)
        # 输入姓名
        self.driver.find_element(MobileBy.XPATH,
                                 "//*[contains(@text,'姓名')]/..//*[@resource-id='com.tencent.wework:id/ase']").send_keys(
            name)
        # 输入手机号
        self.driver.find_element(MobileBy.ID, 'com.tencent.wework:id/emh').send_keys(mobile)
        # 选择性别
        self.driver.find_element(MobileBy.ID, 'com.tencent.wework:id/ate').click()
        #注意引号外面要加f
        self.driver.find_element(MobileBy.XPATH, f"//*[@text='{sex}']").click()
        # 点击保存
        self.driver.find_element(MobileBy.ID, 'com.tencent.wework:id/gq7').click()
        # print(self.driver.page_source)
        # self.driver.find_element(MobileBy.XPATH, "//*['@text=添加成功']")
        sleep(2)  #
        toast = self.driver.find_element(MobileBy.XPATH, "//*[@class='android.widget.Toast']").text
        assert '添加成功' in toast

也可以直接使用fixture,这样不至于显得很累赘,修改代码如下:


如何安装openresty 如何安装应用宝_如何安装openresty_13