BeautifulReport 实现app UI自动化测试

修改了 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(‘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截图



原文地址:https://www.cnblogs.com/changqing8023/p/10153371.html

时间: 2024-10-09 21:32:31

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

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

顾铮,10年+测试及测试开发相关经验,2014年加入京东,曾主导设计开发UI测试框架,参与CI测试平台建设,现负责iOS侧的工具,框架建设.在UI自动化,性能测试,单元测试方面有较深入研究,在App,web端等有较丰富的测试开发和设计经验. >>>> 写在前面 关于UI测试的文章,多数是通过架构的演进,或是重构,或是推翻重做来讲述的.今天我想讲述我的"一步到位"的测试框架设计.当然,这个"一步到位"是加引号的,并不是说没有持续的优化或改进,而

Mac下的UI自动化测试 (上)

在我看来,实现UI自动化测试的过程一向都是令人快乐的事情,而维护它们就是跟噩梦一样了,尤其是对每次CI产生的build进行BVT测试,由于开发不会告诉你任何UI的变化,那么你拿到的测试结果就势必会一片红了.但是对于界面相对稳定的项目,有大量回归测试需要进行的项目,实现UI自动化的投资回报率还是很高的. 最近我实现了公司一个产品在Mac OSX上的UI自动化测试,下面就把具体的细节写出来. 首先,选用的是由 MIT 研究团队发布的图形化编程技术 Sikuli,它以图像检索为基础,提供了一套基于 J

Android Espresso(UI自动化测试)的搭建

Espresso是Google官方提供的Android UI自动化测试的框架. 为什么叫Espresso(浓咖啡),好像是想让Android码农们轻松的写完自动化用例后能享受着咖啡,看着自动化测试"飞". 这是Espresso官方的地址.另外,也推荐大家看这个YouTube上关于Espresso环境搭建的短视频. Espresso环境搭建 下面将基于Android Studio,介绍如何搭建Espresso. 1. 在Android Studio中新建一个Project; 2. 修改P

[转]Android UI 自动化测试

介绍 Android测试支持库包含UI自动化模块,它可以对Android应用进行自动黑盒测试.在API Level 18中引入了自动化模块,它允许开发者在组成应用UI的控件上模仿用户行为. 在这个教程中,我将展示如何使用此模块来创建和执行一个基本的UI测试,选择默认的计算器模块进行测试. 先决条件 在使用前,需要具备以下条件: 最新版本的Android Studio 运行Android 4.3或者更高版本的设备或者虚拟器 理解JUnit 1. 安装依赖库 工程中使用UI自动化模块,需要编辑你的工

UI自动化测试的那些事

互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自动化测试逐渐流行起来.自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程.自动化测试的优点很多,简单罗列几条:避免重复工作.提高测试效率.保证每次测试地一致性和可重复性.更好的利用资源(周未/晚上的资源空闲时段).节省人力资源.增加软件信任度.缩短软件开发测试周期让产品更快投放市场.提高软件

【腾讯TMQ】解放程序猿(媛)的双手—iOS UI自动化测试

解放程序猿(媛)的双手-iOS UI自动化测试 前言 随着移动互联网时代的蓬勃发展,移动终端的自动化测试也在业界日益活跃,总体来看在Android平台上的自动化工具和实践比较多,但是说到iOS平台无论从自动化工具的数量还是质量上就陡降了.究其原因,无外乎是iOS系统的封闭性,加上相对Android用户的数量少,导致对这个平台系统的自动化进展缓慢,据笔者了解到的情况,很多iOS平台的测试人员还处于纯手工测试模式,自动化程度和Android平台无法相论,更别提和PC端相比了. 然而越是困难的事,越是

软件测试培训 UI 自动化测试详解

软件测试培训小编有好久都没有跟新软件测试,从今天开始,小编会逐渐把这部分知识给大家补上!今天这篇文章给大家介绍的是: UI 自动化测试 互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自动化测试逐渐流行起来.自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程. 自动化测试的优点很多,简单罗列几条:避免重复工作.提高测试效率.保证每次测试地一

Android测试(六):Android UI自动化测试

Android测试(六):Android UI自动化测试 发布时间 2017年12月20日 虫师 原文:https://developer.android.com/training/testing/ui-testing/index.html 用户界面(UI)测试可以确保你的应用程序满足其功能要求,并达到用户最可能成功采用的高质量标准. UI测试的一种方法是简单地让人类测试人员在目标应用程序上执行一组用户操作,并验证其行为是否正确. 但是,这种手动方法可能耗时.乏味.且容易出错.更有效的方法是编写

Selenide 阶段性总结介绍(UI自动化测试工具)

今天给大家介绍一个比较新的UI自动化测试工具-- Selenide.确实是比较新的,国内应该还没有多少人用它.在百度和google上你只能搜到一个中文帖子简单介绍了一下.如果你想用这个工具,不可避免的你要去阅读英文文档了.不过这年头写代码的有几个看不懂英文的.所以这都不是问题. 简单介绍 Selenide的团队自诩它是一个测试工具而不是一个测试框架.因为它只是webdriver的一个封装,只是他们封装了更好用的API,更稳定的控件搜索机制,更好的异常处理机制等等.底层的实现还是webdriver