zoukankan      html  css  js  c++  java
  • UI自动化测试框架:数据驱动

    一、UI自动化框架介绍

    测试框架使用了Po设计模式(Page Object),每一个页面用一个类来对应,这个类里面要实现所有核心页面元素的获取方法,类里面提供操作页面元素的所有方法。
    这个框架实现几点:
    1.把常用的代码进行了封装,减少重复代码的编写。
    比如说,操作excel 的方法,记录日志的方法,创建文件的方法,查找元素的方法,解析ini配置文件的方法,还有记录时间的方法,都进行封装,在使用时直接进行调用。
    2.做到了测试程序和测试数据进行了分离。
    3.做到了定位表达式和程序的分离。
    4.易于维护
    5.能够选择不同的测试数据进行执行
    6.有测试报告
    7.可以在异常的时候进行截屏操作
    8.可以记录测试日志

    二、框架的结构

    1 配置信息:Conf

      日志的配置文件,框架工程的全局变量,其他配置

    2 日志:Log

      执行的时候打印的日志

    3 测试数据:TestData

      测试的excel文件,元素的定位表达式文件,其他测试数据

    4 测试逻辑封装:Action

      基于你的测试逻辑或者场景通过常见测试步骤的封装,比如登录。

    5 测试框架的核心代码:TestScript

      数据驱动中执行的测试步骤; 读取测试数据;执行测试脚本;收集测试结果;提供测试报告。

    6 工程的全局封装:Util

       excel读取;日志的使用;日期的封装;目录的封装;页面元素获取的封装;配置文件读取的封装

    7 PageObject (homepage 页面属于的结构) PageObject

    目录结构如下:

    三、代码说明

    1、ConfPageElementLocator.ini

    [crm_login]
    loginPage.username=xpath>//input[@id="txtUsername"]
    loginPage.password=xpath>//input[@id="txtPassword"]
    loginPage.loginbutton=xpath>//input[@type="submit"]

    说明:

    该文件的作用是实现定位表达式和程序的分离。让每个定位表达式有个名字,方便使用和管理。

    用到哪个页面的元素就把对应的定义表达式更新到该文件中。

    给每个页面起个名字,作为section的名字,[crm_login]:

       loginPage.username 是自己给每个元素取的名字;

      =xpath 表示用xpath定位;

      > 用于分割;

      //input[@id="txtUsername"]是xpath表达式

    2、ConfProjVar.py

      放置当前工程路径;配置文件路径;数据文件路径;测试数据Excel列。

      代码举例:

    import os
    
    # 当前工程的路径
    proj_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # 配置文件的路径
    PageElementLocator_file_path = os.path.join(proj_path,r"ConfPageElementLocator.ini")
    
    # 数据文件的路径
    test_data_file_path = os.path.join(proj_path,r"TestDatacrm登录账号.xlsx")
    
    # "crm账号"sheet页名称
    test_user_info_sheet = "crm账号"
    # "crm账号"sheet页列表的名称
    username_col = 1
    password_col = 2
    test_data_sheet_col = 3
    execute_flag_col = 4
    test_time_col = 5
    test_user_info_result_col = 6
    
    # "测试结果"sheet页名称
    test_result_sheet = "测试结果"

    3、ConfLogger.conf

      记录日志的配置文件

      同时将生成的日志写入:LogAutoTestLog.log 文件

    4、PageObjectLoginPage.py

      负责实现po的内容,一个页面的所有操作,都写到一个类里面。
      举例:LoginPage.py 实现登录页面的PO
        get_login_link(self):获取要操作的链接元素
        click_login_link(self):点击这个链接元素的动作
        只写怎么操作页面元素,不写任何测试逻辑
      部分代码示例:
    class loginPage():
        def __init__(self,driver):
            self.driver = driver
    
        def get_login_username(self):
            input = read_ini_file_option(PageElementLocator_file_path,"crm_login","loginPage.username")
            element = find_element(self.driver,input.split(">")[0],input.split(">")[1])
            return element
    
        def input_login_username(self,username):
            self.get_login_username().send_keys(username)

    5、ScreenPics

      在代码中,断言失败或执行失败时,将当前页面截图,根据执行时间生成路径并保存截图。

    6、TestData

      将需要测试的数据放到该文件夹下,根据excel中的数据执行自动化测试脚本。

    7、TestScript

      该文件夹下的文件执行具体的测试步骤和用例。

      如:AddNewCaseTestScript.py 从TestData的excel中,读取测试数据,根据不同的测试数据创建case。

    8、Util

      放配置文件,如常用的 获取时间,创建文件夹,读写Excel等文件封装好,放到这里。使用时直接调用。

      举例1:TakePic.py  截图配置文件

    from Util.Dir import *
    from selenium import webdriver
    
    def take_pic(driver):
        file_path = make_time_dir()
        pic_path = os.path.join(file_path, TimeUtil().get_chinesedatetime() + ".png")
        try:
            result = driver.get_screenshot_as_file(pic_path)
            print(result)
        except IOError as e:
            print(e)

      举例2:ParseConfig.py 解析配置文件PageElementLocator.ini

    #encoding=utf-8
    # 解析配置文件
    
    import configparser
    
    def read_ini_file_all_sections(ini_file_path):
        '''拿到所有的section'''
        cf = configparser.ConfigParser()
        cf.read(ini_file_path,encoding="utf-8")
        return cf.sections()
    
    def read_ini_file_section_all_options(ini_file_path,section_name):
        '''拿到指定的section的所有名称'''
        cf = configparser.ConfigParser()
        cf.read(ini_file_path, encoding="utf-8-sig")
        return cf.options(section_name)
    
    def read_ini_file_option(ini_file_path,section_name,option_name):
        '''拿到指定section名称的值'''
        cf = configparser.ConfigParser()
        cf.read(ini_file_path, encoding="utf-8-sig")
        try:
            value = cf.get(section_name,option_name)
        except:
            print ("the specific seciton or the specific option doesn't exit!")
            return None
        else:
            return value

      举例3:Dir.py 创建目录

    def make_dir(dir_path):
        if not os.path.exists(dir_path):
            try:
                os.makedirs(dir_path)
                print("创建目录 %s 成功" %dir_path)
            except:
                print("创建目录 %s 不成功" %dir_path )
    
    def make_time_dir():
        date = TimeUtil().get_chinesedate()
        dir_path = os.path.join(proj_path,"ScreenPics")
        dir_path = os.path.join(dir_path,date)
        dir_path =  os.path.join(dir_path,str(TimeUtil().get_hour()))
        make_dir(dir_path)
        return dir_path

      其他常用的方法可根据项目的需求进行封装:

  • 相关阅读:
    About Dump File
    设置IIS延长Debug
    正则表达式中\d和[00]有什么区别
    理解程序语言语法的merge工具——semanticmerge
    大数据还是小数据
    如何在TFS中配置别的diff/merge的工具
    一个很cool的展示编程语言相互影响关系的网状图
    常见的算法的时间和空间复杂度
    C#的强迫执行域Constrained Execution Regions(CERs)
    C++的C4305和C4800的编译警告
  • 原文地址:https://www.cnblogs.com/hqq2019-10/p/14096857.html
Copyright © 2011-2022 走看看