python+uiautomator2+pytest自动化测试框架(一)

  • 一、框架目录结构
  • 1、目录结构
  • 1)、使用pip freeze
  • 2)、使用freeze生成的文件进行第三方库的安装
  • 二、运行和环境准备
  • 三、封装方法
  • 1、public下的func.py:通用方法的封装


首先感谢老大哦啦嘿嘿(我的主管)框架结构是他帮助重构的,后面我开始一步步的踩坑!

一、框架目录结构

opencv pytorch AI UI自动化测试工具 pytest ui自动化_pycharm

1、目录结构

case = 存在case 的目录
			data = 测试数据存在目录,数据化使用
			driver = 创建多个设备,设备驱动初始化目录
			lib = 存在依赖文件底层库的目录
			logs = 日志存放目录
			page = 页面对象存放目录
			public = 存放各种方法的目录
			report = 存放报告目录
			resource = 资源包
			test_run = 运行测试用例目录,以后集成web+ios+H5做变量使用
			conftest.py = 封装了一个全局调用的方法配合case使用,每次case执行完成后返回首页,便于执行后面的用例
			main.py = 启动文件
			run.bat = shell 启动命令
			requirements.txt = 所需要应用的库

注:requirements.txt 使用方法:

1)、使用pip freeze

pip freeze > requirements.txt
这个命令安装了环境中的所有第三方库,一般在虚拟环境中可以这样使用比较方便。
安装命令:
pip3 install freeze

2)、使用freeze生成的文件进行第三方库的安装

pip install -r requirements.txt(我是用的是pip3 安装)
没有报错的情况下就代表安装成功,如果报错就需要替换安装源,
pip install <包名> -i http://pypi.douban.com/simple
常见国内镜像源:
http://pypi.douban.com/simple/ 豆瓣
http://mirrors.aliyun.com/pypi/simple/ 阿里
http://pypi.hustunique.com/simple/ 华中理工大学
http://pypi.sdutlinux.org/simple/ 山东理工大学
http://pypi.mirrors.ustc.edu.cn/simple/ 中国科学技术大学

二、运行和环境准备

1、使用机型:虚拟机-网易mumu
注:我的电脑有时候使用adb 链接虚拟机不成,使用adb kill-server && adb server && adb shell 后再运行adb device
2、框架Python+uiautomator2+pytest
3、环境准备 python3.6,预装的工具在resource文件下

三、封装方法

1、public下的func.py:通用方法的封装

import re
from lib.loggers import JFMlogging
LOG = JFMlogging().getloger()
from drivers import android
import pysnooper

# @pysnooper.snoop()
class base():
    d = android.device_android()
    def link_test(self):
        '''
        判断设备是否连接成功
        :return:
        '''
        if self.d.info['naturalOrientation'] == True:
            print('设备连接正常!')
            # self.run_app()
        else:
            print('设备连接出现问题!请检查后重试!')

    def find_elements(self, element, timeout=5):
        '''
        查找元素是否存在当前页面
        :return:
        '''
        is_exited = False
        try:
            while timeout > 0:
                xml = self.d.dump_hierarchy()
                # print(self.d)
                if re.findall(element, xml):
                    is_exited = True
                    LOG.info("查询到{}".format(element))
                    break
                else:
                    timeout -= 1
        except Exception as e:
            LOG.info("{}查找失败!{}".format(element, e))
        finally:
            return is_exited

    def click_X(self, content):
        """点击xpath
        固定等待N秒
        点击对应元素"""
        try:
            self.d.xpath(content).wait(3)
            self.d.xpath(content).click(timeout=3)
            LOG.info("点击Xpath{}成功".format(content))
            return '成功'
        except Exception as e:
            LOG.info("{}点击Xpath失败!{}".format(content, e))
            return '点击失败'

    def click_R(self, content):
        """点击resourceId
        固定等待N秒
        点击对应元素"""
        try:
            self.d(resourceId=content).wait(3)
            self.d(resourceId=content).click(timeout=3)
            LOG.info("点击resourceId{}成功".format(content))
            return '成功'
        except Exception as e:
            LOG.info("{}点击resourceId失败!{}".format(content, e))
            return '点击失败'

    def click_T(self, content):
        """点击text
        固定等待N秒
        点击对应元素"""
        try:
            self.d(text=content).wait(3)
            self.d(text=content).click(timeout=3)
            LOG.info("点击text{}成功".format(content))
            return '成功'
        except Exception as e:
            LOG.info("{}点击text失败!{}".format(content, e))
            return '点击失败'

    def click_zb(self,x,y):
        """点击坐标x,y
           固定等待N秒
           点击对应元素"""
        try:
            self.d.click(x=x,y=y)
            LOG.info("点击坐标{}成功".format(x,y))
            return '成功'
        except Exception as e:
            LOG.info("{}坐标点击失败!{}".format(x,y, e))
            return '点击失败'

    def swipe_up_R(self,content):
        '''
        向上滑动到底
        :param content:参数
        :return:
        '''
        try:
            self.d(resourceId=content).swipe("up")
            LOG.info("{}滑动成功".format(content))
            return '滑动到底'
        except Exception as e:
            LOG.info("{}滑动失败!{}".format(content, e))
            return '滑动失败'

    def swipe_down_R(self,content):
        '''
        向下滑动到底
        :param content:参数
        :return:
        '''
        try:
            self.d(resourceId=content).swipe("down")
            LOG.info("{}滑动成功".format(content))
            return '滑动到底了'
        except Exception as e:
            LOG.info("{}滑动失败!{}".format(content, e))
            return '滑动失败'