肖sir__接口自动化python+request+ddt(模版)

接口自动化python+request+ddt

接口自动化讲解:

新建一项目:命名:dcs

首先我们先新建7个包:如下图

 =========================================================================

首先在conf包下新建一个ini文件,命名 cms_conf.ini

 

ini 文件的格式(节点 下面:键=值)  节点就是:section      键值:option

如下图:

[env]    #环境
url = http://cms.duoceshi.cn #域名
headers = {"Content-Type":"application/x-www-form-urlencoded"} #请求头
[test_data] #测试数据
username = admin #账号
pwd = 123456 #密码
[db] #数据库
[email] #邮件

  =========================================================================

第二文件utils文件中就是要讲整个项目包的路径进行整理:

我们可以命名:headle_path  将7个文件的都写在这个文件中

导入os模块

import os

# 定义项目的路径
# 获取当前运行脚本的绝对路径
base_path = os.path.dirname(os.path.dirname(__file__))
#os.path.dirname(os.path.dirname(__file__)) 是一个常见的 Python 表达式,用于获取当前文件所在的目录的父目录

os.path.dirname(__file__): 这行代码的作用是获取当前文件(即执行该代码的文件)的目录。__file__ 是一个内置变量,它表示当前文件的路径。os.path.dirname() 是一个函数,它将路径解析为目录。
os.path.dirname(os.path.dirname(__file__)): 这行代码的作用是获取上一步返回的目录的父目录。即,它获取当前文件所在的目录的父目录。

# print(base_path)
# 定义conf的路径
conf_path = os.path.join(base_path,'conf') #os.path.join 是 Python 的一个内置函数,用于连接路径
# 定义data的路径
data_path = os.path.join(base_path,'data')
# 定义report路径
report_path = os.path.join(base_path,'report')
#定义library路径
library_path = os.path.join(base_path,'library')
#定义run路径
run_path = os.path.join(base_path,'run')
#定义utils路径
utils_path = os.path.join(base_path,'utils')
#定义testcase路径
testcase_path = os.path.join(base_path,'testcase')

   =========================================================================

第三步就是我们将接口用例编写  存放在 data  包中 ,以xlsx文件格式

点击data包右键,new  ,show  in  explorer  显示data路径,在路径中新建一个apicase.xlsx 文件

 

 一个接口一个sheet页面,一条正确的用例,多条异常用例

 

注意点:

1、在执行的过程一定要关闭xlsx文档,

思考点1:接口用例改成中文,能读取吗?(忽略)

 

 ====================================================================

下载:pip install configparser

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
不管是ini文件,还是xlsx文件都要能够去读取文件:
 
在utils 包下新建handle_conf.py 文件
 
在读取ini 文件要用到  ConfigParser 模块 ,我们需要pip  install  ConfigParser   #参考连接:https://blog.csdn.net/m0_47403059/article/details/133915993
 
from configparser import ConfigParser  #导入configparser这个模块并导入ConfigParser类
from utils.handle_path import * #导入工具类中定义得路径
import os
class Handle_conf(ConfigParser): #定义了一个名为Handle_conf的新类,它继承自ConfigParser类: #这意味着Handle_conf类将具有ConfigParser类的所有功能和属性
    '''
    当前这个类是用来处理conf.ini文件的工具类
    '''
    def __init__(self,filename):  #构造一个初始化函数#当创建一个Handle_conf类的实例时,这个函数会被调用。#当创建一个Handle_conf类的实例时,这个函数会被调用。
        super(Handle_conf,self).__init__()  #继承父类的构造方法
#这行代码调用父类ConfigParser的构造函数。这是在子类中重写父类的构造函数时常见的做法,以确保父类的初始化逻辑被正确执行
#我们可以引用:super()函数是一个内置函数,用于调用父类的方法或属性。在类定义中,如果子类重写了父类的方法或属性,但是仍然需要调用父类的方法或属性,就可以使用super()函数来实现。
#super(Handle_conf, self).__init__()这行代码的含义是:调用Handle_conf类的父类的__init__()方法,并且将self对象作为第一个参数传递给这个方法。
其中,Handle_conf是当前类名,self是当前对象。
#为什么要使用super()函数呢?这是因为当子类重写父类的方法时,如果不使用super()函数调用父类的方法,那么父类的方法就会被覆盖掉,导致一些继承自父类的属性或方法无法被正确地初始化或调用。
        self.filename = filename  #把传进来的形式参数赋值给到实例变量self.filename
