Pytest+Allure+Uiautomator2框架实现APP自动化测试

一  总体框架

代码框架如下:

    

    ------ run.py  主函数,用于运行所有测试用例

    ------ Commom,公共函数

      ------ logger.py, 定义日志

      ------ logins.py, 提取登录功能

      ------ Operator.py, 封装操作,如点击、输入等

    ------ Page ,各业务流使用的元素

    ------ Report, 测试报告

    ------ TestCase, 测试用例

    ------ TestData, 测试数据

二  详解

    1  Operator        
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     Operator.py
   Author :        曾良均
   QQ:             277099728
   Date:          12/11/2023 2:32 PM   
   Description :
-------------------------------------------------
   Change Activity:
                   
-------------------------------------------------
"""
__author__ = 'ljzeng'

import re
import uiautomator2 as u2


def device():
    driver = u2.connect()
    driver.app_start("com.xxx.xxx")
    return driver


class Operator:
    driver = None

    def find_element(self, location, **kwargs):
        if str(location).startswith("com"):  # 若开头是com则使用ID定位
            return self.driver(resourceId=location)
        elif str(location).startswith("android"):
            if kwargs:
                return self.driver(className=location, index=kwargs.values())  # classname+index组合定位
            else:
                return self.driver(className=location)
        elif re.findall("//", str(location)):  # 若//开头则使用正则表达式匹配后用xpath定位
            return self.driver.xpath(location)
        else:  # 若以上两种情况都不是,则使用描述定位
            try:
                if kwargs:
                    # text+index组合定位,Fleet App上存在以图片或字体来表示功能按钮,如WO附件的图库、拍照、录像功能
                    return self.driver(text=location, index=kwargs.values())
                else:
                    return self.driver(text=location)
            except Exception:
                return self.driver(description=location)

    def click(self, location, **kwargs):
        if kwargs:
            self.find_element(location, index=kwargs.values()).click()
        else:
            self.find_element(location).click()

    def clear(self, location):
        self.find_element(location).clear_text()

    def input(self, location, txt):
        # self.clear(location)
        self.find_element(location).set_text(txt)
2  Page页面
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     assetPage.py
   Author :        曾良均
   QQ:             277099728
   Date:          12/11/2023 5:34 PM   
   Description :
-------------------------------------------------
   Change Activity:
                   
-------------------------------------------------
"""
__author__ = 'ljzeng'

from Common.Operator import *


class assetPage(Operator):
    asset_menu = "Manage Assets"

    add_btn = 'Add'  # Add 按钮
    search_inbox = '//android.widget.RelativeLayout/android.view.ViewGroup[1]/android.view.ViewGroup[2]/android.view.ViewGroup[1]/android.view.ViewGroup[2]/android.view.ViewGroup[1]/android.view.ViewGroup[1]/android.view.ViewGroup[1]/android.view.ViewGroup[1]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]/android.view.ViewGroup[1]'

    # Add Page
    save_btn = 'Save'

3 测试用例
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     TestAssets.py
   Author :        曾良均
   QQ:             277099728
   Date:          12/11/2023 5:30 PM   
   Description :
-------------------------------------------------
   Change Activity:
                   
