如何搭建数据驱动自动化测试框架?

news2024/12/23 6:56:19

前言

说到数据驱动自动化测试,你会不会有这样的疑问:数据怎么管理?数据怎么才能驱动测试用例执行?到底怎么样才算数据驱动?那么本篇文章就教你如何进行数据驱动测试,相信你一定能对数据驱动自动化测试有一个不一样的理解,希望这篇文章能帮助还在懵懵懂懂的你了解数据驱动测试,如何来做数据驱动测试?那么就跟上我的脚步吧^_^

项目介绍

1.实现126邮箱登录功能的验证

2.实现126邮箱添加新联系人功能的验证

目录结构

项目源码

1.新建config目录存放和业务无关的数据文件,比如PageElementLocator.ini 用来存放我们每个页面的定位元素表达式。


[126mail_login]
loginPage.frame=xpath>//div[@id='loginDiv']/iframe
loginPage.username=xpath>//input[@name='email']
loginPage.password=xpath>//input[@name='password']
loginPage.loginBtn=xpath>//a[@id='dologin']
[126mail_homePage]
homePage.addressbook=id>_mail_tabitem_1_4text
[126mail_addContactPage]
addContactPage.newContact=xpath>//span[text()='新建联系人']
addContactPage.newName=id>input_N
addContactPage.newMail=xpath>//div[@id='iaddress_MAIL_wrap']//input[@class='nui-ipt-input']
addContactPage.newMark=xpath>//span[@class='nui-chk-text']/preceding-sibling::span/b
addContactPage.newPhone=xpath>//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']
addContactPage.newComment=id>input_DETAIL
addContactPage.newCommit=xpath>//span[text()='确 定']

2.有了上面元素的表达式我们又该如何查找我们的元素呢?这时候我们需要封装一套无论何种定位方式都可以使用的通用的查找方法。新建util目录(util目录主要存放和我们业务无关的公共方法),此目录下新建ObjectMap.py文件


 1 from selenium.webdriver.support.wait import WebDriverWait
 2 
 3 def getElement(driver, by, locate):
 4     '''
 5     查找单一个元素
 6     :param driver: 浏览器驱动
 7     :param by: 定位方式,id, name, class, xpath...
 8     :param locate: 定位表达式
 9     :return: 元素
10     '''
11     try:
12         element = WebDriverWait(driver, 30).until(lambda x :x.find_element(by, locate))
13     except Exception as e:
14         raise e
15     else:
16         return element
17 def getElelments(driver, by, locate):
18     '''
19     查找一组元素
20     :param driver: 浏览器驱动
21     :param by: 定位方式
22     :param locate: 定位表达式
23     :return: 一组元祖组成的列表
24     '''
25     try:
26         elements = WebDriverWait(driver, 30).until(lambda x :x.find_elements(by, locate))
27     except Exception as e:
28         raise e
29     else:
30         return elements
31 if __name__=='__main__':
32     from selenium import webdriver
33     driver = webdriver.Firefox()
34     driver.get('http://www.baidu.com')
35     inputBaidu = getElement(driver, 'id', 'kw')
36     inputBaidu.send_keys('python')

3.定位表达式有了,查找元素的方法封装好了,下面我们需要解析配置文件,获取配置文件中我们需要的定位方式和定位表达式。同样在util目下新建ParseConfigurationFile.py文件用来解析配置文件


 1 from config.varCondig import pageElementLocatorPath
 2 import configparser
 3 
 4 class ParseConfigFile(object):
 5     '''
 6     解析ini配置文件
 7     '''
 8     def __init__(self):
 9         try:
10             self.cf = configparser.ConfigParser() # 获取配置文件对象
11             self.cf.read(pageElementLocatorPath, encoding='utf-8') # 加载配置文件到内存中
12         except Exception as e:
13             raise e
14 
15     def getItemsSection(self, sectionName):
16         '''
17         获取section下面所有section的键值
18         :param sectionName:
19         :return:
20         '''
21         try:
22             vlaues = dict(self.cf.items(sectionName))
23         except Exception as e:
24             raise e
25         else:
26             return vlaues
27 
28     def getElementValue(self, sectionName, optionName):
29         try:
30             locator = self.cf.get(sectionName, optionName).split('>')
31         except Exception as e:
32             raise e
33         else:
34             return locator # 获取option键对应的value
35 
36     def getAllSections(self):
37         try:
38             allsections = self.cf.sections()
39         except Exception as e:
40             raise e
41         else:
42             return allsections # 所有的sections返回值是个列表
43 
44     def getAllOptions(self, section):
45         try:
46             options = self.cf.options(section)
47         except Exception as e:
48             raise e
49         else:
50             return options # 某个section下面的键
51 
52 if __name__=='__main__':
53     cf = ParseConfigFile()
54     locator = cf.getElementValue('126mail_login','loginPage.username')
55     # print(locator)
56     print(cf.getItemsSection('126mail_login'))
57     print(cf.getAllSections())
58     print(cf.getAllOptions('126mail_addContactPage'))

4.我们获取到了每一个元素的定位方式和定位表达式,接下来我们又该如何查找到我们的元素对象呢?这时候我们会想到PO(pageObject)设计模式,把我们每一个page页面的元素保存到对应页面的文件中。

新建pageObjects目录,在此目录下分别创建HomePage.py LoginPage.py NewContact.py 三个页面文件LoginPage.py文件存放我们登录页面所需要的元素, HomePage.py 存放登录成功后首页所需要的页面元素, NewContact.py文件存放我们添加联系人页面所需要的元素。


 1 from util.ObjectMap import *
 2 from util.ParseConfigurationFile import ParseConfigFile
 3 class LoginPage(object):
 4     '''
 5     登录页面所有的操作元素对象
 6     '''
 7     def __init__(self, driver):
 8         self.driver = driver
 9         self.cf = ParseConfigFile()
10 
11     def switchToFrame(self):
12         '''
13         切换到frame中
14         :return:
15         '''
16         by, locator = self.cf.getElementValue('126mail_login', 'loginPage.frame')
17         try:
18             self.driver.switch_to.frame(getElement(self.driver, by,locator))
19         except Exception as e:
20             raise e
21 
22     def switchToDefaultFrame(self):
23         '''
24         跳出frame
25         :return:
26         '''
27         try:
28             self.driver.switch_to.default_content()
29         except Exception as e:
30             raise e
31 
32     def userNameObj(self): # 用户名输入框
33         by, locator = self.cf.getElementValue('126mail_login', 'loginPage.username')
34 
35         username = getElement(self.driver, by, locator)
36         return username
37 
38     def passwordObj(self): # 密码输入框
39         by, locator = self.cf.getElementValue('126mail_login', 'loginPage.password')
40 
41         password = getElement(self.driver, by, locator)
42         return password
43 
44     def loginBtnObj(self): # 登录按钮
45         by, locator = self.cf.getElementValue('126mail_login', 'loginPage.loginBtn')
46 
47         loginbtn = getElement(self.driver, by, locator)
48         return loginbtn
49 
50 if __name__=='__main__':
51     from selenium import webdriver
52     import time
53     driver = webdriver.Firefox()
54     driver.get('https://mail.126.com')
55     login = LoginPage(driver)
56     time.sleep(5)
57     login.switchToFrame()
58     login.userNameObj().send_keys('linuxxiaochao')
59     login.passwordObj().send_keys('xiaochao11520')
60     login.loginBtnObj().click()
61     login.switchToDefaultFrame()
62     driver.quit()

1 from util.ObjectMap import * #查找元素的模块
 2 from util.ParseConfigurationFile import ParseConfigFile
 3 
 4 class HomePage(object):
 5 
 6     def __init__(self, driver):
 7         self.driver = driver
 8         self.cf = ParseConfigFile()
 9 
