Bootstrap

selenium UI自动化之数据驱动

在设计UI自动化时,需要考虑到如何进行数据驱动的处理,当下比较常见的有DDT,Yaml,关键字驱动,CSV等等作为ui自动化测试用例;

其中以csv文件为例,如果有一个业务多个场景可以再csv文件中使用多行数据,每一行代表一个用例实现业务串联自动化

在以上过程涉及到两个点:

1、csv读取到的数据格式以什么样的形式,具体数据格式示例:{‘机构名称’: [‘大道展览(北京)有限公司’], ‘机构证件类型’: [‘营业执照(统一社会信用代码)’], ‘证件类型参数’: [‘测试批文一号’]}

2、如果将csv获取到的数据以串联的方式,实现一行数据代表一个业务场景,实现多个账户在同一个csv文件下执行多场景用例;

以账户开户为例,多个用户开户涉及到不同的元素有:手机号码,国籍,企业类型,产品名称,证件类型等等

解决问题1;以数据采用key:value模式,其中csv文件上首行为key,其他行为value,每一行数据为一个业务场景

以下是相关csv实现代码:

import pandas as pd

class Read_Pandas_Excel:
    def __init__(self, file_path=None, n=None):
        """

        :param file_path:
        :param n:
        """
        if file_path == None:
            self.file_path = "../config/acoountdata.csv"
        else:
            self.file_path = file_path

        if n == None:
            self.n = 1
        else:
            self.n = n

    def read_excel(self):
        """
        读取CSV文件,第一行作为 key,后续行作为对应 key 的 values 返回键值对
        :return: 键值对字典
        """
        try:
            df = pd.read_csv(self.file_path, header=None, encoding='utf-8')
        except UnicodeDecodeError:
            df = pd.read_csv(self.file_path, header=None, encoding='gbk')

        data_dict = {}
        keys = df.iloc[0]  # First row as keys

        num_rows = df.shape[0]  # Number of rows in the DataFrame excluding header
        for col in range(len(keys)):
            key = keys[col]
            values = df.iloc[1:num_rows, col].tolist()  # Values for each key (from row 1 to num_rows)
            data_dict[key] = values

        return data_dict, num_rows

    def get_value(self, key,nums):
        try:
            data_dict = self.read_excel()[0]
            if key not in data_dict:
                raise KeyError(f"Key '{key}' not found in data.")
            else:
                return data_dict[key][nums]
        except Exception as e:
            print(f"Error occurred: {str(e)}")
            return None
if __name__ == "__main__":
    getPandas = Read_Pandas_Excel(file_path="../config/registercase.csv")
    data_dict, num_rows = getPandas.read_excel()
    for i in range(0, num_rows-1):
        test_account = getPandas.get_value("机构名称", i)
        print(test_account)
"""
目前以csv文件形式做数据的保存,其中以行数据作为每条测试用例来执行
case1,case2,case3...caseN为第一行,第二行,第三行...第N行;
执行结果以断言成功为准;
失败结果使用日志进行记录,将每个页面划分为多个模块,如果某个模块有问题,则可以直接定位到大致模块位置
后期拓展:如果有报错信息,则进行截图并将截图信息保存在固定位置,截图信息以当日时间精确到秒级别命名保存在同一文件夹中
,其中文件夹以每日为分割进行划分,保证数据可以分类;
"""

解决问题2,在主程序中读取到csv文件数,并将涉及到需要填充csv文件数的代码设置成可变化的形式,并采用subTest方式实现以上功能;具体代码如下:

# coding=utf-8
import time
import unittest
from selenium import webdriver
from log.user_log import UserLog
from util.read_ini import ReadIni
from AccountUtils.AccountPandasExcel import Read_Pandas_Excel
from business.plateform_register_business import PlateFormRegisterBusiness

