BeautifulReport 实现app UI自动化测试

Posted backlight

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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截图

 


以上是关于BeautifulReport 实现app UI自动化测试的主要内容,如果未能解决你的问题,请参考以下文章

selenium+python+unittest多线程生成报告(BeautifulReport)

BeautifulReport 遇到的问题 template

十python BeautifulReport 可视化报告

unittest使用BeautifulReport库生成测试报告

python之单元测试——BeautifulReport

BeautifulReport模块产生的测试报告