前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DDT框架结合单元测试

DDT框架结合单元测试

作者头像
清菡
发布2020-12-02 16:46:00
9740
发布2020-12-02 16:46:00
举报
文章被收录于专栏:清菡软件测试清菡软件测试

文章总览图

  • Excel读写测试数据
  • python配置文件的类封装
  • DDT框架原理以及使用
  • DDT框架结合单元测试

读取数据的方式

方法一:一次性读取所有的数据,对内存的要求高点。

方法二:需要用的时候读取所有的数据,就是磁盘读写要求高点。

磁盘(速度最低)----》 内存(速度中间)---》 CPU(速度最高)

如果磁盘数据量大,一次性读取到内存,再读取到CPU,这样快点。每次启动磁盘读到内存再到CPU,CPU会等待磁盘读到数据,造成CPU资源的浪费。

方式一,方式二都ok,以后肯定是方法一。

方法三:使用DDT进行参数化。

Excel处理

Excel去处理测试数据,得到测试结果。把数据存到Excel里面去,通过Python去操作Excel。 openpyxl只支持.xlsx这种格式。

先创建一个xh.xlsx文件。

代码语言:javascript
复制
#来自文件do_excel_1.py

from openpyxl import load_workbook#打开工作簿

wb=load_workbook("xh.xlsx")

sheet=wb['python']


#错误演示1:res=sheet.cell(do,do)
# 只定位到单元格,并未取值。
#返回:<Cell 'python'.A1>

# res=sheet.cell(do,do).value
# print(res)
test_data=[]
for i in range(1,sheet.max_row+1):#取1-5之间的值,do,2,3,4
    sub_data={}
    method=sheet.cell(i,1).value
    sub_data['method']=method

    url=sheet.cell(i,2).value
    sub_data['url']=url

    data=sheet.cell(i,3).value
    sub_data['data']=data

    expected=sheet.cell(i,4).value
    sub_data['expected']=expected
    test_data.append(sub_data)
print(test_data)

运行结果如下:

代码语言:javascript
复制

#来自文件class_excel.py

from openpyxl import load_workbook

#do.打开Excel
wb=load_workbook("xh.xlsx")

#2.定位表单
sheet=wb['python']#传表单名,返回一个表单对象。

#3.定位单元格。根据行列值定位
res=sheet.cell(1,1).value#拿单元格里面的值用.value

print("最大行:{}".format(sheet.max_row))#求表单的最大行,有空行也算。
print("最大列:{}".format(sheet.max_column))#求表单的最大列,有空列也算
# print("拿到的结果是:",res)

#数据从Excel里面拿出来是什么类型?
#数字还是数字,其它都是字符串。
print("url:{},类型是{}".format(sheet.cell(1,1).value,type(sheet.cell(1,1).value)))
print("date:{},类型是{}".format(sheet.cell(1,2).value,type(sheet.cell(1,2).value)))
print("code:{},类型是{}".format(sheet.cell(1,3).value,type(sheet.cell(1,3).value)))
print("float:{},类型是{}".format(sheet.cell(1,4).value,type(sheet.cell(1,4).value)))
print("float:{},类型是{}".format(sheet.cell(1,5).value,type(sheet.cell(1,5).value)))


# 拓展:
#eval()只限于字符串的布尔值、字符串的元组、字符串的列表,字符串的数字转换成原本的数据类型。
# s='True'
# print(eval(s),type(eval(s)))
# 输出结果:
# True <class 'bool'>

# s='{"age":18}'
# print(s,type(s))
# 输出结果如下:
# {"age":18} <class 'str'>
# print(eval(s),type(eval(s)))
# 输出结果如下:
# {'age': 18} <class 'dict'>

输出结果如下:

三种方法读取数据

代码语言:javascript
复制
#来自文件http_request.py

import requests
class HttpRequest:
    '''利用request封装get请求和post请求'''

    def http_request(self,url,data,method,cookie=None):
        '''url:请求的地址 http://xxx:port
               param:传递的参数  非必填参数  字典的格式传递参数
               method:请求方式支持get以及post  字符串形式的参数
               cookie:请求的时候传递的cookie值'''
        if method.lower()=='get':
            res = requests.get(url, data, cookies=cookie)
        else:
            res=requests.post(url,data,cookies=cookie)#响应结果的消息实体 http response包含响应头,响应状态码,响应正文,Cookie
        return res#返回一个消息实体

