人生处万类,知识最为贤。这篇文章主要讲述BeautifulReport 实现app UI自动化测试相关的知识,希望能为你提供帮助。
修改了 BeautifulReport源码中的一些内容<
附:BeautifulReport--适用于unittest自动化测试的可视化报告>
;
1.生成截图时,原来的img文件夹必须在项目根目录下,做了调整;
文章图片
文章图片
2.生成的截图无法在html报告上展示,老是会报路径错误,检查发现源码中在做判断时少加了system()方法才导致错误的出现;
【BeautifulReport 实现app UI自动化测试】
源码github截图
文章图片
修改后截图
文章图片
简单的登录功能实现,懂车帝app为例;
1.页面元素封装;
page_car.py
from common.basics import Crazyclass CarLoginPage(Crazy): """元素定位"""# 跳过广告 skip_loc = (\'id\', \'com.ss.android.auto:id/c8r\')def click_skip(self): self.click(self.skip_loc)tag_loc = ("id", "com.ss.android.auto:id/bqp")# 首页文本 def text_home(self): return self.get_texts(self.tag_loc, 0)# 是否未 登录 def text_landed(self): return self.get_texts(self.tag_loc, 3)# 进入 未登录(我的)页面 def click_landed(self): self.clicks(self.tag_loc, 3)# # 判断是否进入未登录(我的)页设置编辑资料 common_loc = (\'id\', \'com.ss.android.auto:id/dd\')def text_common(self): return self.get_text(self.common_loc)# 点击手机图标 phone_loc = (\'id\', \'com.ss.android.auto:id/brg\')def click_phone(self): self.click(self.phone_loc)# 判断是否进入手机登录页面 phone_login_loc = (\'id\', \'com.ss.android.auto:id/jv\')def text_phone_login(self): return self.get_text(self.phone_login_loc)# 输入手机号 _phone_loc = (\'id\', \'com.ss.android.auto:id/jy\')def input_phone(self, phone): self.send_keys(self._phone_loc, phone)# 点击获取验证码 verification_code_loc = (\'id\', \'com.ss.android.auto:id/jz\')def click_verification_code(self): self.click(self.verification_code_loc)# 输入验证码 input_verification_code_loc = (\'id\', \'com.ss.android.auto:id/k3\')def input_verification(self, code): self.send_keys(self.input_verification_code_loc, code)# 点击 进入app 按钮 into_btn_loc = (\'id\', \'com.ss.android.auto:id/k7\')def click_into_btn(self): self.click(self.into_btn_loc)# QQ登录 qq_loc = (\'id\', \'com.ss.android.auto:id/brh\')def click_qq(self): self.click(self.qq_loc)# 授权按钮 # grant_btn_loc = (\'id\', \'com.tencent.mobileqq:id/name\') [36,1418][1044,1538] # grant_btn_loc = [(36, 1301), (1044, 1421)] grant_btn_loc = [(36, 1418), (1044, 1538)]def click_grant_btn(self): self.click_coordinate(self.grant_btn_loc)# 判断登录成功 personal_center_loc = (\'id\', \'com.ss.android.auto:id/br3\')def text_personal_center(self): return self.get_text(self.personal_center_loc)# 微信登录 wechat_loc = (\'id\', \'com.ss.android.auto:id/bri\')def click_wechat(self): self.click(self.wechat_loc)# 确认登录 [42,1176][1038,1320] com.tencent.mm:id/ch6[39,1079][1041,1211] [42,1176][1038,1320] confirm_wechat_loc = [(42, 1176), (1038, 1320)]def click_confirm_wechat(self): self.click_coordinate(self.confirm_wechat_loc)# 退出操作 set_up_loc = (\'id\', \'com.ss.android.auto:id/bvb\')def click_set_up(self): self.click(self.set_up_loc)# 判断进入设置页 text_common# 退出按钮 logout_loc = (\'id\', \'com.ss.android.auto:id/c7o\')def click_logout(self): self.click(self.logout_loc)# 是否存在退出按钮 def element_logout(self): return self.find_element(self.logout_loc)# 退出确认 logout_confirm_loc = (\'id\', \'com.ss.android.auto:id/i3\')def text_logout_confirm(self): return self.get_text(self.logout_confirm_loc)# 确认退出 confirm_logout_loc = (\'id\', \'com.ss.android.auto:id/c9_\')def click_confirm_logout(self): self.click(self.confirm_logout_loc)# 修改资料 update_user_loc = (\'id\', \'com.ss.android.auto:id/br5\')def click_update_user(self): self.click(self.update_user_loc)# 用户名 user_name_loc = (\'id\', \'com.ss.android.auto:id/j_\')def click_user_name(self): self.click(self.user_name_loc)# 请输入用户名 title enter_user_loc = (\'id\', \'com.ss.android.auto:id/ali\')def text_enter_user(self): return self.get_text(self.enter_user_loc)# 修改用户名 input_user_loc = (\'id\', \'com.ss.android.auto:id/alj\')def input_user(self, name): self.send_keys(self.input_user_loc, name)# 确定按钮 enter_btn_loc = (\'id\', \'com.ss.android.auto:id/alm\')def click_enter_btn(self): self.click(self.enter_btn_loc)# 获取用户名称 get_user_name_loc = (\'id\', \'com.ss.android.auto:id/jc\')def text_get_user_name(self): return self.get_text(self.get_user_name_loc)
basics.py 是用显示等待封装的一些常用方法< 附:基于显示等待封装的一些常用方法> ; 在做授权操作时,需要使用坐标定位的方法实现点击操作; 剩下的就是页面主要元素的函数;
2.测试用例;
test_car.py
import unittest import time from BeautifulReport import BeautifulReport from page.page_car import CarLoginPage from common.logger import Log from common.basics import open_app from common import readConfigclass TestCar(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver = open_app() cls.log = Log() cls.car = CarLoginPage(cls.driver) # cls.img_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), \'report\\img\') cls.img_path = readConfig.img_path# 必须是这个路径@classmethod def tearDownClass(cls): cls.driver.close_app()def save_img(self, img_name): self.driver.get_screenshot_as_file(\'{}/{}.png\'.format(self.img_path, img_name))@BeautifulReport.add_test_img(\'test_1app\') def test_1app(self): """打开app测试用例""" car = self.car # car.click_skip()# 跳过广告 self.assertEqual(\'首页\', car.text_home(), \'进入app出错!\') self.log.info(\'进入app成功!\')@BeautifulReport.add_test_img(\'QQ登录\') def test_2qq(self): """QQ登录测试用例""" car = self.car if car.text_landed() == \'我的\': car.click_landed() self.sign_out() if car.text_landed() == \'未登录\': self.log.info(\'用户未登录,准备 QQ 用户登录中...\') car.click_landed() self.assertEqual(car.text_common(), \'常用功能\', \'未进入 未登录 页面!\') self.log.info(\'选择 QQ 用户登录.\') car.click_qq() time.sleep(2) car.click_grant_btn() time.sleep(2) self.assertEqual(car.text_personal_center(), \'个人主页\', \'QQ 用户登录失败!\') self.log.info(\'QQ 用户登录成功!\') self.save_img(\'QQ登录\')@BeautifulReport.add_test_img(\'微信登录\') def test_2wechat(self): """微信登录测试用例""" car = self.car if car.text_landed() == \'我的\': car.click_landed() self.sign_out() if car.text_landed() == \'未登录\': self.log.info(\'用户未登录,准备 微信 用户登录中...\') car.click_landed() self.assertEqual(car.text_common(), \'常用功能\', \'未进入 未登录< 我的> 页面!\') self.log.info(\'选择 微信 用户登录.\') car.click_wechat() time.sleep(2) if car.text_personal_center() == \'个人主页\': self.log.info(\'微信 用户登录成功!\') else: car.click_confirm_wechat() time.sleep(2) self.assertEqual(car.text_personal_center(), \'个人主页\', \'微信 用户登录失败!\') self.log.info(\'微信 用户登录成功1!\') self.save_img(\'微信登录\')@BeautifulReport.add_test_img(\'编辑资料\') def test_4update_user_info(self): """编辑用户资料""" car = self.car if car.text_landed() == \'未登录\': self.log.warning(\'未检测到用户登录,不能进行编辑资料操作!\') elif car.text_landed() == \'我的\': self.log.info(\'用户已登录,准备进行 编辑资料 操作.\') car.click_landed() car.click_update_user() self.assertEqual(car.text_common(), \'编辑资料\', \'出现错误,没有进入 编辑资料 页面!\') start_user = car.text_get_user_name() car.click_user_name() car.input_user(\'111\') car.click_enter_btn() end_user = car.text_get_user_name() self.save_img(\'编辑资料\') time.sleep(2) if start_user == end_user: self.log.info(\'用户名称未做修改.\') else: self.log.info(\'修改用户名称成功!修改后的名称:{}\'.format(end_user))# def test_3phone(self): #"""手机登录""" #car = self.car #if car.text_landed() == \'我的\': #car.click_landed() #self.sign_out() #if car.text_landed() == \'未登录\': #self.log.info(\'用户未登录,准备 手机 用户登录中...\') #car.click_landed() #self.assertEqual(car.text_common(), \'常用功能\', \'未进入 未登录< 我的> 页面!\') #self.log.info(\'选择 手机 用户登录.\') #car.click_phone() #self.assertEqual(car.text_phone_login(), \'手机快捷登录\', \'进入 手机快捷登录 页面失败!\') #car.input_phone(\'xxxxxxxxxxx\') #time.sleep(1) #car.click_verification_code() #time.sleep(2) #car.input_verification(\'5556\') #car.click_into_btn() #self.assertEqual(car.text_personal_center(), \'个人主页\', \'手机 用户登录失败!\') #self.log.info(\'手机 用户登录成功!\')@BeautifulReport.add_test_img(\'退出登录\') def sign_out(self): """用户退出""" car = self.car if car.text_common() == \'常用功能\': self.assertEqual(car.text_personal_center(), \'个人主页\', \'没有用户登录,无法退出!\') self.log.info(\'正在执行用户退出登录操作.\') car.click_set_up() self.assertEqual(car.text_common(), \'设置\', \'进入设置页面失败!\') self.log.info(\'进入设置页成功!\') car.click_logout() self.assertEqual(car.text_logout_confirm(), \'退出确认\', \'出现错误,没有发现退出确认弹框!\') car.click_confirm_logout() if not car.element_logout(): self.log.info(\'退出登录成功!\') self.save_img(\'退出登录\') car.back() else: self.log.info(\'当前不在 我的 页面,无法进行退出登录操作!\')if __name__ == \'__main__\': unittest.main()
CarLoginPage,元素类; Log方法,打印日志< 附:python logging模块 输出日志和过期清理> ; open_app方法,连接appium,启动被测app; readConfig方法,配置文件;
手机登录的就比较蛋疼了,试了根据adb logcat获取手机日志,提取验证码没有成功...
生成的截图和html报告:
1.每条用例都会生成一张截图,错误截图另算;
文章图片
2.html报告;
文章图片
错误case截图
文章图片
正常case截图
文章图片
推荐阅读
- nohup 命令(设置后台进程)( appending output to ‘nohup.out’ 问题)
- Android 子线程更新UI 异常
- 一起学Android之Intent
- 使用Android服务,实现报警管理器和广播接收器
- android文件写入和读取
- Android Wifi 主动扫描 被动扫描
- 求数组中最小的数值(结合apply() call())
- Android 扫描枪开发
- 跨平台移动APP开发进阶 三 hbuilder+mui mobile app 开发心酸路