APP自动化测试和Web自动化测试的不同之处在于它的环境搭建更复杂,不过环境搭建之后,具体的操作步骤是类似的。都是定位元素+操作元素
之前有一篇使用WEditor开发APP自动化测试脚本可以拿来进行APP自动化的定位工具
这次介绍另一款更强大的工具「Sonic」
https://sonic-cloud.gitee.io/#/
由于需要连接的设备不多,这次采用「快速搭建」
下载官方提供的docker-compose.yml
文件
官方为了数据的持久化采用了本地的mysql数据库,但这样比较麻烦,所以直接修改一下
加了一下
db:
image: mysql
command: --character-set-server=utf8 --collation-server=utf8_general_ci
volumes:
- mysql_db:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: Sonic!@#123
MYSQL_DATABASE: sonic
MYSQL_ROOT_HOST: '%'
ports:
- "3307:3306"
networks:
- sonic-network
我这边主机的ip为172.28.253.211
,把它改成你自己的IP就可以了
version: '3'
services:
db:
image: mysql
command: --character-set-server=utf8 --collation-server=utf8_general_ci
volumes:
- mysql_db:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: Sonic!@#123
MYSQL_DATABASE: sonic
MYSQL_ROOT_HOST: '%'
ports:
- "3307:3306"
networks:
- sonic-network
sonic-server-simple:
image: "sonicorg/sonic-server-simple:v1.3.1-beta"
depends_on:
- db
environment:
#以下为MySql配置,localhost请替换为自己MySql服务的ipv4地址
- MYSQL_HOST=172.28.253.211
- MYSQL_PORT=3307
- MYSQL_DATABASE=sonic
- MYSQL_USERNAME=root
- MYSQL_PASSWORD=Sonic!@#123
#在服务器部署的话,localhost改为服务器ip,port更改为sonic-server-simple暴露的port(一般不变)
- SONIC_API_HOST=172.28.253.211
- SONIC_API_PORT=8094
- SONIC_NETTY_PORT=8095
#token加密的key值
- SECRET_KEY=sonic
#身份验证token有效天数
- EXPIRE_DAY=14
#前端页面访问地址,不填默认为http://localhost:3000
- CLIENT_HOST=http://172.28.253.211:3000
#文件保留天数(指测试过程产生的文件,包括图片、录像等等)
- FILE_KEEP_DAY=60
#测试结果保留天数
- RESULT_KEEP_DAY=60
#以下均为Cron表达式
#清理文件定时任务
- FILE_CRON=0 0 12 * * ?
#清理测试结果定时任务
- RESULT_CRON=0 0 12 * * ?
#发送日报定时任务
- DAY_CRON=0 0 10 * * ?
#发送周报定时任务
- WEEK_CRON=0 0 10 ? * Mon
networks:
- sonic-network
volumes:
- files:/keepFiles/
- files:/imageFiles/
- files:/recordFiles/
- files:/packageFiles/
- files:/logs/
ports:
- "8094:8094"
- "8095:8095"
sonic-client-web:
image: "sonicorg/sonic-client-web:v1.3.1-beta"
environment:
#在服务器部署的话,localhost改为服务器ip,port更改为sonic-server-simple暴露的port(一般不变)
- SONIC_API_HOST=172.28.253.211
- SONIC_API_PORT=8094
networks:
- sonic-network
ports:
- "3000:80"
volumes:
files:
mysql_db:
networks:
sonic-network:
driver: bridge
然后按照官网的说明run起来~
然后在插了手机的电脑上运行一个Agent
选择一台安卓设备进入
点击「控件元素」-「获取控件元素」就可以拿到元素定位信息了
把xpath推荐的语句拿出来就可以了
把它放到代码中
- page:
pageName: home_android
desc: 首页_android
locators:
- { desc: "挂号文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"挂号,全国7800+医院")]', name: "registered_text" }
同理拿到问诊和购药的文案
- { desc: "挂号文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"挂号,全国7800+医院")]', name: "registered_text" }
- { desc: "问诊文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"问诊,27万医生在线服务")]', name: "inquiry_text" }
- { desc: "购药文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"购药,微医自营购药更安心")]', name: "buy_medicine_text" }
鼠标移动到右上角就可以看到设备序列号了
编写一个fixture夹具来打开APP
后面可以根据需求把sys、udid、app放到jenkinsfile中实现参数化构建
@pytest.fixture(scope='module')
def home_android():
home = HomePage(file_name="home_android")
with allure.step(f"打开微医APP"):
home.open_phone(sys='android', udid="8688dab6", app='wy')
home.click(home.home_index) # 进入首页Tab
time.sleep(2)
yield home
home.close()
调试的时候修改打开手机对应的url
def open_phone(self, sys='android', udid="8688dab6", app='wys', apk=None):
"""
移动端打开操作
http://appium.io/docs/en/writing-running-appium/caps/
"""
url = "http://172.28.57.33:4723/wd/hub"
desired_caps = {"udid": udid}
if sys == 'android':
desired_caps['platformName'] = "Android"
if app == 'wys':
# 打开微医生APP
desired_caps["appPackage"] = "com.greenline.yihuantong"
desired_caps["appActivity"] = ".home.WelcomeActivity"
elif app == 'wy':
# 打开微医APP
desired_caps["appPackage"] = "com.greenline.guahao"
desired_caps["appActivity"] = ".home.WelcomeActivity"
desired_caps["skipServerInstallation"] = True
desired_caps["automationName"] = "UiAutomator2"
desired_caps["noReset"] = True
desired_caps["newCommandTimeout"] = 3600
elif sys == 'ios':
desired_caps['platformName'] = "iOS"
if app == 'wys':
# 打开微医生APP
desired_caps["bundleId"] = "com.minkanginfo.guahao"
elif app == 'wy':
# 打开微医APP
desired_caps["bundleId"] = "com.lvxian.guahao"
desired_caps["automationName"] = "XCUITest"
if apk:
desired_caps1 = copy.deepcopy(desired_caps)
desired_caps1["appPackage"] = "com.android.settings"
desired_caps1["appActivity"] = ".Settings"
driver = app_webdriver.Remote(url, desired_caps1)
if app == 'wys':
self.install_apk(driver, "com.greenline.yihuantong", apk)
elif app == 'wy':
self.install_apk(driver, "com.greenline.guahao", apk)
driver.quit()
print(desired_caps)
self.driver = app_webdriver.Remote(url, desired_caps)
self.wait_for(10)
return self.driver
注意这个函数内部根据实际打开的APP来进行修改或调整
根据需求修改
appPackage
appActivity
使用上面这个url的时候需要在对应的电脑上打开Appium,端口指定为默认端口4723
在给小米手机自动安装APP的时候老是有弹框,可以通过下面方式修改:
设置
-> 授权管理
-> 右上角设置按钮
-> USB安装管理
->关闭
如果授权管理页面的右上角没有设置按钮
在开发者选项
中 -> 启动MIUI优化
->关闭
再返回到授权页面,就可以看到 右上角的设置按钮了
关闭USB安装管理后,通过USB安装就不会有确认弹窗了
使用Appium控制部分安卓手机时,重复提示需要安装uiautomator2
desired_caps["skipServerInstallation"] = True
用例内容和上次一样,不过这次换成了打开APP
@compose(feature="微医APP", story="首页", title='主入口下方文案校验')
@pytest.mark.parametrize("way", ["registered_text", "inquiry_text", "buy_medicine_text"])
def test_home_android_text(home_android, way):
"""
按钮下方文案测试
* 挂号
* 问诊
* 购药
"""
ele = getattr(home_android, way)
with allure.step(f"查看{ele.desc}"):
text = home_android.get_attribute(ele, "content-desc")
if way == 'registered_text':
assert text == '挂号,全国7800+医院'
elif way == 'inquiry_text':
assert text == '问诊,27万医生在线服务'
elif way == 'buy_medicine_text':
assert text == '购药,微医自营购药更安心'
使用参数化的方式测试三个地方的文案是否符合要求
运行之后,直接在Sonic平台上查看运行的效果
代码见:https://gitee.com/zx660644/uitest/tree/first_android_test
IOS操作也同理