if  __name__ =='__main__':
    url = 'http://v.juhe.cn/laohuangli/d'
    data =  {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
    res=HttpRequest().http_request(url,data,'post')
    print("登录结果是:", res.json())

#充值
    recharge_url='http://v.juhe.cn/laohuangli/d'
    recharge_data= {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
    recharges_res=HttpRequest().http_request(recharge_url,recharge_data,'get',res.cookies)
    print("充值结果是:",recharges_res.json())
代码语言:javascript
复制
#来自文件get_data.py

class GetData:
    Cookie=None#存储cookie,初始值为None
    

方法一

一次性读取所有的数据。

先桌面创建一个1.xlsx文件,填写进需要的数据,保存后复制进do_Excel文件夹中或者在Python代码文件夹的磁盘路径下创建.xlsx文件。注意:不可在Python中直接新建.xlsx文件。

代码语言:javascript
复制
#来自文件do_excel_1.py

from openpyxl import load_workbook#打开工作簿

class DoExcel:
    def __init__(self,file_name,sheet_name):
        self.file_name=file_name
        self.sheet_name=sheet_name
    def get_data(self):
        wb=load_workbook(self.file_name)
        sheet=wb[self.sheet_name]#错误点2:写成了字符串['self.sheet_name'],所以报错。
        test_data=[]
        for i in range(1,sheet.max_row+1):#取1-5之间的值,1,2,3,4
            sub_data={}
            sub_data['method']=sheet.cell(i,1).value
            sub_data['url']=sheet.cell(i,2).value
            sub_data['data']=sheet.cell(i,3).value
            sub_data['expected']=sheet.cell(i,4).value
            test_data.append(sub_data)
        return test_data#返回获取到的数据
if __name__ ==  '__main__':
    print(DoExcel("1.xlsx", "python").get_data())
代码语言:javascript
复制
#来自文件test_http_1.py

import unittest
from do_Excel.http_request import HttpRequest
from do_Excel.get_data import GetData


class TestHttp(unittest.TestCase):
    def setUp(self):
        pass

    # 数据给它参数化,通过初始化传参,实现参数化
    def __init__(self,methodName,url,data,method,expected):#通过初始化函数来传参数
        super(TestHttp,self).__init__(methodName)#父类的方法要保留,用的超继承。
        self.url=url
        self.data=data
        self.method=method
        self.expected=expected

    def test_api(self):#接口用例
            res=HttpRequest().http_request(self.url,self.data,self.method,getattr(GetData,'Cookie'))
            if res.cookies:#如果cookie有的话,就更新COOKIE
                  setattr(GetData,'Cookie',res.cookies)#反射
            try:
                self.assertEqual(self.expected,res.json()['reason'])
            except AssertionError as e:
                print("test_api's error is{}".format(e))
                raise e
            print(res.json())

    def tearDown(self):
        pass
代码语言:javascript
复制

#来自文件test_suite_1.py

import unittest
import HTMLTestRunner
from do_Excel.test_http_1 import TestHttp#类名
from do_Excel.do_excel_1 import  DoExcel

test_data=DoExcel("1.xlsx", "python").get_data()
suite=unittest.TestSuite()
#遍历数据
for item in  test_data:#创建实例
    suite.addTest(TestHttp("test_api",item['url'],eval(item['data']),item['method'],str(item['expected'])))
#实例的方式去加载用例url,data,method,expected


#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹do_Excel下已创建文件request.py,文件get_data.py,文件do_excel_1.py,文件test_http_1.py和文件test_suite_1.py,执行文件test_suite_1.py

输出结果如下:

方法二

需要用的时候读取所有的数据。

数据给它参数化,通过初始化传参,实现参数化。根据传入的坐标来获取值。实例的方式去加载用例url,data,method,expected。

#方法二

代码语言:javascript
复制
#来自文件do_excel_2.py

from openpyxl import load_workbook#打开工作簿

class DoExcel:
    def __init__(self,file_name,sheet_name):
        self.file_name=file_name
        self.sheet_name=sheet_name
        self.sheet_obj=load_workbook(self.file_name)[self.sheet_name]#打开了一个工作簿,再去拿到表单名,
        #在实例化里面拿到1个表单对象,把表单对象存在里面。
        self.max_row=self.sheet_obj.max_row

    def get_data(self,i,j):
        '''根据传入的坐标来获取值'''
        return self.sheet_obj.cell(i,j).value

if __name__ ==  '__main__':
    res=(DoExcel("xh.xlsx", "python").get_data(1,1))
    print(res)
    
代码语言:javascript
复制
#来自文件test_http_2.py

import unittest
from do_Excel.http_request import HttpRequest
from do_Excel.get_data import GetData


class TestHttp(unittest.TestCase):
   def setUp(self):
       print("开始测试啦")

   # 数据给它参数化,通过初始化传参,实现参数化
   def __init__(self,methodName,method,url,data,expected):#通过初始化函数来传参数
       super(TestHttp,self).__init__(methodName)#父类的方法要保留,用的超继承。
       self.url=url
       self.data=data
       self.method=method
       self.expected=expected

   def test_api(self):#接口用例
           res=HttpRequest().http_request(self.url,self.data,self.method,getattr(GetData,'Cookie'))
           if res.cookies:#如果cookie有的话,就更新COOKIE
                 setattr(GetData,'Cookie',res.cookies)#反射
           try:
               self.assertEqual(self.expected,res.json()['reason'])
           except AssertionError as e:
               print("test_api's error is{}".format(e))
               raise e
           print(res.json())

   def tearDown(self):
       pass
代码语言:javascript
复制
#来自文件test_suite_2.py

#方法二
import unittest
import HTMLTestRunner
from do_Excel.test_http_2 import TestHttp#类名
from do_Excel.do_excel_2 import  DoExcel

test_data=DoExcel("1.xlsx", "python")
t=DoExcel('1.xlsx','python')
suite=unittest.TestSuite()
for i in range(1,t.max_row+1):
    suite.addTest(TestHttp("test_api",t.get_data(i,1),t.get_data(i,2),eval(t.get_data(i,3)),str(t.get_data(i,4))))
    #实例的方式去加载用例url,data,method,expected

#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹do_Excel下已创建文件request.py,get_data.py,文件do_excel_2.py,文件test_http_2.py和文件test_suite_2.py,执行文件test_suite_2.py

输出结果如下:

方法三

根据嵌套循环读取数据。使用DDT进行参数化。

创建文件xh.xlsx文件:

代码语言:javascript
复制
#来自文件do_excel_3.py

#方法3:仅供参考,日后可以拿来优化。
from openpyxl import load_workbook#打开工作簿

class DoExcel:
    def __init__(self,file_name,sheet_name):
        self.file_name=file_name
        self.sheet_name=sheet_name

    def get_header(self):
        '''获取第一行的标题行'''
        wb = load_workbook(self.file_name)
        sheet = wb[self.sheet_name]
        header=[]#存储我们的标题行
        for j in range(1,sheet.max_column+1):
            header.append(sheet.cell(1,j).value)
        return header

    def get_data(self):
        '''根据嵌套循环读取数据'''
        wb=load_workbook(self.file_name)
        sheet=wb[self.sheet_name]
        header=self.get_header()#拿到header,是一个列表。索引是从0开始的。
        print("header:",header)
        test_data=[]
        for i in range(2,sheet.max_row+1):#取1-5之间的值,1,2,3,4
            sub_data={}
            for j in range(1,sheet.max_column+1):#1 2 3 4 5 6 7
                sub_data[header[j-1]]=sheet.cell(i,j).value
            test_data.append(sub_data)
        return test_data#返回获取到的数据

if __name__ ==  '__main__':
    print(DoExcel("xh.xlsx", "python").get_data())

DDT

DDT是一个处理数据的模型。

安装ddt:打开cmd输入pip install ddt

pip install openpyxl

ddt+unittest来进行数据的处理的第三方库。有了它,不需要做超继承了,它会自动的把数据进行拆分。

代码语言:javascript
复制
#来自文件test_http_canshuhua.py

#参数化,实现用例的可配置。
import unittest
from ddt import ddt,data
from do_Excel.http_request import HttpRequest
from do_Excel.get_data import GetData
from do_Excel.do_excel_canshuhua import DoExcel

test_data=DoExcel('xh.xlsx','python').get_data([1,3])

@ddt
class TestHttp(unittest.TestCase):
    def setUp(self):
        print("开始测试啦")

    @data(*test_data)
    def test_api(self,item):#接口用例
            res=HttpRequest().http_request(item['url'],eval(item['data']),item['method'],getattr(GetData,'Cookie'))
            if res.cookies:#如果cookie有的话,就更新COOKIE
                  setattr(GetData,'Cookie',res.cookies)#反射
            try:
                self.assertEqual(str(item['expected']),res.json()['reason'])
            except AssertionError as e:
                print("test_api's error is{}".format(e))
                raise e
            print(res.json())

    def tearDown(self):
        pass

文件夹do_Excel下已创建文件request.py,文件get_data.py,文件do_excel_3.py,文件test_http_canshuhua.py,执行文件test_http_canshuhua.py

输出结果如下:

代码语言:javascript
复制
# 来自文件do_excel_4.py

from openpyxl import load_workbook#打开工作簿

class DoExcel:
    def __init__(self,file_name,sheet_name):
        self.file_name=file_name
        self.sheet_name=sheet_name
    def get_data(self):
        wb=load_workbook(self.file_name)
        sheet=wb[self.sheet_name]#错误点2:写成了字符串['self.sheet_name'],所以报错。
        test_data=[]
        for i in range(2,sheet.max_row+1):
            sub_data={}
            sub_data['method']=sheet.cell(i,4).value
            sub_data['url']=sheet.cell(i,5).value
            sub_data['data']=sheet.cell(i,6).value
            sub_data['expected']=sheet.cell(i,7).value
            test_data.append(sub_data)
        return test_data#返回获取到的数据
if __name__ ==  '__main__':
    print(DoExcel("xh.xlsx", "python").get_data())

代码语言:javascript
复制
#来自文件test_http_4.py

import unittest
from ddt import ddt,data
from do_Excel.http_request import HttpRequest
from do_Excel.get_data import GetData
from do_Excel.do_excel_4 import DoExcel

test_data=DoExcel("xh.xlsx", "python").get_data()

@ddt
class TestHttp(unittest.TestCase):
    def setUp(self):
        print("开始测试啦")

    @data(*test_data)
    def test_api(self,item):#接口用例
            res=HttpRequest().http_request(item['url'],eval(item['data']),item['method'],getattr(GetData,'Cookie'))
            if res.cookies:#如果cookie有的话,就更新COOKIE
                  setattr(GetData,'Cookie',res.cookies)#反射
            try:
                self.assertEqual(str(item['expected']),res.json()['reason'])
            except AssertionError as e:
                print("test_api's error is{}".format(e))
                raise e
            print(res.json())

    def tearDown(self):
        pass
代码语言:javascript
复制
#来自文件test_suite_4.py

import unittest
import HTMLTestRunner
from do_Excel.test_http_4 import TestHttp#类名
from do_Excel.do_excel_4 import  DoExcel

#DDT loader
loader=unittest.TestLoader()
suite=unittest.TestSuite()
suite.addTest(loader.loadTestsFromTestCase(TestHttp))
#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹do_Excel下已创建文件request.py,文件get_data.py,文件do_excel_4.py,文件test_http_4.py和文件test_suite_4,执行文件test_suite_4.py

输出结果如下:

脱外套

代码语言:javascript
复制
def print_msg(*args):
    print(args)

t=[1,4]
#输出结果:[1, 4]
# print(t)
#脱外套
print(*t)
#输出结果:1 4

用unpack

ddt+unittest来进行数据的处理的第三方库。有了它,不需要做超继承了,它会自动的把数据进行拆分。

装饰器:会在你的函数运行之前运行,不会改变你代码的结构。例如@staticMethod就是装饰器。

@ddt装饰测试类。

@data(*test_data)装饰测试方法,拿到几个数据就执行几条用例。

@unpack拿到数据根据逗号进行拆分,如果unpack后的参数少于5个,推荐用unpack。

代码语言:javascript
复制
#来自文件class_ddt_unpack.py

import unittest
from ddt import ddt,data,unpack

test_data=[[1,3],[4,5,8]]#--->[do,3],[4,5,7]#--->[do,3]---->do 3要用2个参数来接收
                                             #--->[4,5,7]--->4 5 7要用3个参数来接收

@ddt#装饰测试类
class TestMath(unittest.TestCase):#测试用例

    @data(*test_data)#装饰测试方法,拿到几个数据就执行几条用例。
    @unpack  # 拿到数据根据逗号进行拆分,如果unpack后的参数少于5个,推荐用unpack。
    # 要注意参数不对等的情况,提供对应个数的参数来接收变量。
    def test_add(self,a=None,b=None,c=None):#参数要一一对应
        print("a",a)
        print("b",b)
        print('c',c)
        '''
        输出结果如下:
        a do
        b 3
        c None
        a 4
        b 5
        c 8
        '''
    # def test_add(self):
        # a=10
        # b=20
        # print(a+b)

#@data(test_data)不加*,是一条用例,执行1次。输出结果:item [do, 3]。加了*,@data(*test_data),
#就脱1层外套变成两个数据,运行两次,两条用例。
#输出结果:item do
#         item 3
#鼠标要放在最后面空白处进行运行。

@data(test_data)不加*,是一条用例,执行1次。输出结果:item [do, 3]。加了*,@data(*test_data),就脱1层外套变成两个数据,运行两次,两条用例。

直接运行文件class_ddt_unpack.py

输出结果如下:

不用unpack

代码语言:javascript
复制

#来自文件class_ddt_no_unpack.py

import unittest
from ddt import ddt,data,unpack

test_data=[[1,3],[4,5,8,9,10,11,12,13,14,15,16,17,18,19]]

@ddt#装饰测试类
class TestMath(unittest.TestCase):#测试用例

    @data(*test_data)#装饰测试方法,拿到几个数据就执行几条用例。
    def test_add(self,a):
        print("a",a[1])

直接运行文件class_ddt_unpack.py

输出结果如下:

列表嵌套字典,对字典进行unpack

代码语言:javascript
复制
#来自文件liebiaoqiantaozidian_3.py

#列表嵌套字典
import unittest
from ddt import ddt,data,unpack
#列表里面嵌套了一个字典。
test_data=[{"no":1,"name":"稳当"},{"no":2,"name":"小黄"}]

@ddt#装饰测试类
class TestMath(unittest.TestCase):#测试用例
    @unpack
    @data(*test_data)#装饰测试方法,拿到几个数据就执行几条用例。
#如果要对字典进行unpack的话,参数名与你的字典key对应
    def test_add(self,no,name):
        print("no",no)
        print("name", name)
#直接run就行

直接运行文件liebiaoqiantaozidian_3.py

输出结果如下:

配置文件

实现用例的可配置:改一个参数就可以执行指定的用例。

properties config ini log4j 以这些结尾的都是不同的配置文件,里面有不同的参数。你改一下,代码就会以不同的方式执行。

数据库的文件就会写在这样结尾的配置文件中,万一我的项目变了,不需要去改代码,改配置文件就行了。

Python里面有个configparser模块,可以去读取配置文件里的信息。

配置文件中,不同的区域,表示要记不同的数据。片段只能用中括号[PYTHON11]

配置文件里的值分为3个区域,section,option,value组成,第一个section,叫做片段。配置文件的有些值需要分开存储的,不能放在一个地方混淆了。

同1类数据存储在同1类片段里面,片段名要大写,必须中括号括起来。option是选项,等号左侧那一栏都是option。等号右侧那一栏都是value。

option value相当于字典里的key:value一样。

configparser模块里面的ConfigParser实现用例的可配置。

单个片段

先在python里创建配置文件case.config

代码语言:javascript
复制

import configparser
cf=configparser.ConfigParser()
cf.read('case.config',encoding='utf-8')

#读取配置文件的数据
#第一种读值方式:
res_1=cf.get('QINGHAN','age')#get获取到数据。
print(res_1)

#第二种读值方式:
res_2=cf['MODE']['mode']
print(res_2)

先在python里创建配置文件case.config,再运行文件class_peizhiwenjian_dangepianduan.py

输出结果如下:

数据类型

代码语言:javascript
复制
#来自文件class_peizhiwenjian_shujuleixing.py

import configparser

cf=configparser.ConfigParser()
cf.read('case.config',encoding='utf-8')
#根据数据类型讨论的问题
print(type(cf.get('PYTHON11','num')))
print(type(cf.get('PYTHON11','name')))
#不管是数字还是其它数据类型,它到了配置文件里面都变成了字符串。

先在python里创建配置文件case.config,再运行class_peizhiwenjian_shujuleixing.py

输出结果如下:

所有片段

代码语言:javascript
复制
#来自文件class_peizhiwenjian_suoyoupianduan.py

import configparser
cf=configparser.ConfigParser()
cf.read('case.config',encoding='utf-8')

#读取配置文件的数据
print(cf.sections())#拿到所有的片段
print(cf.items('PYTHON11'))#根据你指定的片段拿到所有的items

先在python里创建配置文件case.config。

再运行文件 class_peizhiwenjian_suoyoupianduan.py

输出结果如下:

DDT跟unittest的结合使用+excel结合使用详细讲解

总结:两种unittest+excel

1)超继承 2)ddt