class FirstCase(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        """
        :return:
        """
        cls.log = UserLog()
        cls.logger = cls.log.get_log()
        cls.driver = webdriver.Chrome()
        cls.driver.get('http://xxxxxxx/xxx/#/index')
        cls.driver.maximize_window()

    def setUp(self):
        self.driver.refresh()
        self.plateregister = PlateFormRegisterBusiness(self.driver)

    def tearDown(self):
        pass

    @classmethod
    def tearDownClass(cls):
        pass
        # cls.driver.close()

    def test_register_success(self):
        """
        需求完成:1.完成csv用例循环输入,保证可以一次性多用户输入
        未完成,针对机构证件类型这里还没做比较合适的选择操作
        """
        #
        getPandas = Read_Pandas_Excel(file_path="../config/registercase.csv")
        data_dict, num_rows = getPandas.read_excel()
        for i in range(0, num_rows-1):
            test_account = getPandas.get_value("机构名称", i)
            with self.subTest(row=i):
                time.sleep(2)
                success = self.plateregister.startplateformTest(test_account,i)
                self.assertFalse(success)  # 根据实际情况断言测试结果

if __name__ == '__main__':
    unittest.main()

业务代码:

#coding=utf-8
import time
from handle.plateform_register_handel import PlateFormRegisterHandle
class PlateFormRegisterBusiness:

    def __init__(self,driver):
        self.plateformregister_h = PlateFormRegisterHandle(driver)

    # 登录页面
    def startplateformTest(self, company_name, num):

        ## 选择注册
        self.plateformregister_h.plateform_register_element()

        ## 设置注册公司
        self.plateformregister_h.plateform_register_jginfo(company_name, num)

业务代码2:

class PlateFormRegisterHandle(object):
    def __init__(self,driver):
        self.driver = driver
        get_user_log = UserLog()
        self.logger = get_user_log.get_log()
        self.fd = FindElement(driver)
        self.wait = WebDriverWait(driver, 20,0.5)
        self.updowm = PyautoguiUpDown()
        self.WebWaits = WebDriverWaitCommon(self.driver)
        self.pandasdata =Read_Pandas_Excel(file_path="../config/registercase.csv")
        self.idnumber = RandomIDCards()

    def WebDriverWaitOperaton(self, checkparams):
        """
        等待时间封装
        :param checkparams:
        :return:
        """
        return WebDriverWait(self.driver, 15).until(EC.element_to_be_clickable((By.XPATH, checkparams)))

    def plateform_register_element(self):
        self.register_element = self.fd.get_plateform_element("register_element")
        self.register_element.click()
        time.sleep(3)
        self.next_element = self.fd.get_plateform_element("next_element")
        self.driver.execute_script("$(arguments[0]).click()", self.next_element)

    def register_user_cardtype(self, num):
        """
        实现针对用户选择机构证件类型的操作,从csv文件中获取到相应的值
        :param num:
        :return:
        """
        #选择证件类型逻辑处理
        self.WebWaits.send_keys_paramsba570d48(self.fd.get_plateform_text("jg_id"), "click",
                                                self.pandasdata.get_value("机构证件类型", num))
        if self.pandasdata.get_value("机构证件类型", num) == "营业执照(统一社会信用代码)":
            return None

        if self.pandasdata.get_value("机构证件类型", num) == "批文":
            self.WebWaits.send_keys_params(self.fd.get_plateform_text("jg_idnumber"), "focus", self.pandasdata.get_value("证件类型参数", num))
        else:
        #输入证件id
         self.WebWaits.send_keys_params(self.fd.get_plateform_text("jg_idnumber"), "focus", self.idnumber)

    def plateform_register_jginfo(self, company_name, num):
        """
        设置注册公司,采用输入在使用script点击操作;
        :param company_name:
        :return:
        """
        time.sleep(2)
        self.jg_name = self.fd.get_plateform_element("jg_name").send_keys(company_name)
        self.target_element = self.wait.until(EC.visibility_of_element_located((By.XPATH, f"//ul[contains(@class, 'el-autocomplete-suggestion__list')]//li[contains(text(), '{company_name}')]")))
        self.driver.execute_script("arguments[0].click();", self.target_element)

        # 设置机构类型
        self.register_user_cardtype(num)
        #经办人
        self.second_element = self.fd.get_plateform_element("second_element").click()
        self.jbr_name = self.fd.get_plateform_element("jbr_name").send_keys("经办人测试")
        # 身份证号码设置
        self.idcode = self.fd.get_plateform_element("idcode").send_keys(ET3OTClibs.runidcard(1))
        # 设置邮箱
        self.email = self.fd.get_plateform_element("email").send_keys(ET3OTClibs.RandomEmail())
        # 设置手机号码
        self.phone = self.fd.get_plateform_element("phone")
        phonenumber = ET3OTClibs.generate_random_phone_number()
        self.phone.send_keys(phonenumber)

        with open('../test.txt', 'a') as f:
            # 将参数写入文件,并添加换行符
            f.write(f"param1: {company_name}, param2: {phonenumber}\n")
;