4.UI自动化测试框架搭建-文件结构

2022-03-29 16:38:14 浏览数 (1)

项目结构

代码语言:javascript复制
├── data                       # 存放元素定位yaml文件
├── src                        # 源代码
│   ├── cases                  # 测试用例
│   ├── pages                  # 元素业务操作类
│   ├── tools                  # 常用工具
│   └── utils                  # 封装的类
├── .gitignore                 # 上传git时候忽略的文件
├── Jenkinsfile                # jenkins运行流程
├── README.md                  # 项目说明
└── requirements.txt           # python包管理

根据上述方式创建好文件之后,把我们之前写的元素操作放到utils文件夹中去

yaml文件放到data文件夹中

另外UI测试的时候需要打开浏览器,把不同操作系统对应的driver放到tools文件夹中

https://github.com/allure-framework/allure2/releases

后面需要在使用到allure来生成报告,下载一份allure.zip解压后将它也放到tools文件夹中

摆放之后的文件夹如下:

常量文件

随着项目变大,里面的文件也越来越多,所以需要一个变量快速的拿到我们想要的路径

utils文件夹中新增一个constant.py文件

首先拿到当前项目根节点的绝对路径

使用os.path.abspath(__file__)拿到当前文件夹的绝对路径

使用os.path.dirname(path)拿到path的上一层路径

使用三次就可以拿到根路径地址了:当前文件utilssrcuitest

代码语言:javascript复制
BASE_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

接下来就是根据根路径使用os.path.join()方法进行路径拼接了

代码语言:javascript复制
import os

BASE_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
BASE_DATA_PATH = os.path.join(BASE_PATH, 'data')
SRC_PATH = os.path.join(BASE_PATH, 'src')
TOOL_PATH = os.path.join(SRC_PATH, 'tools')
ALLURE_TOOL_PATH = os.path.join(TOOL_PATH, 'allure-2.14.0/bin')

在测试过程中,需要有一些文件夹存放一些临时的文件

这些文件夹可以在运行的过程中判断是否存在,如果不存在则创建

代码语言:javascript复制
LOG_PATH = os.path.join(BASE_PATH, 'log')
REPORT_PATH = os.path.join(BASE_PATH, 'report')
TEST_PIC = os.path.join(REPORT_PATH, 'test_pic')
for i in [LOG_PATH, REPORT_PATH, TEST_PIC]:
    if not os.path.exists(i):
        os.mkdir(i)

现在我们就可以通过constant.py文件拿到项目中的路径了

打开浏览器

到这里我们就能使用绝对路径拿到driver文件去打开浏览器了

设置desired_capabilities

desired_capabilities可以设置的方式有三种

  • none: 当html下载完成之后,不等待解析完成,selenium会直接返回
  • eager: 要等待整个dom树加载完成,即DOMContentLoaded这个事件完成,仅对html的内容进行下载解析
  • normal: 即正常情况下,selenium会等待整个界面加载完成(指对html和子资源的下载与解析,如JS文件,图片等,不包括ajax)

在进行UI自动化测试的时候经常会遇到一个奇怪的问题,也就是人工去操作没有问题,但是使用脚本操作的时候却提示没找到元素,或者脚本迟迟不进行下一步操作

这可能是因为某几个资源没有加载完成导致的。这时候我们可以将desired_capabilities设置为eager

只要DOM加载完毕,元素基本上就可以找到和操作了

代码语言:javascript复制
from selenium.webdriver import DesiredCapabilities

desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "eager"
webdriver.Chrome(desired_capabilities=desired_capabilities)

确定当前操作系统

代码语言:javascript复制
platform.system()
  • Windows
  • Linux
  • Darwin
代码语言:javascript复制
if platform.system() == "Windows":
    driver_path = f'{TOOL_PATH}/driver/win/chromedriver'
elif platform.system() == "Linux":
    driver_path = f'{TOOL_PATH}/driver/linux/chromedriver'
    os.system(f"chmod -R 777 {driver_path}")
else:
    driver_path = f'{TOOL_PATH}/driver/mac/chromedriver'
    os.system(f"chmod -R 777 {driver_path}")

