修改了 BeautifulReport源码中的一些内容<附:BeautifulReport--适用于unittest自动化测试的可视化报告>;

1.生成截图时,原来的img文件夹必须在项目根目录下,做了调整;

2.生成的截图无法在html报告上展示,老是会报路径错误,检查发现源码中在做判断时少加了system()方法才导致错误的出现;

源码github截图

修改后截图

简单的登录功能实现,懂车帝app为例;

1.页面元素封装;

page_car.py
from common.basics import Crazy

class 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 readConfig class 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('')
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截图

												

BeautifulReport 实现app UI自动化测试的更多相关文章

  1. APP UI自动化测试思路总结

    python+appium自动化测试系列就要告一段落了,本篇博客咱们做个小结. 首先想要说明一下,APP自动化测试可能很多公司不用,但也是大部分自动化测试工程师.高级测试工程师岗位招聘信息上要求的,所 ...

  2. Appium App UI 自动化测试理论知识

    (一)App自动化测试背景 随着移动终端的普及,手机应用越来越多,也越来越重要.App的回归测试用例数量越来越多,全量回归也越来越消耗时间.另外移动端碎片化严重(碎片化:兼容性测试,手机品牌多样.An ...

  3. ios app UI自动化测试用到的命令

    ios测试的app测试包,真机设备需要开发者证书并且将测试机的udid加入到pp文件文件,configruation 要求为debug模式的ipa包, 1.苹果手机的UDID, a.通过 xcode- ...

  4. APP的UI自动化测试框架及平台化探索

    顾铮,10年+测试及测试开发相关经验,2014年加入京东,曾主导设计开发UI测试框架,参与CI测试平台建设,现负责iOS侧的工具,框架建设.在UI自动化,性能测试,单元测试方面有较深入研究,在App, ...

  5. UI自动化测试:App的WebView页面中,当搜索栏无搜索按钮时处理方法

    一.遇到的问题 在做移动端的UI自动化测试时,经常会遇到上图所示的搜索框,这里有个麻烦就是搜索框没有"搜索"按钮,UI自动化测试时不能确认搜索. 要解决这个问题,我们可以通过 dr ...

  6. 从0到1搭建移动App功能自动化测试平台(2):操作iOS应用的控件

    转自:http://debugtalk.com/post/build-app-automated-test-platform-from-0-to-1-Appium-interrogate-iOS-UI ...

  7. UI自动化测试的那些事

    互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自 ...

  8. 从0到1搭建移动App功能自动化测试平台(0):背景介绍和平台规划

    本文作者: 伯乐在线 - debugtalk .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 转载地址:http://blog.jobbole.com/101221/ 背景 最近新加入DJI的 ...

  9. <自动化测试方案_7>第七章、PC端UI自动化测试

    第七章.PC端UI自动化测试 UI自动化测试又分为:Web自动化测试,App自动化测试.微信小程序.微信公众号UI层的自动化测试工具非常多,比较主流的是UFT(QTP),Robot Framework ...

随机推荐

  1. centos7 yum安装LAMP

    说明:我安装后的版本号分别是: apache : Apache/2.4.6 (CentOS)mysql:5.6.42php:5.6.39 一.配置网络. 我们首先需要让我们的虚拟机能够连接上外网,这样 ...

  2. css 浮动布局,清除浮动

    浮动的特性: (1)浮动元素有左浮动(float:left)和右浮动(float:right)两种 (2)浮动的元素会向左或向右浮动,碰到父元素边界.其他元素才停下来 (3)相邻浮动的块元素可以并在一 ...

  3. target和currentTarget

    event.target返回触发事件的元素 event.currentTarget返回绑定事件的元素   1 <ul id="ul">ul 2 <li>li ...

  4. Mac_IntelliJ IDEA For Mac 快捷键

    Mac键盘符号和修饰键说明 ⌘ Command ⇧ Shift ⌥ Option ⌃ Control ↩︎ Return/Enter ⌫ Delete ⌦ 向前删除键(Fn+Delete) ↑ 上箭头 ...

  5. 马昕璐 201771010118《面向对象程序设计(java)》第六周学习总结

    第一部分:理论知识学习部分 1.继承 继承:用已有类来构建新类的一种机制.当定义了一个新类继承了一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的方法和域以适应新的情况. 继承是Java ...

  6. vue_eHungry 饿了么

    eHungry 仿饿了么 git 操作 git checkout -b dev        // 创建新分支 dev git push origin dev        // 代码推送到 dev ...

  7. 全排列筛选(java)

    蓝桥杯-全排列筛选(java) 蓝桥杯每年必考全排列筛选,一般为填空题: 可以使用for循环暴力破解,但是代码相对较长,也比较乱,不建议使用: 这里使用递归来解决,代码量相对较少,也很好理解: 如下为 ...

  8. MySQL自动备份shell脚本

    在数据库的日常维护工作中,除了保证业务的正常运行以外,就是要对数据库进行备份,以免造成数据库的丢失,从而给企业带来重大经济损失.通常备份可以按照备份时数据库状态分为热备和冷备,按照备份数据库文件的大小 ...

  9. 一篇搞懂python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)

           关于文件操作的几种常用方式,网上已有很多解说,内容很丰富,但也因此有些杂乱复杂.今天,我就以我个人的学习经验写一篇详细又易懂的总结文章,希望大家看完之后会有所收获. 一.核心功能 ‘r’ ...

  10. LeetCode 50 - Pow(x, n) - [快速幂]

    实现 pow(x, n) ,即计算 x 的 n 次幂函数. 示例 1: 输入: 2.00000, 10输出: 1024.00000 示例 2: 输入: 2.10000, 3输出: 9.26100 示例 ...