10     def addressLink(self):
11         '''
12         通讯录菜单对象
13         :return:
14         '''
15         by, locator = self.cf.getElementValue('126mail_homePage','homePage.addressbook')
16 
17         elementObj = getElement(self.driver, by, locator)
18         return elementObj
19 
20 if __name__=='__main__':
21     from selenium import webdriver
22     from pageObjects.LoginPage import LoginPage
23     import time
24     driver = webdriver.Firefox()
25     driver.get('https://mail.126.com')
26     login = LoginPage(driver)
27     homePage = HomePage(driver)
28     time.sleep(5)
29     login.switchToFrame()
30     login.userNameObj().send_keys('linuxxiaochao')
31     login.passwordObj().send_keys('xiaochao11520')
32     login.loginBtnObj().click()
33     login.switchToDefaultFrame()
34     time.sleep(3)
35     homePage.addressLink().click()
36     time.sleep(10)
37     driver.quit()

1 from util.ParseConfigurationFile import ParseConfigFile
 2 from util.ObjectMap import *
 3 
 4 class AddContactPage(object):
 5     '''
 6     添加联系人页面所有操作元素对象
 7     '''
 8     def __init__(self, driver):
 9         self.driver = driver
10         self.cf = ParseConfigFile()
11 
12     def newContact(self): # 新建联系人
13         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newContact')
14 
15         element = getElement(self.driver, by, locator)
16         return element
17 
18     def addName(self): # 姓名输入框
19         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newName')
20 
21         element = getElement(self.driver, by, locator)
22         return element
23 
24     def addMail(self): # 电子邮件输入框
25         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newMail')
26 
27         element = getElement(self.driver, by, locator)
28         return element
29 
30     def markStar(self): # 设为星际联系人
31         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newMark')
32 
33         element = getElement(self.driver, by, locator)
34         return element
35 
36     def addPhone(self): # 手机号码输入框
37         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newPhone')
38 
39         element = getElement(self.driver, by, locator)
40         return element
41 
42     def addContent(self): # 备注
43         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newComment')
44 
45         element = getElement(self.driver, by, locator)
46         return element
47 
48     def clickCommitBtn(self): # 确定按钮
49         by, locator = self.cf.getElementValue('126mail_addContactPage', 'addContactPage.newCommit')
50 
51         element = getElement(self.driver, by, locator)
52         return element
53 
54 if __name__=='__main__':
55     from selenium import webdriver
56     import time
57     from pageObjects.HomePage import HomePage
58     from appModules.LoginAction import LoginAction
59 
60     driver = webdriver.Firefox()
61     driver.get('https://mail.126.com')
62     time.sleep(3)
63     # 登录
64     LoginAction.login(driver,'linuxxiaochao', 'xiaochao11520')
65     # 主页面
66     homepage = HomePage(driver)
67     homepage.addressLink().click()
68     time.sleep(5)
69     # 添加联系人页面
70     addcontact = AddContactPage(driver)
71     addcontact.newContact().click()
72     time.sleep(2)
73     addcontact.addName().send_keys('test')
74     addcontact.addMail().send_keys('13691579846@qq.com')
75     addcontact.addPhone().send_keys('13691579846')
76     addcontact.addContent().send_keys('ceshi')
77     addcontact.markStar().click()
78     time.sleep(3)
79     addcontact.clickCommitBtn().click()

5.接下来考虑,我们的框架需要数据驱动?那么我们该怎么用数据驱动我们测试呢?是不是应该通过修改测试数据能够控制我们用例的执行还是不执行呢?没错,大概就是这个样子,那我们又该如何来设计我们的数据呢?大概最好的办法就是使用excel文件来存储或者如果你有能力可以考虑使用数据库来存储,看下我们的表格是什么样子。

新建testData目录存放我们测试过程中所有和业务数据相关的数据文件,并新建126MailContact.xlsx 文件,文件中分两个sheet 126account 和 126contact 分别存放登录和联系人数据

6.通过上面的表我们可以看到两列数据“是否执行”,没错了我们就是通过这来控制数据是否驱动用例执行的,用例执行后写入测试是否通过和测试执行时间(代码中我没加写入时间,感兴趣的自己在用例只加就行了)7.有了这些数据我们又该如何读取到这些数据应用到我们的用例中呢?在util目录下新建ParseExcel.py 用来解析excel文件


 1 from openpyxl import load_workbook
 2 from config.varCondig import *
 3 class ParseExcel(object):
 4     '''
 5     解析excel文件的封装
 6     '''
 7     def __init__(self):
 8         # 加载excel文件到内存
 9         self.wb = load_workbook(testExcelValuePath)