对没有图形化界面的Linux系统,需要使用无头浏览器运行

代码语言:javascript复制
chrome_option = Options()
chrome_option.add_argument('--headless')
chrome_option.add_argument('--no-sandbox')
chrome_option.add_argument('--disable-gpu')
chrome_option.add_argument('--disable-dev-shm-usage')

运行H5

使用H5的方式运行,需要修改浏览器的mobileEmulation配置

代码语言:javascript复制
chrome_option = Options()
chrome_option.add_experimental_option('mobileEmulation', {'deviceName': deviceName})
chrome_option.add_experimental_option('w3c', False)

完整的打开浏览器操作

增加一些异常处理、兼容性处理

  • HEADLESS:是否采用无头浏览器模式
    • True:是
    • False:否

打开浏览器后最大化

代码语言:javascript复制
try:
    self.driver.maximize_window()
except Exception as e:
    print(f"浏览器最大化失败:{e}")

切换frame

代码语言:javascript复制
def switch_frame(self, frame_locator):
    self.driver.switch_to.default_content()
    self.driver.switch_to.frame(frame_locator.element)

完整代码

代码语言:javascript复制
def open(self, url, locator, frame_locator=None, driver='chrome', deviceName='iPhone X'):
    """

    :param url: 打开的地址
    :param locator: 确认打开成功的元素
    :param frame_locator: 需要切换的frame
    :param driver: 浏览器驱动
    :param deviceName: h5测试设备型号
    :return:
    """
    driver = driver.lower()
    if driver in ['chrome', 'ie', 'chrome-h5']:
        try:
            socket.setdefaulttimeout(50)
            if not self.driver:
                if 'chrome' in driver:
                    desired_capabilities = DesiredCapabilities.CHROME
                    desired_capabilities["pageLoadStrategy"] = "eager"
                    chrome_option = Options()
                    if HEADLESS == 'true':
                        chrome_option.add_argument('--headless')
                    if driver == 'chrome-h5':
                        chrome_option.add_experimental_option('mobileEmulation', {'deviceName': deviceName})
                        chrome_option.add_experimental_option('w3c', False)
                    if platform.system() == "Windows":
                        driver_path = f'{TOOL_PATH}/driver/win/chromedriver'
                    elif platform.system() == "Linux":
                        chrome_option.add_argument('--headless')
                        chrome_option.add_argument('--no-sandbox')
                        chrome_option.add_argument('--disable-gpu')
                        chrome_option.add_argument('--disable-dev-shm-usage')
                        driver_path = f'{TOOL_PATH}/driver/linux/chromedriver'
                        os.system(f"chmod -R 777 {driver_path}")
                    else:
                        driver_path = f'{TOOL_PATH}/driver/mac/chromedriver'
                        os.system(f"chmod -R 777 {driver_path}")
                    logger.info(f'使用的chromedriver为「{driver_path}」。请确认版本是否与当前浏览器版本一致')
                    self.driver = webdriver.Chrome(executable_path=f'{driver_path}',
                                                   chrome_options=chrome_option,
                                                   desired_capabilities=desired_capabilities)
                elif driver == 'ie':
                    ie_options = DesiredCapabilities.INTERNETEXPLORER  # 将忽略IE保护模式的参数设置为True
                    ie_options['ignoreProtectedModeSettings'] = True  # 忽略浏览器缩放设置
                    ie_options['ignoreZoomSetting'] = True  # 启动带有自定义设置的IE浏览器
                    self.driver = webdriver.Ie(capabilities=ie_options)
            time.sleep(2)
            self.driver.get(url)
            time.sleep(5)
            try:
                self.driver.maximize_window()
            except Exception as e:
                print(f"浏览器最大化失败:{e}")
            if frame_locator:
                self.wait_element_visible(frame_locator)
                self.switch_frame(frame_locator)
            if locator:
                self.wait_element_visible(locator)
        except Exception as e:
            raise Exception(f"打开浏览器进入{url}失败:{e}")
    self.wait_for(10)
    return self.driver

项目地址

新建了一个version_1分支:

https://gitee.com/zx660644/uitest/tree/version_1/

0 人点赞