1.自己先写个类

2.unittest 进行单元测试,通过单元测试实现对自己写的类的测试。

3.Testcase里面写用例,断言self.assert,异常处理。

4.单元测试后进行参数化:

用例的相似度达到80%以上可以进行参数化,可以把数据写在代码里面,也可以把数据写在Excel里面。

在Excel里面需要用到openpyxl进行处理,处理数据的话用到三种方式。写成类:方法一,方法二,方法三。

参数化的方式有2种:超继承和DDT。推荐使用DDT。

先创建配置文件case1.config:

创建文件xh.xlsx文件:

代码语言:javascript
复制
#来自文件http_request.py

import requests
class HttpRequest:
    '''利用request封装get请求和post请求'''

    def http_request(self,url,data,method,cookie=None):
        '''url:请求的地址 http://xxx:port
               param:传递的参数  非必填参数  字典的格式传递参数
               method:请求方式支持get以及post  字符串形式的参数
               cookie:请求的时候传递的cookie值'''
        if method.lower()=='get':
            res = requests.get(url, data, cookies=cookie)
        else:
            res=requests.post(url,data,cookies=cookie)#响应结果的消息实体 http response包含响应头,响应状态码,响应正文,Cookie
        return res#返回一个消息实体

if  __name__ =='__main__':
    url = 'http://v.juhe.cn/laohuangli/d'
    data =  {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
    res=HttpRequest().http_request(url,data,'post')
    print("登录结果是:", res.json())

#充值
    recharge_url='http://v.juhe.cn/laohuangli/d'
    recharge_data= {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
    recharges_res=HttpRequest().http_request(recharge_url,recharge_data,'get',res.cookies)
    print("充值结果是:",recharges_res.json())
代码语言:javascript
复制
#来自文件get_data.py

class GetData:
    Cookie=None#存储cookie,初始值为None
代码语言:javascript
复制
#来自文件read_config.py

#类 参数化 excel  执行指定的用例。
import configparser

class ReadConfig:
    def read_config(self,file_name,section,option):
        cf=configparser.ConfigParser()
        cf.read(file_name,encoding='utf-8')
        return cf.get(section,option)

if __name__ == '__main__':
    res=ReadConfig().read_config('case1.config','MODE','mode')
    print(res)

代码语言:javascript
复制
#来自文件do_excel_1

#参数化,实现用例的可配置。
from openpyxl import load_workbook#打开工作簿
from do_config.read_config import ReadConfig
class DoExcel:
    def __init__(self,file_name,sheet_name):
        self.file_name=file_name
        self.sheet_name=sheet_name

    def get_data(self):
#从配置文件读取mode值
        mode=ReadConfig().read_config('case1.config','MODE','mode')

        wb=load_workbook(self.file_name)
        sheet=wb[self.sheet_name]#错误点2:写成了字符串['self.sheet_name'],所以报错。
        test_data=[]
        for i in range(2,sheet.max_row+1):
            sub_data={}
            sub_data['case_id'] = sheet.cell(i, 1).value
            sub_data['module'] = sheet.cell(i, 2).value
            sub_data['title'] = sheet.cell(i, 3).value
            sub_data['method'] = sheet.cell(i, 4).value
            sub_data['url']=sheet.cell(i,5).value
            sub_data['data']=sheet.cell(i,6).value
            sub_data['expected']=sheet.cell(i,7).value
            test_data.append(sub_data)#存储了所有的数据。

         #根据mode值去进行判断
        if mode=='all':#执行所有的用例
            final_data=test_data
        else:#[do,2,3,4]传递列表,可以根据序号来执行所有的用例。
            final_data=[]
            for item in test_data:#对test_data所有的测试数据进行遍历
                if item['case_id'] in eval(mode):
                    final_data.append(item)


        return final_data#返回获取到的数据

if __name__ ==  '__main__':
    print(DoExcel("xh.xlsx", "python").get_data())

代码语言:javascript
复制
#来自文件test_http_1.py
#写用例写预期和断言
import unittest
from ddt import ddt,data
from do_config.http_request import HttpRequest
from do_config.get_data import GetData
from do_config.do_excel_1 import DoExcel

test_data=DoExcel("xh.xlsx", "python").get_data()

@ddt
class TestHttp(unittest.TestCase):
    def setUp(self):
        print("开始测试啦")

    @data(*test_data)
    def test_api(self,item):#接口用例
            res=HttpRequest().http_request(item['url'],eval(item['data']),item['method'],getattr(GetData,'Cookie'))
            if res.cookies:#如果cookie有的话,就更新COOKIE
                  setattr(GetData,'Cookie',res.cookies)#反射
            try:
                self.assertEqual(str(item['expected']),res.json()['reason'])
            except AssertionError as e:
                print("test_api's error is{}".format(e))
                raise e
            print(res.json())

    def tearDown(self):
        pass



代码语言:javascript
复制
#来自文件test_suite_1.py

#执行用例
import unittest
import HTMLTestRunner
from do_config.test_http_1 import TestHttp#类名
from do_config.do_excel_1 import  DoExcel

#DDT loader
loader=unittest.TestLoader()
suite=unittest.TestSuite()
suite.addTest(loader.loadTestsFromTestCase(TestHttp))
#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title=None,description=None,tester="清菡")
    runner.run(suite)

代码语言:javascript
复制
#来自文件test_suite_1.py

#执行用例
import unittest
import HTMLTestRunner
from do_config.test_http_1 import TestHttp#类名
from do_config.do_excel_1 import  DoExcel

#DDT loader
loader=unittest.TestLoader()
suite=unittest.TestSuite()
suite.addTest(loader.loadTestsFromTestCase(TestHttp))
#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title=None,description=None,tester="清菡")
    runner.run(suite)

do_config文件夹下已创建文件get_data.py,文件http_request.py,文件read_config.py,文件do_excel_1.py,文件test_http_1.py,文件test_suite_1.py,xh.xlsx文件,case1.config文件,运行文件test_suite_1.py

输出结果如下:

补充

不能以Python中的模块名命名文件名,例如requests。它找文件的时候会在当前的环境变量下找,找不到的时候才会在配置的环境变量下的lib下找。

拓展:eval()只限于字符串的布尔值、字符串的元组、字符串的列表,字符串的数字转换成原本的数据类型。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 清菡软件测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章总览图
    • 读取数据的方式
      • Excel处理
    • 三种方法读取数据
      • 方法一
      • 方法二
    • 方法三
      • DDT
        • 脱外套
          • 用unpack
            • 装饰器:会在你的函数运行之前运行,不会改变你代码的结构。例如@staticMethod就是装饰器。
          • 不用unpack
            • 列表嵌套字典,对字典进行unpack
              • 配置文件
                • 单个片段
                • 数据类型
                • 所有片段
              • DDT跟unittest的结合使用+excel结合使用详细讲解
                • 补充
                相关产品与服务
                数据保险箱
                数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档