前言:
前面简单分享了数据驱动与Unittest的简单使用,这篇将分享结合数据文件的数据驱动。
安装pandas,ddt,selenium,Unittest模块,csv模块为Python内置模块,直接导入即可。
一、Python内置CVS模块与数据驱动
cvs读取数据文件是从首行开始读取,从左至右依次读取,所以后面的解包数据也是一样,需要根据csv文件的列名,依次加入形参列表,方便后面写入文件。如下图,若表内的多个数据需要参与函数执行,需要写入后面的相关形参名(注意:形参是按列过来的,不是一样的名字到处换位)
csv文件写入不像excel写入那么灵活,目前本人没有探索到能够指定csv文件中的某个单元格写入数据。一写就是整行或者整列数据,所以一般都是在一个新表里面进行追加。
(一)csv读取据文件
import csv
#定义一个空列表用于接收从文件中读取的数据
value_data=[]
#csv读写文件需要先打开文件,打开的文件在使用结束后需要使用close方法关闭
file=open('CVS数据表.csv','r')
#使用reader方法读取文件
csv_data=csv.reader(file)
#循环追加内容进列表
for value in csv_data:
print(value)
value_data.append(value)
file.close()
print(value_data)
上面的内容如果用于实际使用中,需要进行改造:
import csv
#将其定义成一个函数,方便后续使用调用
def get_csv(filename):
value_data=[]
file=open(filename,'r')
csv_data=csv.reader(file)
for value in csv_data:
value_data.append(value)
file.close()
return value_data
print(get_csv('CVS数据表.csv'))
(二)写入数据
使用以下代码时需要自己准备一个名为:CVS数据表2.csv的数据文件,并在首行加入表头
import csv
def writer_csv(filename,name,result):
#由于代码用于循环,一般使用追加模式(a),如果使用(w)写模式,那么会覆盖掉表里面的数据。
#newline=''是用于避免加入一条数据之后产生空行
file=open(filename,'a',newline='')
csv_data=csv.writer(file)
#writerow方法只能接收一个参数,如果像下面有多个列的数据,一般用[]包裹,转为一个列表。
#下面代码每次只能写入一行,如果想一次写入多行,需要writerows方法
#多行示例:writerows([[name,result],[name,result]])
csv_data.writerow([name,result])
file.close()
writer_csv('CVS数据表2.csv','孔子','pass')
结果:
(三)结合数据文件与数据驱动的实例
from selenium import webdriver
import unittest,time,csv
from ddt import ddt,data,unpack
#下面这段函数与search_data后面的内容就是与没有使用数据文件的的区别
def get_csv(filename):
value_data=[]
file=open(filename,'r')
csv_data=csv.reader(file)
for value in csv_data:
value_data.append(value)
file.close()
return value_data
search_data=get_csv('CVS数据表.csv')
#使用装饰器,表明该测试集采用ddt驱动
@ddt
#使用unittest必须先使用class定义一个类,且以Test开头,并继承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
# 必须使用@classmethod装饰器,这是使用tearDownClass与setUpClass的基本要求
#setUpClass表示下面的代码Testbaidu_search测试集只会在开始时运行一次
@classmethod
def setUpClass(cls) -> None:
global driver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')
#data取数据
# @data(['孔子'],['孟子'],['庄子'])
#如果传入的是一个变量接收的数据集,那么需要在变量前面加*
@data(*search_data)
#unpack解压数据包
@unpack
#由于只有一个变量,在测试用例用中,加入一个变量名,用于接收解压到的数据,针对多个的情况后面再详细说明
def test_search(self,value):
driver.find_element_by_id('kw').send_keys(value)
driver.find_element_by_id('su').click()
time.sleep(3)
driver.find_element_by_id('kw').clear()
@classmethod
# tearDownClass表示下面的代码Testbaidu_search测试集只会在结束时运行一次
def tearDownClass(cls) -> None:
driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)
二、Python pandas模块读写csv文件与数据驱动
(一)读取数据文件
pandas读取csv数据之后需要一点处理,不然得到的结果我们没法用在数据驱动里面
def read_csv(filename,col_name):
#为了方便以后使用,直接在函数中导入模块
import pandas as pd
csv_data=pd.read_csv(filename,encoding='utf-8')
#这个取数据就像字典格式一样,同时下面使用了Python内置的list函数,将数据转为列表格式。如果不转,那么我们后续没法用这段代码。
#参考:[https://blog.csdn.net/hei653779919/article/details/106885286](https://blog.csdn.net/hei653779919/article/details/106885286)
result=list(csv_data[col_name])
return result
#注意,我的csv文件中有一列名称(首行)叫name,如果你的没有这个,就需要根据自己的列名来改
print(read_csv('CVS数据表2.csv',col_name='name'))
结果:['孔子', '孟子', '庄子']
(二)写入数据文件
def writer_csv(filename,name,result):
#简单测试输入框,只有两个字段,一个是输入内容,一个接收结果
data_dic = {
'name': name,
'result': result
}
#index=[0]必须写,不然会报错,我目前是这样的
csv_data = pd.DataFrame(data=data_dic, index=[0])
#mode='a'为追加模式,这种不停写入旧文件一般都用追加,不会覆盖原来的内容
# header=False,不会在写入数据时添加首行标题,否则结果看起来会很乱
csv_data.to_csv(filename, mode='a', index=False,header=False,encoding='utf-8')
(三)综合实例
from selenium import webdriver
import unittest,time,csv
from ddt import ddt,data,unpack
#下面这段函数与search_data后面的内容就是与没有使用数据文件的的区别
def read_csv(filename,col_name):
#如果将这些函数都放入一个py文件中,那么在开头导入一次即可
import pandas as pd
csv_data=pd.read_csv(filename,encoding='utf-8')
result=list(csv_data[col_name])
return result
def writer_csv(filename,name,result):
import pandas as pd
#简单测试输入框,只有两个字段,一个是输入内容,一个接收结果
data_dic = {
'name': name,
'result': result
}
#index=[0]必须写,不然会报错,我目前是这样的
csv_data = pd.DataFrame(data=data_dic, index=[0])
#mode='a'为追加模式,这种不停写入旧文件一般都用追加,不会覆盖原来的内容
# header=False,不会在写入数据时添加首行标题,否则结果看起来会很乱
csv_data.to_csv(filename, mode='a', index=False,header=False,encoding='utf-8')
search_data=read_csv('CVS数据表.csv',col_name='name')
print(search_data)
#使用装饰器,表明该测试集采用ddt驱动
@ddt
#使用unittest必须先使用class定义一个类,且以Test开头,并继承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
# 必须使用@classmethod装饰器,这是使用tearDownClass与setUpClass的基本要求
#setUpClass表示下面的代码Testbaidu_search测试集只会在开始时运行一次
@classmethod
def setUpClass(cls) -> None:
global driver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')
#data取数据
#如果传入的是一个变量接收的数据集,那么需要在变量前面加*
@data(*search_data)
#@unpack,由于的是一个单纯的列表,里面没有嵌套数据,所以不需要使用unpack二次解包,只需要使用@data(*search_data)一次解包即可
#由于只有一个变量,在测试用例用中,加入一个变量名,用于接收解压到的数据,针对多个的情况后面再详细说明
def test_search(self,value):
driver.find_element_by_id('kw').send_keys(value)
text=driver.find_element_by_id('kw').get_attribute('value')
driver.find_element_by_id('su').click()
time.sleep(3)
driver.find_element_by_id('kw').clear()
#这个列表里面没有加庄子,是为了看结果的的区别
if text in ['孔子','孟子']:
writer_csv('CVS数据表2.csv',value,'pass')
else:
writer_csv('CVS数据表2.csv', value, 'unpass')
@classmethod
# tearDownClass表示下面的代码Testbaidu_search测试集只会在结束时运行一次
def tearDownClass(cls) -> None:
driver.quit()
if __name__ == '__main__':
注意:我的python最近不知道怎么了,需要经常在utf-8与gbk编码之间切换,不然会乱码。如果你也出现,请注意点,修改编码格式即可。
分享是一种快乐,也是一种进步,希望看到文章的你也能持续分享!