-------------------------------------------------
"""
__author__ = 'ljzeng'

import time

import pytest
from Common.logger import Log
from Common.logins import logins
import uiautomator2 as u2
from Page.assetPage import assetPage

log = Log("TestAssets")


@pytest.fixture()
def begin():
    driver = u2.connect()
    driver.app_start("com.xxx.xxx")
    driver.implicitly_wait(10)
    lg = logins()
    lg.login(driver, username='admin@iicon004.com', pwd='Win.12345')
    lg.asset = assetPage()

    yield lg
    driver.app_stop("com.xxx.xxx")
    driver.app_clear("com.xxx.xxx")


@pytest.mark.usefixtures("begin")
class TestAssets:
    def add_asset(self, begin):
        time.sleep(3)
        begin.click(begin.asset.asset_menu)
        time.sleep(2)
        txt = begin.find_element(begin.asset.add_btn).get_text()
        return txt

    def test_asset(self, begin):
        res = self.add_asset(begin)
        assert res == 'Add'


if __name__ == '__main__':
    pytest.main(['-vs', 'TestAssets.py'])  # 主函数模式
4 日志封装
# -*- coding:utf8 -*-
import logging
import os
from datetime import datetime


class Log:
    def __init__(self, log_name=None):
        # 指定log保存位置
        base_path = os.path.dirname(os.path.abspath(__file__))
        fpath = os.path.abspath(os.path.join(base_path, '..\\'))
        self.log_path = os.path.join(fpath, "Logs")

        # 文件的命名
        if log_name is None:
            self.logname = os.path.join(self.log_path, '%s.log' % datetime.now().strftime('%Y_%m_%d_%H_%M_%S'))
        else:
            self.logname = os.path.join(self.log_path,
                                        '%s_%s.log' % (log_name, datetime.now().strftime('%Y_%m_%d_%H_%M_%S')))

        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        # 日志格式
        # self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s[line:%(lineno)d] - '
        #                                    'fuc:%(funcName)s- %(levelname)s: %(message)s')
        self.formatter = logging.Formatter('[%(asctime)s] - %(levelname)s: %(message)s')

    def __console(self, level, message):
        # 创建一个FileHandler,用于写到本地
        fh = logging.FileHandler(self.logname, 'a',  encoding='utf-8')  # 追加模式
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(self.formatter)
        self.logger.addHandler(fh)

        # 创建一个StreamHandler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(self.formatter)
        self.logger.addHandler(ch)

        if level == 'info':
            self.logger.info(message)
        elif level == 'debug':
            self.logger.debug(message)
        elif level == 'warning':
            self.logger.warning(message)
        elif level == 'error':
            self.logger.error(message)
        # 这两行代码是为了避免输出重复问题
        self.logger.removeHandler(ch)
        self.logger.removeHandler(fh)
        # 关闭打开的文件
        fh.close()

    def debug(self, message):
        self.__console('debug', message)

    def info(self, message):
        self.__console('info', message)

    def warning(self, message):
        self.__console('warning', message)

    def error(self, message):
        self.__console('error', message)


if __name__ == "__main__":
    log = Log()
    log.info("---测试开始---")
    log.info("--------------")
    log.warning("---测试结束---")

5 主函数
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     run.py
   Author :        曾良均
   QQ:             277099728
   Date:          12/11/2023 2:30 PM   
   Description :
-------------------------------------------------
   Change Activity:
                   
-------------------------------------------------
"""
__author__ = 'ljzeng'
import pytest
import os


if __name__ == '__main__':
    pytest.main(['-s', '-q', '--clean-alluredir', '--alluredir=allure-results'])
    os.system(r"copy environment.properties allure-results\\")
    os.system(r"allure generate -c -o Report\allure-report")

三   运行及结果查看

    运行主函数后,在对应目录运行命令:    

allure open .\allure-report\

  即在浏览器打开测试报告:

四   说明

    1 Pytest配置:pytest.ini        
[pytest]
addopts=-vs                 
testpaths=./TestCase
python_files=Test*.py
python_classes=Test
python_functions=test
markers=
    smoke:
    uermanage:
  2 报告的环境变量: environment.properties
ProductName = 你的项目名称
ProductVersion = 被测对象版本号
TestFramework = Pytest+Allure

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PytestAllure是两个非常流行的测试框架,可以用于搭建接口自动化测试框架Pytest是一个功能强大且易于使用的Python测试框架。它支持使用简单的语法编写测试用例,并提供丰富的断言和插件机制。Pytest可以与其他Python库很好地集成,方便编写和管理测试用例。 Allure是一个开源的测试报告框架,它能够生成美观且易于理解的测试报告。Allure提供了丰富的报告展示功能,包括测试用例的执行结果、日志、截图等信息。同时,Allure还支持生成历史报告、趋势分析和统计等功能,方便团队进行测试结果的分析和优化。 结合PytestAllure,可以搭建一个完整的接口自动化测试框架。一般来说,你需要按照以下步骤进行配置和编写测试用例: 1. 安装PytestAllure:使用pip命令安装PytestAllurePython库。 2. 编写测试用例:使用Pytest的语法编写接口自动化测试用例,并使用合适的断言进行结果验证。 3. 配置Allure报告:在项目中配置Allure报告生成的相关参数,如报告路径、报告名称等。 4. 运行测试用例:使用Pytest命令运行编写的测试用例,并生成Allure测试报告。 5. 查看测试报告:打开生成的Allure测试报告,查看测试结果、日志和截图等信息。 这样,你就可以使用PytestAllure搭建一个简单而功能强大的接口自动化测试框架了。当然,根据实际需求,你还可以结合其他工具和库进行扩展和定制化开发。希望对你有帮助!如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zljun8210

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值