自动化测试学习官

自动化测试学习官

一、设计思路

框架采用python3+yaml+po+unittest+HTMLTestRunner等技术编写的UI自动化测试框架
1.使用Page Object模式将页面定位和业务操作分开,分离测试对象(元素对象)和测试脚本(用例脚本),一个页面建一个对象类,提高用例的可维护性;
2.使用yaml管理页面空间元素和测试用例数据。例如一个页面元素发生变化时,不需要去修改代码,只需要在对应的页面元素yaml文件中修改即可。
3.以每个页面作为模块管理,随时组装,互不影响。

二、测试框架分层

webUI自动化测试框架-LMLPHP

1.框架层:基础组件封装,支撑整个框架的流程执行及功能扩展
2.用例层:根据用例场景构造test测试方法
3.业务层:封装页面对象类,一个页面建立一个类,业务层基础基础层page类
4.基础层:二次开发selenium的元素定位已经操作
 

三、编写用例方法

例如我需要新增百度搜索测试场景用例:

1.在testyaml目录下新增一个页面对象yaml文件,利用封装的yamlload方法将yaml文件中的dom元素读取出来,提供给封装页面对象类调用并定元素操作。

  

2.在testdata目录下新增一个yaml文件提供给用例测试数据

3.在page_obj目录编写百度搜索场景的页面对象类封装

4.在testcase目录编写测试用例文件,采用ddt数据驱动读取yaml测试数据源文件

5.通过多线程将驱动传给执行方法,并行开启多个浏览器执行测试

  

6.操作元素封装

7.浏览器驱动封装

from typing import Union, Type
from selenium.webdriver import *
from selenium.webdriver.opera.options import Options as OperaOptions
from selenium.webdriver.edge.options import Options as EdgeOptions
from setting import *

BROWSERS = (Chrome, Ie, Firefox, Edge, Opera, PhantomJS)
OPTIONS = (ChromeOptions, IeOptions, FirefoxOptions, EdgeOptions, OperaOptions)


class BROWSER:

    CHROME_DRIVER_PATH = CHROME_DRIVER_PATH

    # 使用32位ie驱动解决文本输入缓慢的问题
    IE_DRIVER_PATH = IE_DRIVER_PATH

    FIREFOX_DRIVER_PATH = FIREFOX_DRIVER_PATH
    EDGE_DRIVER_PATH = EDGE_DRIVER_PATH
    OPERA_DRIVER_PATH = OPERA_DRIVER_PATH

    HEADLESS = HEADLESS

    # IMPLICITLY WAITING TIME METHOD
    IMPLICITLY_WAIT_TIME = 10

    # PAGE SOURCE LOAD TIME METHOD
    PAGE_LOAD_TIME = 10

    # the script should wait during an
    # execute_async_script call before throwing an error
    SCRIPT_TIMEOUT = 0

    # SET WINDOW SIZE METHOD
    WINDOWS_SIZE = (1024, 900)

    def __init__(self, browser_type: Type[Union[Chrome, Ie, Firefox, Edge, Opera, PhantomJS, Remote]] = Chrome,
                 option_type: Type[Union[FirefoxOptions, ChromeOptions, IeOptions, EdgeOptions, OperaOptions]] = ChromeOptions,
                 driver_path: str = CHROME_DRIVER_PATH):
        if not issubclass(browser_type, BROWSERS):
            raise TypeError
        if not issubclass(option_type, OPTIONS):
            raise TypeError
        if not isinstance(driver_path, str):
            raise TypeError
        self._driver = browser_type
        self._option = option_type
        self._path = driver_path

    @property
    def browser(self):
        """
        subclass should implement this method
        return the instance of WebDriver
        :return:
        """
        return

    @property
    def _options(self):
        """
        subclass should implement this method
        return instance of the Option Type like ChromeOptions
        :return:
        """
        return