10 
11     def getRowValue(self, sheetName, rawNo):
12         '''
13         获取某一行的数据
14         :param sheetName:
15         :param rawNo:
16         :return: 列表
17         '''
18         sh = self.wb[sheetName]
19         rowValueList = []
20         for y in range(2, sh.max_column+1):
21             value = sh.cell(rawNo,y).value
22             rowValueList.append(value)
23         return rowValueList
24     def getColumnValue(self, sheetName, colNo):
25         '''
26         获取某一列的数据
27         :param sheetName:
28         :param colNo:
29         :return: 列表
30         '''
31         sh = self.wb[sheetName]
32         colValueList = []
33         for x in range(2, sh.max_row +1):
34             value = sh.cell(x, colNo).value
35             colValueList.append(value)
36         return colValueList
37 
38     def getCellOfValue(self, sheetName, rowNo, colNo):
39         '''
40         获取某一个单元格的数据
41         :param sheetName:
42         :param rowNo:
43         :param colNo:
44         :return: 字符串
45         '''
46         sh = self.wb[sheetName]
47         value = sh.cell(rowNo, colNo).value
48         return value
49     def writeCell(self, sheetName, rowNo, colNo, value):
50         '''
51         向某个单元格写入数据
52         :param rowNo: 行号
53         :param colNo: 列号
54         :param value:
55         :return: 无
56         '''
57         sh = self.wb[sheetName]
58         sh.cell(rowNo, colNo).value = value
59         self.wb.save(testExcelValuePath)
60 if __name__=='__main__':
61     p = ParseExcel()
62     print(p.getRowValue('126account',2))
63     print(p.getColumnValue('126account',3))
64     print(p.getCellOfValue('126account', 2, 3))

8.在config目录下新建varConfig.py文件来存储一些目录信息和数据表对应的列号


 1 import os
 2 
 3 # print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 4 # 项目目录
 5 parentDirPath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 6 # init文件路径
 7 pageElementLocatorPath = parentDirPath+r'\config\PageElementLocator.ini'
 8 # excel文件路径
 9 testExcelValuePath = parentDirPath+r'\testData\126MailContact.xlsx'
10 # 日志文件存放路径
11 logPath = parentDirPath + r'\log'
12 
13 # 126username 表,每列对用的序号
14 account_userName = 2
15 account_passWord = 3
16 account_dataBook = 4
17 account_isExecute = 5
18 account_testResult = 6
19 
20 # 126联系人表,每列对应的序号
21 contact_contactName = 2
22 contact_contactMail = 3
23 contact_contactStar = 4
24 contact_contactPhone = 5
25 contact_contactComment = 6
26 contact_contactKeyWords = 7
27 contact_contactIsExcute = 8
28 contact_contactExcuteTime = 9
29 contact_contactTestResult = 10
30 
31 if __name__=='__main__':
32 
33     print(pageElementLocatorPath)
34     print(testExcelValuePath)
35     print(logPath)

9.所有的数据已经准备完全,我们可以编写用例了把?等等! 我们是不是要考虑把业务功能封装一下呢?这样也方便以后依赖这些功能的用例直接调用!新建目录appModules 此目录用来存放业务功能代码,目录下新建LoginAction.py 和 AddContact.py 文件


 1 # 封装登录方法
 2 
 3 from pageObjects.LoginPage import LoginPage
 4 class LoginAction(object):
 5     def __init__(self):
 6         pass
 7 
 8     @staticmethod #
 9     def login(driver, username, password):