是将传入的参数(一个文件名)赋值给实例变量self.filename。这意味着这个类将用这个文件名指定的文件来初始化自己。
        self.read(self.filename)  #打开ini文件进行读取
调用ConfigParser类的read方法来读取和解析指定的.ini文件。这意味着当你创建一个Handle_conf实例时,它将自动读取与filename参数指定的文件名对应的.ini文件
    def get_value(self,section,option): #定义在此类中的方法,用于获取.ini文件中的特定section下的特定option的值。
        '''
        获取ini文件中的section下面对应的option的value值
        '''
        value = self.get(section,option)  #调用ConfigParser类的get方法,获取指定的section和option的值,并将其赋值给变量value。
        return value # 从方法中返回获取到的值
path = os.path.join(conf_path,'conf.ini'#获取我们要读取得ini文件路径
conf =Handle_conf(path)  #创建类得对象,path是传入的文件
#print(conf.get_value('env','url'))    #调试下查看的 url
#print(conf.get_value('env','headers'))  #调试下查看的 headers

  

 ====================================================================

 

 

然后在新建utils 包下得 handle_excel.py 包,用来它用于读取和写入Excel电子表格

我们要运用openpyxl 这个库首先下载 openpyxl模块如下:

pip  install   openpyxl   

filename
sheet_name
self.filename 实例变量
self.sheet_name  实例变量
    def open(self): #定义一个打开的函数 命名为:open
'''封装一个打开Excel表格的工具方法'''
#通过openpyxl模块调用load_workbook函数打开filename文件
self.wb = openpyxl.load_workbook(self.filename)
# 通过self.wb这个Excel文件的对象读取对应的sheet页面的
self.sh = self.wb[self.sheet_name]

def read_data(self): #封装read_data方法,读取Excel表格中的数据
'''封装了一个读取Excel表格的工具方法'''
self.open() #我们调用open方法,打开Excel表格,

#获取表格中的每一行的数据放在元组当中,都要当作键,存储
datas = list(self.sh.rows) #把每一行的元素数据放在list列表当中 ,rows 所有的行
# print(datas) #datas是取到的所有行数据的对象,打印出来的A1,B1,C1。。。。。对应表格的A1,B1,C1。。。。
# for i in datas[0]: #通过for循环拿到里面的值,datas[0]取的是第一行的数据的对象
# print(i.value)
#列表解析式
title = [i.value for i in datas[0]] #对这个datas进行for循环遍历并且赋值给title这个变量
# print(title)

#创建一个空列表,用来接收所有的测试用例
cases = []
for j in datas[1:]: #对第2,3,4,5,6......行进行遍历
# print(j)
values = [k.value for k in j] #然后通过对j进行遍历,用k.value获取没有用例对象中value值,然后放在一个列表
# print(values)
case = dict(zip(title,values)) #把title列表和values每个用例一一对应打包放进一个字典当中
# print(case)
cases.append(case)
return cases #把所有的用例返回
def write_excel(self,row,column,value=None):
'''
封装一个往Excel表格里面写入测试结果的工具方法
'''
#打开表格
self.open()
# 往固定的row行和column列写入value数据
self.sh.cell(row,column,value)
#保存数据
self.wb.save(self.filename)
if __name__ == '__main__':
path = os.path.join(data_path,'apicase.xlsx')
read_excel = Handle_Excel(path,'login')
# read_excel.read_data() #打印出来的A1,B1,C1.....拿到的对应的对象,没有拿到值
read_excel.write_excel(2,8,'通过')

 ====================================================================

以上得操作都是数据准备工作,我们数据准备好了,就要组件接口调用方法

在utils中新建一个handle_requests.py文件

'''
此模块是用来封装发送接口请求的工具类
'''
import requests #我们要调用接口,导入 requests 库,用于发送 HTTP 请求  
class Send_requests(object): #定义一个名为 Send_requests 的类,用于封装发送接口请求的功能  
'''封装了一个发送接口请求的工具类'''

def __init__(self):#始化方法,创建一个 requests Session 对象,用来保持 HTTP 会话,这样可以在同一个会话中发送多个请求 
'''用来保持会话'''
self.session = requests.Session()
def send(self,method,url,data=None,json=None,params=None,headers=None):#初始化方法,创建一个 requests Session 对象,用来保持 HTTP 会话,这样可以在同一个会话中发送多个请求 
method = method.lower() #把接口的请求方法改为小写  # 将请求方法转换为小写,这样处理更通用  
 # 根据不同的请求方法,发送请求
        if method == 'get':   #   get 方法
response = self.session.get(url,params) #
elif method=="post": #post方法
response = self.session.post(url,data,headers)
elif method=="post_json": #post——json 方法
response = self.session.post(url,json,headers)
elif method == 'delete': #delete 方法
response = self.session.delete(url,data)
return response #返回响应结果
#如下是一个调试过程
# method = 'post' #写好请求方式
# url ='http://cms.duoceshi.cn/cms/manage/loginJump.do' # url请求链接
# data ={"userAccount":"admin","loginPwd":"123456"} #请求数据
# headers = {"Content-Type":"application/x-www-form-urlencoded"} #请求头
# s = Send_requests() #创建类对象,
# se = s.send(method=method,url=url,data=data,headers=headers) # 通过对象调函数
# print(se.json()) #打印结果

===================================

接下来我们开始在testcase 下新建用例 以test 开始开头:

第一个用例文件名: test_login.py  登录接口

 

1
import unittest  #导入unttest框架:<em>from ddt import ddt,data  #ddt辅助讲解  #https://www.cnblogs.com/xiaolehong/p/16801208.html <br>from utils.handle_excel import Handle_Excel  #编写用例要读取excel中的接口文档<br>from utils.handle_path import *  #导入所有路径<br>import os  #导入os模块<br>from utils.handle_conf import conf  #导入都取conf模块,读取ini文件中的内容<br>from utils.handle_requests import Send_requests #导入组建好接口<br>'''<br>ddt模块<br>打开dos窗口:输入 pip install ddt  进行下载<br>ddt模块:是用来做数据驱动的<br>ddt装饰器:用来装饰类<br>data装饰器:用来装饰方法的<br>装饰器的原理:就是闭包,闭包就是函数里面定义一个函数,外面的函数称为外函数,里面的函数称为内函数<br>外函数中返回内函数的函数名,也就是返回内函数的地址,内函数里面写装饰器的逻辑<br>'''<br>case_file = os.path.join(data_path,'apicase.xlsx')  #变量存储了apicase.xlsx文件的路径<br></em>@data(*cases)ase_id        # 2.发送接口请求<br>        response = self.request.send(method=method,url=url,data=data,headers=headers)  #调用接口请求方法<br>        result = response.json() #将结果转成json格式<br>        # print(result)<br>        # 3.对接口的响应内容进行断言 <br>        try:  #try尝试去执行代码<br>            self.assertEqual(excepted['msg'],result['msg'])  #断言期望结果和实际结果是否一直,如果一致就执行else,否则就抛异常<br>            self.assertEqual(excepted['code'],result['code'])<br>        except Exception as e: #捕捉异常<br>            self.excel.write_excel(case_id,8,'未通过')<br>            print(e)<br>        else:<br>            self.excel.write_excel(case_id,8,'通过')<br><br>if __name__ == '__main__':<br>    unittest.main()

接下来在运行用例:run包下:

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'''
此模块是用来生成测试报告,并且发送报告到邮箱`
'''
import time
import unittest
from library.HTMLTestRunnerNew import HTMLTestRunner
from utils.handle_path import *
from library.mail import SendMail
#定义生成报告的路径和文件
now = time.strftime('%Y-%m-%d-%H-%M-%S')
print(now)
filename = report_path+'\\' + str(now)+"_api_report.html"
def auto_run():
    discover = unittest.defaultTestLoader.discover(start_dir=testcase_path,
                                                   pattern='test_*.py')
    f = open(filename,'wb')
    runner = HTMLTestRunner(stream=f,
                            title='cms平台接口自动化测试报告',
                            description="用例执行情况如下",
                            tester="dcs")
    runner.run(discover)
    f.close()
def sendMail():
    sm = SendMail(send_msg=filename,attachment=filename)
    sm.send_mail()
if __name__ == '__main__':
    auto_run()
    # sendMail()

  ==================================================

在查看report 报告中是否生成报告

 ==================================================

那我们接下来要写其他得用例,可以在testcase包中添加 test_updateloginpwd.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import unittest
from ddt import ddt,data
from utils.handle_excel import Handle_Excel
from utils.handle_path import *
import os
from utils.handle_conf import conf
from utils.handle_requests import Send_requests
from utils.base_login import Cms_login
'''
ddt模块
打开dos窗口:输入 pip install ddt  进行下载
ddt模块:是用来做数据驱动的
ddt装饰器:用来装饰类
data装饰器:用来装饰方法的
装饰器的原理:就是闭包,闭包就是函数里面定义一个函数,外面的函数称为外函数,里面的函数称为内函数
外函数中返回内函数的函数名,也就是返回内函数的地址,内函数里面写装饰器的逻辑
'''
case_file = os.path.join(data_path,'apicase.xlsx')
 
@ddt
class Test_Login(unittest.TestCase):
    excel = Handle_Excel(case_file,'updateLoginPwd')
    cases = excel.read_data()  #一个列表当中是5个字典,每个字典都是一个用例
    # print(cases)
    request = Send_requests()  #创建了一个发送接口请求的对象
    @classmethod
    def setUpClass(cls) -> None:
        cls.request = Cms_login().login()  #调用登录接口
 
 
    @data(*cases)
    def test_02_updateLoginPwd(self,case):
        '''封装登录接口''' #数据要从Excel表格里面拿
        # 1.准备接口的入参
        url = conf.get_value('env','url')+case['url']
        print(url)
        # eval()  函数是用来执行一个字符串表达式,并返回表达式的值
        headers = eval(conf.get_value('env','headers'))
        method = case['method']
        data = eval(case['data'])
        excepted = eval(case['excepted'])
        case_id = case['case_id']
        case_id = case_id+1  #记录当前跑了几条用例
 
        # 2.发送接口请求
        response = self.request.send(method=method,url=url,data=data,headers=headers)
        result = response.json()
        # print(result)
        # 3.对接口的响应内容进行断言
        try#try尝试去执行代码
            self.assertEqual(excepted['msg'],result['msg'])  #断言期望结果和实际结果是否一直
            self.assertEqual(excepted['code'],result['code'])
        except Exception as e: #捕捉异常
            self.excel.write_excel(case_id,8,'未通过')
            print(e)
        else:
            self.excel.write_excel(case_id,8,'通过')
if __name__ == '__main__':
    unittest.main()

 ==================================================

在utils 中新建 公共登录方法: base_login.py

因为我们封装一个登录公共方法

1
2
3
4
5
6
7
8
9
10
11
from utils.handle_conf import conf
from utils.handle_requests import Send_requests
class Cms_login():
    def login(self):
        request = Send_requests()
        url = conf.get_value('env','url')+"/cms/manage/loginJump.do"
        data = {"userAccount":"admin",
                "loginPwd":"123456"}
        headers = {"Content-Type":"application/x-www-form-urlencoded"}
        response = request.send(method='post',url=url,data=data,headers=headers)
        return reques

==================================================

在testcase包中添加 test_delete.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import unittest
from ddt import ddt,data
from utils.handle_excel import Handle_Excel
from utils.handle_path import *
import os
from utils.handle_conf import conf
from utils.handle_requests import Send_requests
from utils.base_login import Cms_login
'''
ddt模块
打开dos窗口:输入 pip install ddt  进行下载
ddt模块:是用来做数据驱动的
ddt装饰器:用来装饰类
data装饰器:用来装饰方法的
装饰器的原理:就是闭包,闭包就是函数里面定义一个函数,外面的函数称为外函数,里面的函数称为内函数
外函数中返回内函数的函数名,也就是返回内函数的地址,内函数里面写装饰器的逻辑
'''
case_file = os.path.join(data_path,'apicase.xlsx')
 
@ddt
class Test_Login(unittest.TestCase):
    excel = Handle_Excel(case_file,'delete')
    cases = excel.read_data()  #一个列表当中是5个字典,每个字典都是一个用例
    # print(cases)
    request = Send_requests()  #创建了一个发送接口请求的对象
    @classmethod
    def setUpClass(cls) -> None:
        cls.request = Cms_login().login()  #调用登录接口
 
 
    @data(*cases)
    def test_03_delete(self,case):
        '''封装登录接口''' #数据要从Excel表格里面拿
        # 1.准备接口的入参
        url = conf.get_value('env','url')+case['url']
        print(url)
        # eval()  函数是用来执行一个字符串表达式,并返回表达式的值
        headers = eval(conf.get_value('env','headers'))
        method = case['method']
        data = eval(case['data'])
        excepted = eval(case['excepted'])
        case_id = case['case_id']
        case_id = case_id+1  #记录当前跑了几条用例
 
        # 2.发送接口请求
        response = self.request.send(method=method,url=url,data=data,headers=headers)
        result = response.json()
        # print(result)
        # 3.对接口的响应内容进行断言
        try#try尝试去执行代码
            self.assertEqual(excepted['msg'],result['msg'])  #断言期望结果和实际结果是否一直
            self.assertEqual(excepted['code'],result['code'])
        except Exception as e: #捕捉异常
            self.excel.write_excel(case_id,8,'未通过')
            print(e)
        else:
            self.excel.write_excel(case_id,8,'通过')
if __name__ == '__main__':
    unittest.main()

==========================================

接下来,我们在去run下,查看所有运行结果

以上就是我们整个框架;

 =========================================

讲解稿:

我讲下我编写的的接口自动化框架是: python+requests+unittest+ddt 实现的

案例1:

首先建立一个新的项目,命名"cms",然后新建7个包:分别如下

定义一个confi包是用来存放环境、账号、密码等,

再定义一个data包用来存放测试数据,数据可以是excel表格,通过excel编写接口用例,

定义一个library包存放外部导入的工具函数:比如报告模板、邮件模板

再定义一个report包用来存放运行后的的测试报告,

再定义定义一个run_allcase包执行所有的用例并生成报告;
再定义一个testcase包在里面编写的测试用例,

再定义一个utils包存放所有自己写的封装语句:比如读取ini文件,excel文件,接口调用方法等。

案例2:

详细说下:再每个包中新建的py文件

在conf包下建一个conf.ini文件里面写入要运行的系统基本信息和登陆账号密码。

在utils包下新建一个head_path模块在里面编写项目与包的路径比如:导入os模块,os.path.dirname(__file__),定义每个包的路径。

在utils包下新建一个head_conf模块在里面编写处理ini文件的类,我们要用到configparser库来获取ini文件中的环境,账号

在utils包下新建一个head_requests模块在里面写入封装接口的工具类,我们导入  requests ,封装调用方法。

在utils包下新建一个head_excel模块在里面写入读取表格的接口数据,使用openpyxl 库。

在data包的路径下新建一个表格,表格写接口用例:内容

id、接口名称、用例标题,、用例类型、url、要填写的信息、预期结果、是否通过空置。

在testcase包下新建一个test_login模块在里面写入数据驱动的代码,导入ddt工具函数,引入装饰器@ddt @data导入数据。

在testcase包下导入unittest框架,通过框架来管理用例,将命名test开头,再用例下需要引入读取的数据和调用方法,并发送接口,

library包下存放报告模,邮件模板;

在run包下新建一个run_tesascase模块,通过un ittest_Testload 搜索一个路径下的用例,通过报告运行所有用例的代码,并生成测试报告,并将报告的存放路径放到report包下。

 代码参考:https://www.cnblogs.com/xiaolehong/p/16801467.html

案例3:

我讲下接口自动化框架:python+requests+unittest+ddt  实现的,我们一共分为7层。

第1层的话是config配置层,这个里面主要是封装了一些我们测试环境的url地址和一些连接数据库的IP地址,用户名密码等等
第2层是data数据层,这个里面主要放的是接口的用例,把接口的入参,接口的路径,接口的编号,请求方法都放在这个里面了,一个接口放在一个sheet页面里面,然后一个sheet页面里面有多个接口测试用例,有正常场景的也有多个异常场景的
第3层是一个library第三方的公共库层,里面主要是放了发邮件的工具类,生成测试报告的工具类
第4层就是utils工具类层,主要封装了读取Excel表格,读取ini配置文件和发送接口请求的工具类
第5层就是testcase用例层,这个里面首先会创建一个类,然后在里面创建以test开头的方法,然后定义一个data装饰器主要是用来接受Excel表格里面的接口入参,第一步先做数据的处理,然后第二步再通过封装好的发接口请求的工具类发送接口请求得到response返回值,第三步再对接口进行断言,一般会对接口返回的状态码或内容和预期结果进行断言
第6层就是run运行层,首先会通过把所有的用例搜索出来,并通过HTMLtestrunner报告模板运行生成测试报告

第7层报告层report里面,将运行的报告存在再report包中

最后通过Jenkins做可持续集成,在回归测试阶段,每天晚上都会运行一下我们的接口自动化用例,大致的一个框架结构就是这样的。

==========================================

1、将框架调试一边

2、将框架自己写一遍

3、将框架用word文档总结,并发出来

 

posted @   xiaolehua  阅读(257)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-11-28 肖sir__杭州字节面试题___归纳
2022-11-28 肖sir___阿里面试题__笔试题
点击右上角即可分享
微信分享提示