class CHROME(BROWSER):

    METHOD_MARK = True

    IMPLICITLY_WAIT_TIME = 30

    PAGE_LOAD_TIME = 20

    SCRIPT_TIMEOUT = 10

    # HEADLESS MODEL OPTION
    HEADLESS = False

    OPTION_MARK = True

    # EXPERIMENTAL OPTION
    EXPERIMENTAL = {
        # 'mobileEmulation': {'deviceName': 'iPhone 6'},  #以移动格式现实启动页面做h5时候会用到
        'excludeSwitches': ['enable-automation'] #浏览器启动时左上角提示正在运行自动化
    }

    # WINDOW SIZE OPTION
    WINDOW_SIZE = ''
    # WINDOW_SIZE = '--window-size=1920,1080'

    # START MAXIMIZED OPTION
    START_MAXIMIZED = '--start-maximized'

    @property
    def _options(self):
        """
        chrome浏览器特有的操作属性
        :return:
        """
        if self.OPTION_MARK:
            chrome_option = self._option()
            chrome_option.headless = self.HEADLESS
            if self.WINDOW_SIZE:
                chrome_option.add_argument(self.WINDOW_SIZE)
            if self.START_MAXIMIZED:
                # chrome_option.add_argument(self.START_MAXIMIZED)
                chrome_option.add_argument('--headless')
                chrome_option.add_argument('--disable-gpu')

            for k, v in self.EXPERIMENTAL.items():
                chrome_option.add_experimental_option(k, v)
            return chrome_option
        return None
    
    @property
    def browser(self):
        """
        启动chrome浏览器并进行初始配置
        :return:
        """

        if self._options:
            chrome = self._driver(self._path, options=self._options)
        else:
            chrome = self._driver(self._path)

        if self.METHOD_MARK:
            chrome.implicitly_wait(self.IMPLICITLY_WAIT_TIME)
            chrome.set_page_load_timeout(self.PAGE_LOAD_TIME)
            chrome.set_script_timeout(self.SCRIPT_TIMEOUT)
            return chrome



class IE(BROWSER):

    IMPLICITLY_WAIT_TIME = 20

    PAGE_LOAD_TIME = 10

    SCRIPT_TIMEOUT = 10

    WINDOWS_SIZE = (1600, 1024)

    CLEAN_SESSION = True

    ATTACH_TIMEOUT = 10000

    MARK = True

    def __init__(self):
        super(IE, self).__init__(
            browser_type=Ie,
            option_type=IeOptions,
            driver_path=super().IE_DRIVER_PATH
        )

    @property
    def _options(self):
        """
        ie浏览器特有的操作属性
        :return:
        """
        ie_option = self._option()
        ie_option.browser_attach_timeout = self.ATTACH_TIMEOUT
        ie_option.ensure_clean_session = self.CLEAN_SESSION
        return ie_option

    @property
    def browser(self):
        """
        启动ie浏览器并进行初始配置
        :return:
        """
        if self.MARK:
            ie = self._driver(self._path, options=self._options)
        else:
            ie = self._driver(self._path)
        ie.implicitly_wait(self.IMPLICITLY_WAIT_TIME)
        ie.set_page_load_timeout(self.PAGE_LOAD_TIME)
        ie.set_script_timeout(self.SCRIPT_TIMEOUT)
        ie.set_window_size(*self.WINDOWS_SIZE)
        return ie


class FIREFOX(BROWSER):

    def __init__(self):
        super(FIREFOX, self).__init__(
            browser_type=Firefox,
            option_type=FirefoxOptions,
            driver_path=super().FIREFOX_DRIVER_PATH
        )

    @property
    def _options(self):
        return

    def browser(self):
        return self._driver(self._path)


class OPERA(BROWSER):

    def __init__(self):
        super(OPERA, self).__init__(
            browser_type=Opera,
            option_type=OperaOptions,
            driver_path=super().OPERA_DRIVER_PATH
        )

    @property
    def _options(self):
        return

    def browser(self):
        return self._driver(self._path)

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员二黑】自提!

webUI自动化测试框架-LMLPHP

webUI自动化测试框架-LMLPHP

03-09 04:22