10         '''
11         登录场景
12         :param driver:
13         :param username:
14         :param password:
15         :return:
16         '''
17         login = LoginPage(driver)
18         login.switchToFrame()
19         login.userNameObj().send_keys(username)
20         login.passwordObj().send_keys(password)
21         login.loginBtnObj().click()
22         login.switchToDefaultFrame()
23 
24 if __name__=='__main__':
25     from selenium import webdriver
26     driver = webdriver.Firefox()
27     driver.get('https://mail.126.com')
28     LoginAction.login(driver, 'linux', 'chao')

 1 from pageObjects.HomePage import HomePage
 2 from pageObjects.NewContact import AddContactPage
 3 from selenium.webdriver.support.wait import WebDriverWait
 4 from selenium.webdriver.support import expected_conditions as EC
 5 from util.ParseConfigurationFile import ParseConfigFile
 6 
 7 class NewContactPersonAction(object):
 8     def __init__(self):
 9         pass
10 
11     @staticmethod
12     def addressLink(driver):
13         '''
14         点击通讯录按钮
15         :param driver:
16         :return:
17         '''
18         homePage = HomePage(driver)
19         # 点击通讯录
20         homePage.addressLink().click()
21     @staticmethod
22     def addContact(driver, contactName, contactMail, isSatr, contactPhone, contactComment):
23         '''
24         添加联系人场景
25         :param driver:
26         :param contactName:
27         :param contactMail:
28         :param isSatr:
29         :param contactPhone:
30         :param contactComment:
31         :return:
32         '''
33         # 点击新建联系人
34         addContact = AddContactPage(driver)
35         # 调试的时候这边有时候会报错。点击不到[新建联系人]这个按钮,所以加了一个显示等待
36         by, locator = ParseConfigFile().getElementValue('126mail_addContactPage', 'addContactPage.newContact')
37         WebDriverWait(driver, 30).until(EC.element_to_be_clickable((by, locator)))
38         addContact.newContact().click()
39         if contactName:
40             # 非必填项
41             addContact.addName().send_keys(contactName)
42         # 必填项
43         addContact.addMail().send_keys(contactMail)
44         if isSatr == '是':
45             addContact.markStar().click()
46         if contactPhone:
47             addContact.addPhone().send_keys(contactPhone)
48         if contactComment:
49             addContact.addContent().send_keys(contactComment)
50         addContact.clickCommitBtn().click()
51 
52 if __name__=='__main__':
53     from appModules.LoginAction import LoginAction
54     import time
55     from selenium import webdriver
56     driver = webdriver.Firefox()
57     driver.get('https://mail.126.com')
58     time.sleep(5)
59     LoginAction.login(driver, 'linux', 'chao')
60     NewContactPersonAction.addressLink(driver)
61     NewContactPersonAction.addContact(driver, '','123456@qq.com', '是', '','')
62     time.sleep(5)
63     driver.quit()

10.我们的大体框架就已经搭建完成了,貌似还少了个执行日志,我们在util目录下新建log.py封装日志模块, 加入到我们想加入的任何地方(用例中我就加了几条,可以自己任意加在想加的位置)


 1 import logging
 2 import time
 3 from config.varCondig import *
 4 
 5 class Logger(object):
 6     '''
 7     封装的日志模块
 8     '''
 9     def __init__(self, logger, CmdLevel=logging.INFO, FileLevel=logging.INFO):
10         """
11 
12         :param logger:
13         :param CmdLevel:
14         :param FileLevel:
15         """
16         self.logger = logging.getLogger(logger)
17         self.logger.setLevel(logging.DEBUG)  # 设置日志输出的默认级别
18         # 日志输出格式
19         fmt = logging.Formatter('%(asctime)s - %(filename)s:[%(lineno)s] - [%(levelname)s] - %(message)s')
20         # 日志文件名称
21         # self.LogFileName = os.path.join(conf.log_path, "{0}.log.txt".format(time.strftime("%Y-%m-%d")))# %H_%M_%S
22         currTime = time.strftime("%Y-%m-%d")
23         self.LogFileName = logPath+r'\log'+currTime+'.txt'
24         # 设置控制台输出
25         # sh = logging.StreamHandler()
26         # sh.setFormatter(fmt)
27         # sh.setLevel(CmdLevel)# 日志级别
28 
29         # 设置文件输出
30         fh = logging.FileHandler(self.LogFileName)
31         fh.setFormatter(fmt)
32         fh.setLevel(FileLevel)# 日志级别
33 
34         # self.logger.addHandler(sh)
35         self.logger.addHandler(fh)
36 
37 if __name__ == '__main__':
38     logger = Logger("fox",CmdLevel=logging.DEBUG, FileLevel=logging.DEBUG)
39     logger.logger.debug("debug")
40     logger.logger.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error

11.目前为止我们的框架就算已经搭建完成了,接下来就是编写我们的测试用例了^_^,新建testCases目录存放测试用例,并新建TestMail126.py编写用例


 1 from selenium import webdriver
 2 import time
 3 from appModules.LoginAction import LoginAction
 4 from appModules.AddContact import NewContactPersonAction
 5 from config.varCondig import *
 6 from util.ParseExcel import ParseExcel
 7 from util.Log import Logger
 8 import logging
 9 import traceback
10 
11 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
12 p = ParseExcel()
13 sheetName = p.wb.sheetnames # 获取所有的sheetname 是个列表
14 
15 # print(sheetName)
16 def bDriver():
17     try:
18         driver = webdriver.Firefox()
19         driver.get('https://mail.126.com')
20         driver.implicitly_wait(30)
21     except Exception as e:
22         raise e
23     else:
24         return driver
25 
26 def testMailLogin(driver):
27     '''
28     测试用例
29     :return:
30     '''
31     # 是否执行列数据
32     isExcute = p.getColumnValue(sheetName=sheetName[0], colNo=account_isExecute)
33     # print(isExcute)
34     for idx,value in enumerate(isExcute[:]):
35         # print(idx, value) # 获取是否执行列数据列表的索引和数据
36         if value.lower() == 'y':
37             userRowValue = p.getRowValue(sheetName[0], idx+2) # 获取执行状态为y所在行的数据
38             userName = userRowValue[account_userName-2]
39             passWord = userRowValue[account_passWord-2]
40             # driver = bDriver()
41             # 登录
42             LoginAction.login(driver,userName, passWord)
43             time.sleep(10) # 足够的时间加载登录成功的页面
44             try:
45                 assert '通讯录' in driver.page_source
46             except Exception as e:
47                 log.logger.info('断言"通讯录"失败,错误信息{}'.format(traceback.format_exc()))
48                 p.writeCell(sheetName[0], idx + 2, account_testResult, 'failed')
49                 # raise e
50             else:
51                 log.logger.info('{},{}登录成功, 断言”通讯录“成功'.format(userName, passWord))
52                 p.writeCell(sheetName[0], idx + 2, account_testResult, 'pass')
53             # 获取联系人数据表中是否执行列的数据
54                 isExcute = p.getColumnValue(sheetName=sheetName[1], colNo=contact_contactIsExcute)
55                 for idx, value in enumerate(isExcute):
56                     if value.lower() == 'y':
57                         # 获取y表示行的数据
58                         contactPersonValue = p.getRowValue(sheetName[1], idx+2)
59                         # 获取添加联系人所需的数据
60                         # 联系人姓名
61                         contactPersonName = contactPersonValue[contact_contactName-2]
62                         # 联系人邮箱
63                         contactPersonMail = contactPersonValue[contact_contactMail-2]
64                         # 是否为星级联系人
65                         contactPersonStar = contactPersonValue[contact_contactStar-2]
66                         # 联系人手机号
67                         contactPersonPhone = contactPersonValue[contact_contactPhone-2]
68                         # 联系人备注
69                         contactPersonComment = contactPersonValue[contact_contactComment-2]
70                         # 验证页面包含的关键字
71                         contactAssert = contactPersonValue[contact_contactKeyWords-2]
72                         NewContactPersonAction.addressLink(driver)
73                         NewContactPersonAction.addContact(driver, contactPersonName, contactPersonMail
74                                                           , contactPersonStar, contactPersonPhone, contactPersonComment)
75                         try:
76                             assert contactAssert in driver.page_source
77                         except Exception as e:
78                             p.writeCell(sheetName[1], idx + 2, contact_contactTestResult, 'failed')
79                             raise e
80                         else:
81                             p.writeCell(sheetName[1], idx+2, contact_contactTestResult, 'pass')
82                         # 设置足够长的时间 让添加联系人成功后的提示框自动消失,当然可以自己写代码关闭
83                         time.sleep(10)
84             driver.quit()
85 
86 if __name__=='__main__':
87     driver = bDriver()
88     testMailLogin(driver)

12.用例编写完成,我们再来编写一个统一执行用例的入口文件,在项目根目录下新建RunTest.py

 1 '''
 2 用例执行入口
 3 '''
 4 
 5 import sys
 6 sys.path.append(r'.')
 7 
 8 if __name__=='__main__':
 9     from testCases.TestMail126 import *
10 
11     driver = bDriver()
12     testMailLogin(driver)

总结

以上就是整个数据驱动测试框架的完整代码,后续还会更新关键字驱动框架和混合测试框架的设计,大家敬请期待!

【整整200集】超超超详细的Python接口自动化测试进阶教程合集,真实模拟企业项目实战

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1031469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java 集合】常用的Java集合框架体系详解(134)

一、集合的体系 概述:java中存储对象数据的一种容器,集合只能存储引用类型的数据。用泛型来规定需要操作元素的数据类型,可以在编译阶段约束集合只能操作某种数据类型。集合分为两个家族 MAP和Collection 特点:大小不固定&#…

YOLOv8 YOLOv7 YOLOv5 训练 SCB-Dataset3-U

目录 0 相关资料1 SCB-Dataset3-U 数据2 YOLOv8 训练2.1 YOLOv8 安装2.2 训练的yaml文件2.3 YOLOv8 训练2.3.1 yolov8n 训练2.3.2 yolov8n 验证 0 相关资料 YOLOV8环境安装教程.:https://www.bilibili.com/video/BV1dG4y1c7dH/ YOLOV8保姆级教学视频:https://www.…

实施预测性维护解决方案的挑战及PreMaint的应对方法

前面我们介绍了企业选择预测性维护解决方案的常见问题和PreMaint的策略,本期我们将带来实施过程中可能会遇到的挑战,以及如何通过PreMaint来应对这些挑战,以实现可靠的预测性维护。 随着工业技术的不断进步,预测性维护作为一种先进…

【C语言】结构体内存对齐机制详解

目录 一、前言二、结构体内存对齐规则三、实例解析 一、前言 在讲解结构体内存对齐机制之前,我们先来看1个例子: typedef struct {char sex; // 性别int id; // 学号char name[20]; // 姓名float score; // 成绩char addr[30]; …

中秋特辑——3D动态礼盒贺卡(可监听鼠标移动)

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

华纳云:如何搭建Nginx服务器做到负载均衡

要搭建Nginx服务器实现负载均衡,您可以使用Nginx作为反向代理来分发客户端请求到多个后端服务器。以下是一个基本的步骤指南: 前提条件: 您需要一台安装有Nginx的服务器。您需要有多台后端服务器,这些服务器将处理客户端请求。 …

centos7 装机遇到的问题

centos7 U盘启动装机 设置完启动项后重启 在菜单界面选择install centos7 按e编辑启动项,修改成如下 --> 之所以这么改是u盘的LABEL超过长度了只能显示到x8这里,nomodeset 是disable 视频驱动比如gpu 开始安装后如果选择的硬盘没有多余的空间了会提…

TikTok的媒体革命:新闻业如何适应短视频时代?

在数字时代,媒体行业一直在不断演变和创新,以适应观众的变化需求和技术的发展。而在这个进化的过程中,短视频应用TikTok已经崭露头角,成为了一个重要的信息传播平台。 这篇文章将深入探讨TikTok如何引领了媒体的一场革命&#xf…

mininum_snap

位置 速度 加速度 角度 jerk 角速度 驱动力 snap 角加速度 推力的导数 凸优化算法 convex optimization 凸优化(Convex Optimization)是数学和计算机科学领域的一个重要分支,主要研究如何有效地解决凸优化问题。凸优化问题的主要目标是找…

pytest进阶之conftest.py

前言 前面几篇随笔基本上已经了解了pytest 命令使用,收集用例,finxture使用及作用范围,今天简单介绍一下conftest.py文件的作用和实际项目中如是使用此文件! 实例场景 首先们思考这样一个问题:如果我们在编写测试用…

AIMS医院手术麻醉信息系统全套源码,自主版权,开箱即用

手术麻醉临床信息系统有着完善的临床业务功能,能够涵盖整个围术期的工作,能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施,能够规范麻醉科的工作流程,实现麻醉手术过程的信息数字化,自动生成麻…

如何无损压缩视频?这些技巧你一定用得到

在日常生活中,我们常常会遇到视频文件过大、手机或电脑存储空间不足的情况。这时候,我们就需要将这些视频文件的内存进行压缩,以节省空间。但是,一个一个地压缩视频文件显然是不现实的。那么,如何快速批量压缩视频呢&a…

【马蹄集】—— 数论专题:筛法

数论专题 目录 MT2213 质数率MT2214 元素共鸣MT2215 小码哥的喜欢数MT2216 数的自我MT2217 数字游戏 MT2213 质数率 难度:黄金    时间限制:1秒    占用内存:256M 题目描述 请求出 [ 1 , n ] \left[1,n\right] [1,n] 范围内质数占比率。…

【word技巧】如何限制word页眉,不被他人修改

我们设置了页眉内容之后,不想其他人修改自己的页眉内容,我们可以设置加密的,设置方法如下: 先将页眉设置好,退出页眉设置之后,我们选择布局功能,点击分隔符 – 连续 设置完之后页面分为上下两节…

基于vue3 的 Echarts图表展示(任务一:用柱状图展示消费额最高的省份)(操作全流程)(图文版)

目录 前言: 操作要求: 操作流程: 一.创建vue项目 1.在vscode上创建vue脚手架工程 二.配置运行环境 2.配置axios(用于访问接口) 和引入echarts包 3.引入需要用到的js包 三.开始实践做题(最后附有完整代码) 1.获取接口数据 2.数据处理 …

博格华纳高压发卡式电机解析

博格华纳的高压发卡式电机具有功率强大、坚固耐用和高性能等特点,采用紧凑型设计,优化的导体绕组结构缩短了电机的尺寸,使其便于在更小的空间内进行安装,并提高了常用区间的工作效率。此外,电机在设计上减少了重稀土元…

Spring Cloud Alibaba Nacos 2.2.3 (4) - 本地源码编译 调试

下载nacos nacos在GitHub上有下载地址:https://github.com/alibaba/nacos/releases,可以选择任意版本下载。 我下载的是2.2.3 版本 导入idea mvn 安装包 1,切换到Terminal ,并且使用command prompt模式 2,执行 mvn -Prelease…

Delaunay三角剖分算法

目录 一. 简介1.1 三角剖分1.2 Delaunay三角剖分 二. Delaunay三角剖分的相关理论2.1 Delaunay三角形和(局部)Delaunay边的概念2.2 Delaunay引理2.3 翻转边算法(flip algorithm)2.4 Delaunay三角剖分的最优性质 三. Delaunay三角剖…

缺口的大利润!伦敦银如何使用缺口交易

在伦敦银市场中,我们经常能够看见市场跳空形成缺口,其实,如果利用得当,我们在伦敦银投之中,这些缺口是能够为我们创造盈利机会的,那么下面我们就来讨论一下在伦敦银投之中如何认识这些跳空缺口,…

哪些远程桌面软件适合与团队共享屏幕和文件

远程桌面软件是一种方便团队协作和共享工作的工具。它们能够允许用户通过互联网连接到其他计算机,实现远程访问、共享屏幕和文件、以及协同工作。以下是一些适合与团队共享屏幕和文件的常用远程桌面软件。 1、RayLink RayLink是一款功能强大且易于使用的远程桌面软…