本文为博主原创,未经授权,严禁转载及使用。
本文链接:https://blog.csdn.net/zyooooxie/article/details/124176686
之前分享过 使用uiautomator2 来搞APP自动化,分别是 https://blog.csdn.net/zyooooxie/article/details/124415385、 https://blog.csdn.net/zyooooxie/article/details/123916767,现在把 剩下的做个分享。
【实际这篇博客推迟发布N个月】
个人博客:https://blog.csdn.net/zyooooxie
【以下所有内容仅为个人项目经历,如有不同,纯属正常】
本期内容
本期主要是说 测试用例.py、元素定位.py、执行结果。
代码
下面是 按着 pageElements + testCases 来讲述的。
(代码有删改)
@filename: page_membership_interests_1.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
class PageMembershipInterests1(object):
"""
大陆APP
"""
SHAOHOU = dict(text="稍后")
GENGXIN1 = dict(resourceId="android:id/button1")
QUXIAO = dict(description="取消,按钮")
QUXIAO2 = '//*[@resource-id="zyooooxie:id/rnRootLayout"]/android.view.ViewGroup[2]/android.view.ViewGroup[2]/android.view.ViewGroup[2]'
WO = dict(text="我")
TANNENGLIANG = dict(text="")
HUIYUANZHONGXIN = dict(text="会员中心")
TANCHUANG = dict(text="close")
HUIYUANZHONGXIN_BIAOTI = dict(descriptionContains="标题")
HUITYANQUANYI = '//*[@resource-id="root"]/android.view.View[1]/android.view.View[1]'
JIFENSHANGCHENG = dict(text="积分商城")
WODEZHUANGXIANGTEQUAN = dict(text="我的专享特权")
CHENGZHANGTIXI = dict(textStartsWith="成长体")
ZANKAI = dict(text="展开")
BAOJIAYOUHUI = dict(text="")
SHOUJIANDUIJIANG = dict(text="")
QUANYIJIESHAO = dict(text="权益介绍")
QUANYINEIRONG = dict(text="权益内容")
LIJIQIANWANG = dict(text="立即前往")
LINGQUYOUHUIQUAN = dict(text="领取优惠券")
GONGXILINGQUCHENGGONG = dict(textStartsWith='恭喜领取成')
TOAST_WUCILIBAO = dict(text="无此礼包或库存不足")
TOAST_HUODONGBUCUNZAI = dict(text="活动不存在")
if __name__ == '__main__':
pass
@filename: test_membership_interests_1.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
import pytest
import allure
import os
import time
import cv2
import random
from pypinyin import lazy_pinyin
from uiautomator2 import Direction
from uiautomator2 import Device
from membership_interests_app_autotest.page_membership_interests_1 import PageMembershipInterests1
from membership_interests_app_autotest.common_function import my_element, my_assert, my_assert_toast
from membership_interests_app_autotest.common_function import kill_button, screenshot_decorator, get_user_id
from membership_interests_app_autotest.common_variable import dl, common_serial_number, dl_account
from membership_interests_app_autotest.common_variable import diff_pictures_path, now_pictures_path
from membership_interests_app_autotest.common_variable import pictures_path
from membership_interests_app_autotest.yy_function import crop_images, pic_diff
from membership_interests_app_autotest.common_mysql import exe_sql
from membership_interests_app_autotest.user_log import Log
print(dl_account, 'test_membership_interests_1.py')
def delete_award_packet_records():
# 做数据清理
user_id = get_user_id(mobile=dl_account)
sql1 = """DELETE FROM table_aprs WHERE USER_ID = '{}';""".format(user_id)
sql2 = """DELETE FROM table_aprsd WHERE USER_ID = '{}';""".format(user_id)
for s in [sql1, sql2]:
exe_sql(sql=s, db_name='zyooooxie_db')
# @pytest.mark.skip
@allure.feature('大陆APP')
@pytest.mark.parametrize('device_dl', dl,
indirect=True) # dl传给 device(fixture): indirect=True 表示将参数'before_after'当做一个函数去执行(即参数名要和定义的fixture的函数名一致),而不是一个参数变量,并且将 dl 当做参数传递给该函数
class TestMembershipInterests1(PageMembershipInterests1):
@staticmethod
def setup_method():
delete_award_packet_records()
@staticmethod
def teardown_method():
# 为了方便 看日志时确定 报错属于哪条用例
Log.info('---------')
def in_member_center(self, device: Device):
device.sleep(5) # 有时不稳定【某个升级弹窗 会弹多次】,加个强制等待
with allure.step('关闭升级弹窗'):
kill_button(device, self.SHAOHOU)
kill_button(device, self.QUXIAO)
kill_button(device, self.QUXIAO2, wait_time=2)
with allure.step('点击会员中心'):
my_element(device, self.WO).click()
my_assert(device, self.TANNENGLIANG, 'exists', True, 'is_', assert_time=5)
my_element(device, self.HUIYUANZHONGXIN).click()
with allure.step('关闭会员中心-弹窗'):
kill_button(device, self.TANCHUANG, wait_time=8)
my_assert(device, self.HUIYUANZHONGXIN_BIAOTI, 'exists', True, 'is_', assert_time=5)
with allure.step('进入会员权益'):
my_element(device, self.HUITYANQUANYI).click()
with allure.step('断言方法 my_assert()'):
my_assert(device, self.WODEZHUANGXIANGTEQUAN, 'exists', True, 'is_')
my_assert(device, self.CHENGZHANGTIXI, 'get_text', '成长体系', 'eq')
# my_assert(device, self.QUXIAO, no_exists=True)
# @pytest.mark.skip
@screenshot_decorator(connect_addr=common_serial_number)
@allure.description('会员权益领取某个权益')
@allure.title('会员中心-会员权益-领取')
def test_1(self, device_dl: Device):
self.in_member_center(device=device_dl)
my_element(device_dl, self.ZANKAI).click()
device_dl.swipe_ext(Direction.UP)
with allure.step(''):
my_element(device_dl, self.BAOJIAYOUHUI).click()
with allure.step('领取优惠券、断言'):
my_element(device_dl, self.LINGQUYOUHUIQUAN).click()
# # 现在2是:礼包不足 -> (toast)无此礼包或库存不足
# my_assert_toast(device_dl, '包或库', 'contains', element=self.LINGQUYOUHUIQUAN, toast_text='无此礼')
# my_assert_toast(device_dl, '库存不足', 'contains', x=0.5, y=0.92, toast_text='无此礼')
# 以前1是:活动已正常 -> 正常领取
my_assert(device_dl, self.GONGXILINGQUCHENGGONG, 'exists', True, 'is_')
# # 以前0是:礼包配置有问题 -> (toast)礼包不存在
# # device_dl.double_click(x=0.5, y=0.92) # 传百分比
# # my_assert(device_dl, cls.TOAST_HUODONGBUCUNZAI, 'exists', True, 'is_') # 断言toast存在,有时成功、有时失败
# my_assert_toast(device_dl, '不存', 'contains', element=self.LINGQUYOUHUIQUAN, toast_text='礼包不')
# my_assert_toast(device_dl, '存在', 'contains', x=0.5, y=0.92, toast_text='礼包不')
if __name__ == '__main__':
pass
pytest.main(['-s', '-v', '{}'.format(__file__)])
# pytest.main(['-s', '-m', 'smoke', '-v', '{}'.format(__file__)])
----------------------------------------------
@filename: page_membership_interests_2.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
class PageMembershipInterests2(object):
"""
香港APP
"""
vConsole = dict(resourceId="__vconsole")
HUIYUAN = dict(text="會員")
JIFENZONGSHULIANG = '//*[@resource-id="app"]/android.view.View[4]'
HUIYUANDUXIANG = dict(text="會員獨享")
JIFENGUIZE = dict(text="積分規則")
ZHUYI = dict(text="注意")
SHUNFENGDIANZITAOPIAOYOUHUI = dict(text="")
QUQIANGGOU = dict(text='去搶購')
SHUNFENGDIANZITAOPIAOXIANGQING = dict(text='')
LIJIGOUMAI = dict(text="立即購買")
WODELIPIN = dict(text="my-gift.9c48adc5")
KUAIGUOQI = dict(text="快過期")
XINLINGQU = dict(text="新領取")
JIFENHUANLING = dict(text="積分換領")
LIJIDUIHUAN = dict(text='立即兌換')
LIPINXIANGQING = dict(text='禮品詳情')
LIPINJIANJIE = dict(text="禮 品 簡 介")
YINGYESHIJIAN = dict(textStartsWith='營業時間')
QUEDINGDUIHUAN = dict(text="確定兌換")
SUOXUJIFEN = dict(textStartsWith='所需積分')
QUEDINGSHIYONG = dict(textStartsWith='確定使用')
QUXIAO = dict(text="取消")
QUEREN = dict(text="確認")
DUIHUANCHENGGONG = dict(text="兌換成功")
JIXUDUIHUAN = dict(text="繼續兌換")
KEYONG = dict(textStartsWith='可用')
JIAZAIGENGDUO = dict(text="加載更多")
CHANPIN_QUQIANGGOU = '//*[@text="不要下架要跑APP自动化的谢谢"]/../android.view.View[5]'
CHANPIN_1 = dict(text="不要下架要跑APP自动化的谢谢")
TONGYI = dict(text="同意")
GOUMAITONGYI = '//android.widget.CheckBox'
SHUNFENGCHUZHIKA = dict(text="")
QUERENFUKUAN = dict(text="確認付款")
ZHIFUJINE = dict(text="支付金額")
ZHIFUCHENGGONG = dict(text="支付成功")
WANCHENG = dict(text="完成")
LIJISHIYONG = dict(text="立即使用")
TEST = dict(text="TEST")
if __name__ == '__main__':
pass
@filename: test_membership_interests_2.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
import pytest
import allure
import random
import string
import re
import os
from uiautomator2 import Device
from uiautomator2 import Direction
from membership_interests_app_autotest.user_log import Log
from membership_interests_app_autotest.common_variable import xg, common_serial_number, xg_account, request_headers
from membership_interests_app_autotest.common_variable import pictures_path
from membership_interests_app_autotest.common_function import screenshot_decorator, my_element, my_assert, get_user_id
from membership_interests_app_autotest.common_function import kill_button, send_request, join_url
from membership_interests_app_autotest.common_mysql import fetch_sql
from membership_interests_app_autotest.page_membership_interests_2 import PageMembershipInterests2
print(xg_account, 'test_membership_interests_2.py')
def update_user_point(available_points: str, login_account: str):
"""
修改用户的积分
:param available_points:
:param login_account:
:return:
"""
add_point_url = '/zyooooxie/addPointOperate'
if int(available_points) <= 100:
user_id = get_user_id(login_account)
if user_id:
source = ''.join(random.sample(string.zy, 10))
data = {'userId': user_id, 'mobile': login_account, 'pointValue': 100}
send_request('post', url=join_url(add_point_url), json=data, headers=request_headers)
Log.info('addPoint-100')
return str(int(available_points) + 100)
else:
return available_points
# @pytest.mark.skip
@allure.feature('香港APP')
@pytest.mark.parametrize('before_after_xgtw_module', xg, indirect=True)
@pytest.mark.parametrize('device_xgtw', xg, indirect=True)
class TestMembershipInterests2(PageMembershipInterests2):
@staticmethod
def teardown_method():
Log.info('---------')
@pytest.mark.skip
@screenshot_decorator(common_serial_number)
@allure.description('积分规则')
@allure.title('香港会员2')
def test_2(self, device_xgtw: Device):
my_element(device_xgtw, self.HUIYUAN).click()
my_element(device_xgtw, self.JIFENGUIZE).click()
my_assert(device_xgtw, self.ZHUYI, 'exists', True, 'is_')
my_assert(device_xgtw, self.TEST, 'exists', True, 'is_') # 不存在的元素
@pytest.mark.smoke
@screenshot_decorator(common_serial_number)
@allure.description('积分换领-兑换礼品')
@allure.title('香港会员10')
def test_10(self, device_xgtw: Device):
my_element(device_xgtw, self.HUIYUAN).click()
my_assert(device_xgtw, self.HUIYUANDUXIANG, 'exists', True, 'is_')
with allure.step('可用积分'):
available_points = my_element(device_xgtw, self.JIFENZONGSHULIANG).get_text()
Log.info(available_points)
# 可用积分 有bug,所以每次都截个图
img_name = ''.join(['available_points', '.png'])
fn = os.path.join(pictures_path, img_name)
device_xgtw.screenshot(filename=fn)
allure.attach.file(source=fn, name=img_name, attachment_type=allure.attachment_type.PNG)
available_points = update_user_point(available_points=available_points, login_account=xg_account)
Log.info(available_points)
with allure.step('某商品-立即兑换'):
device_xgtw.swipe_ext(Direction.UP)
device_xgtw.swipe_ext(Direction.UP)
my_element(device_xgtw, self.LIJIDUIHUAN).click()
my_assert(device_xgtw, self.LIPINXIANGQING, 'exists', True, 'is_')
my_assert(device_xgtw, self.LIPINJIANJIE, 'exists', True, 'is_')
with allure.step('vConsole'):
my_element(device_xgtw, self.vConsole).drag_to(x=0.35, y=0.15, duration=0.5)
with allure.step('某商品详情-获取point'):
point0 = my_element(device_xgtw, self.SUOXUJIFEN).get_text()
re_str = r'\d+'
res0 = re.findall(re_str, point0)
Log.info(res0)
assert len(res0) == 1
ke_yong_points1 = my_element(device_xgtw, self.KEYONG).get_text()
ava1 = re.findall(re_str, ke_yong_points1)
Log.info(ava1)
assert len(ava1) == 1
assert ava1[0].startswith(available_points) is True
with allure.step('某商品兑换'):
my_element(device_xgtw, self.LIJIDUIHUAN).click()
kill_button(device_xgtw, self.YINGYESHIJIAN, wait_time=5)
kill_button(device_xgtw, self.QUEDINGDUIHUAN, wait_time=5)
my_assert(device_xgtw, self.QUXIAO, 'exists', True, 'is_')
point1 = my_element(device_xgtw, self.QUEDINGSHIYONG).get_text()
res1 = re.findall(re_str, point1)
Log.info(res1)
assert len(res1) == 1
assert res1[0] == res0[0]
with allure.step('某商品兑换-确认'):
my_element(device_xgtw, self.QUEREN).click()
my_assert(device_xgtw, self.DUIHUANCHENGGONG, 'exists', True, 'is_')
my_assert(device_xgtw, self.JIXUDUIHUAN, 'exists', True, 'is_')
device_xgtw.press('back')
with allure.step('某商品兑换后-断言'):
ke_yong_points2 = my_element(device_xgtw, self.KEYONG).get_text()
ava2 = re.findall(re_str, ke_yong_points2)
Log.info(ava2)
assert len(ava2) == 1
assert ava2[0] == str(int(available_points) - int(res1[0]))
@pytest.mark.smoke
@screenshot_decorator(common_serial_number)
@allure.description('购买超值福利-特定产品')
@allure.title('香港会员11')
def test_11(self, device_xgtw: Device):
user = get_user_id(xg_account)
with allure.step('特定产品-获取购买记录'):
sql = """
SELECT COUNT(order_code) FROM table_oo WHERE user_id = '{}' AND commodity_name = '不要下架要跑APP自动化的谢谢' ORDER BY order_time DESC;
""".format(user)
res = fetch_sql(sql, db_name='zyooooxie_db', fetch_mode='fetchone')
Log.info(res)
sql2 = """
SELECT COUNT(id) FROM table_oppr WHERE user_id = '{}' AND pay_status = '1' ORDER BY create_tm DESC;
""".format(user)
res2 = fetch_sql(sql2, db_name='zyooooxie_db', fetch_mode='fetchone')
Log.info(res2)
my_element(device_xgtw, self.HUIYUAN).click()
my_element(device_xgtw, self.WODELIPIN).drag_to(x=0.35, y=0.15, duration=0.5)
device_xgtw.swipe_ext(Direction.UP)
with allure.step('特定产品-购买、付款'):
my_element(device_xgtw, self.JIAZAIGENGDUO).click()
my_element(device_xgtw, self.CHANPIN_QUQIANGGOU).click()
my_assert(device_xgtw, self.CHANPIN_1, 'exists', True, 'is_')
my_assert(device_xgtw, self.TONGYI, 'exists', True, 'is_')
my_element(device_xgtw, self.GOUMAITONGYI).click()
my_element(device_xgtw, self.LIJIGOUMAI).click()
my_assert(device_xgtw, self.SHUNFENGCHUZHIKA, 'exists', True, 'is_')
# 確認付款 有时候不稳定
my_element(device_xgtw, self.QUERENFUKUAN).click()
kill_button(device_xgtw, self.QUERENFUKUAN, wait_time=2)
with allure.step('特定产品-输入支付密码'):
my_assert(device_xgtw, self.ZHIFUJINE, 'exists', True, 'is_')
# 支付密码1234
my_element(device_xgtw, dict(text="1")).click()
my_element(device_xgtw, dict(text="2")).click()
my_element(device_xgtw, dict(text="3")).click()
my_element(device_xgtw, dict(text="4")).click()
with allure.step('特定产品-支付完成'):
my_assert(device_xgtw, self.ZHIFUCHENGGONG, 'exists', True, 'is_')
my_element(device_xgtw, self.WANCHENG).click()
with allure.step('特定产品-购买后断言'):
sql3 = """
SELECT COUNT(order_code) FROM table_oo WHERE user_id = '{}' AND commodity_name = '不要下架要跑APP自动化的谢谢' ORDER BY order_time DESC;
""".format(user)
res3 = fetch_sql(sql3, db_name='zyooooxie_db', fetch_mode='fetchone')
Log.info(res3)
assert res3[0] == res[0] + 1
sql4 = """
SELECT COUNT(id) FROM table_oppr WHERE user_id = '{}' AND pay_status = '1' ORDER BY create_tm DESC;
""".format(user)
res4 = fetch_sql(sql4, db_name='zyooooxie_db', fetch_mode='fetchone')
Log.info(res4)
assert res4[0] == res2[0] + 1
if __name__ == '__main__':
pass
----------------------------------------------
@filename: page_membership_interests_3.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
class PageMembershipInterests3(object):
"""
台湾APP
"""
HUIYUAN = dict(text="會員")
LiJILINGQU_close = dict(text="U+e1ILO3mKM256VjE9oujfgGk5zsYyFvRKAAAAABJRU5ErkJggg==")
WODEHUIYUAN = dict(text="我的會員")
HUIYUANGUIZE = dict(text="會員規則")
@filename: test_membership_interests_3.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
import allure
import pytest
from uiautomator2 import Device
from membership_interests_app_autotest.user_log import Log
from membership_interests_app_autotest.common_variable import tw, common_serial_number, tw_account
from membership_interests_app_autotest.common_function import my_element, my_assert, screenshot_decorator, kill_button
from membership_interests_app_autotest.page_membership_interests_3 import PageMembershipInterests3
print(tw_account, 'test_membership_interests_3.py')
# @pytest.mark.skip
@allure.feature('台湾APP')
@pytest.mark.parametrize('before_after_xgtw_module', tw, indirect=True)
@pytest.mark.parametrize('device_xgtw', tw, indirect=True)
class TestMembershipInterests3(PageMembershipInterests3):
@staticmethod
def teardown_method():
Log.info('---------')
@pytest.mark.smoke
@screenshot_decorator(common_serial_number)
@allure.description('会员中心页面')
@allure.title('台湾会员1')
def test_1(self, device_xgtw: Device):
my_element(device_xgtw, self.HUIYUAN).click()
kill_button(device_xgtw, self.LiJILINGQU_close, wait_time=5)
my_assert(device_xgtw, self.WODEHUIYUAN, 'exists', True, 'is_')
my_assert(device_xgtw, self.HUIYUANGUIZE, 'exists', True, 'is_')
if __name__ == '__main__':
pass
pytest.main(['-s', '-v', '{}'.format(__file__)])
----------------------------------------------
@filename: page_membership_interests_4.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
import time
import random
import datetime
import jsonpath
from membership_interests_app_autotest.user_log import Log
from membership_interests_app_autotest.common_function import my_element, send_request, join_url, get_user_id
from membership_interests_app_autotest.common_mysql import fetch_sql
from membership_interests_app_autotest.common_variable import dl_account, request_headers
class PageMembershipInterests4(object):
QINGSHURUSHOUJIHAO = '//*[@resource-id="root"]//android.widget.EditText[1]'
HUOQUYANZHENGMA = dict(text="获取验证码")
QINGSHURUYANZHENGMA = '//*[@text="请输入发送至手机的验证码"]/../android.view.View[2]'
QINGSHURUYANZHENGMA2 = dict(text="请输入发送至手机的验证码")
TONGYIBENTIAOKUAN = dict(text="同意本条款,下次不再提醒")
DENGLU = dict(text="登录")
TANCHUANG = dict(text="close")
@staticmethod
def add_task_and_open(action_type: str = '浏览'):
url_add = '/task/add'
abc = datetime.datetime.now().strftime('%y%m%d%H%M%S')
task_id = "TASK{}{}".format(abc, random.randint(1000, 9999))
if action_type == '浏览':
add_dict = {"actionName": "浏览/浏览会员中心"}
else:
assert action_type == '点击'
add_dict = {"actionName": "点击"}
send_request('post', url=join_url(url_add), json=add_dict, headers=request_headers)
Log.info('任务:{} 已新建'.format(task_id))
return task_id
@staticmethod
def get_visit_url(task_id: str):
url_addTaskCodes = '/task/addTaskCodes'
task_code_list = list() # 暂不提供 task_code_list 生成逻辑
user_id = get_user_id(dl_account)
url_openTask = '/task/openTask'
open_dict = {'mobile': dl_account, 'userId': user_id,
'taskInfos': [{'taskCode': random.choice(task_code_list), 'callBackUrl': ''}]}
res = send_request('post', json=open_dict, headers=request_headers, url=join_url(url_openTask))
url = jsonpath.jsonpath(res, '$..jumpTo')
Log.info('openTask返回的url:{}'.format(url))
assert len(url) == 1
return url[0]
if __name__ == '__main__':
pass
@filename: test_membership_interests_4.py
"""
@blog: https://blog.csdn.net/zyooooxie
"""
import allure
import pytest
import uiautomator2 as u2
from uiautomator2 import Device
from membership_interests_app_autotest.common_variable import dl_account, common_serial_number
from membership_interests_app_autotest.page_membership_interests_4 import PageMembershipInterests4
from membership_interests_app_autotest.common_function import my_element, screenshot_decorator
from membership_interests_app_autotest.common_function import my_assert, kill_button
from membership_interests_app_autotest.user_log import Log
print(dl_account, 'test_membership_interests_4.py')
# @pytest.mark.skip
@allure.feature('大陆会员-任务相关')
class TestMembershipInterests4(PageMembershipInterests4):
def h5_login(self, account: str, device: Device):
login_url = 'https://zyooooxie/Login'
with allure.step('浏览器打开login地址'):
device.open_url(login_url)
with allure.step('输入手机号、获取验证码'):
my_element(device, self.QINGSHURUSHOUJIHAO).click()
device.send_keys(account, clear=True)
my_element(device, self.HUOQUYANZHENGMA).click()
with allure.step('输入验证码'):
my_element(device, self.QINGSHURUYANZHENGMA).set_text('123456')
with allure.step('登录'):
my_element(device, self.TONGYIBENTIAOKUAN).click()
my_element(device, self.DENGLU).click()
kill_button(device, self.TANCHUANG, wait_time=5)
my_assert(device, self.SHENGHUOTEQUAN, 'exists', True, 'is_')
@classmethod
def setup_class(cls):
print('setup_class')
cls.device = u2.connect(addr=common_serial_number)
cls.device.implicitly_wait(10)
TestMembershipInterests4().h5_login(dl_account, cls.device)
@classmethod
def teardown_class(cls):
print('teardown_class')
del cls.device
@staticmethod
def setup_method():
print(__class__.__name__)
@staticmethod
def teardown_method():
Log.info('---------')
@pytest.mark.smoke
@screenshot_decorator(common_serial_number)
@allure.description('用户领取任务、完成任务、断言')
@allure.title('用户领取页面浏览任务')
def test_1(self):
task_id = self.add_task_and_open()
url = self.get_visit_url(task_id=task_id)
self.device.open_url(url=url)
self.device.sleep(3) # 看下效果
# TODO 因为不是白名单,始终没法跑通
if __name__ == '__main__':
pass
执行结果
allure报告
日志文件、手机截图
本文链接:https://blog.csdn.net/zyooooxie/article/details/124176686
uiautomator2的这3篇博客,应该是真实分享时 代码‘马赛克’ 最少的几次。
此外,我这也用了 图像对比:有些用例是 某些H5页面 想做文案对比。我是不想一个一个字去对 + 大佬本就写了这些方法,我就‘拿来主义’ 优化下,搞了搞。 (非我原创 所以就没有做任何展示)
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie