• 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__))), 'reportimg')
            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截图

    
    
  • 相关阅读:
    node搭建文件服务器
    es6快速排序
    vue+koa+mysql简易demo
    linux常用命令
    su: Authentication failure 的解决方案
    安装gensim报错:Original error was: DLL load failed: 找不到指定的模块。 Command "python setup.py egg_info" failed with error code 1 in C:UsersxubingAppDataLocalTemppip-install-nta89iepgensim
    使用服务器上的Jupyter notebook。
    tf.nn.conv2d()需要搞清楚的几个变量。
    tf入门-池化函数 tf.nn.max_pool 的介绍
    tf入门-卷积步长strides参数的具体解释
  • 原文地址:https://www.cnblogs.com/changqing8023/p/10153371.html
Copyright © 2020-2023  润新知