Python接口测试
做过很多项目,后来发现,还是测试工作最重要,因为很多功能的实现和设计,你没办法验证是否合理和满足业务需求,如果你不做严格的测试,直接开发,那么等做完了整个项目后才发现现有设计不满足业务场景,再改再翻工,可就费事了。这是我之前写的用来测试http接口的python脚本,测试接口的工具有很多,比如Jmeter,Postman等等,但作为一个码农,还是觉得自己写脚本测比较方便,尤其是接口的各种参数配置及加密什么,编写脚本程序来测,简直不要太爽。
脚本功能概述
这个测试脚本是用Python写的,包含了接口AES、MD5、base64等参数加密方法,以及token协议头生成等功能,基本还是覆盖比较全面的,尤其aes加密,这块儿要和java及.Net写的接口通用,比较难,不过我还是试出来了,其他的诸如get,post等方式调用,还是比较常规和简单的。
源代码下载
https://github.com/Dahlin/HTTPInterfaceTest
脚本及注释
由于脚很还是蛮简单的,基本注释都有,所以就不再重复解释啦
import time
from urllib.parse import urljoin, urlencode
import hashlib
import base64
import uuid
from Crypto.Cipher import AES
from Crypto.SelfTest.st_common import b2a_hex
import requests
# pip install pycryptodome
# http://cn.python-requests.org/zh_CN/latest/
class HTTPInterfaceTest:
"""
http 接口测试类
"""
publickey = ''
key = ''
usernames = []
param = ''
def __init__(self, publickey, key, usernames, param, url, timeout=1000):
self.publickey = publickey
self.key = key
self.usernames = usernames
self.param = param
self.__base_url = url
self.__timeout = timeout
@staticmethod
def get_timestr():
"""
获取固定格式的时间戳
:return:
"""
now = int(time.time())
timestr = time.localtime(now)
return time.strftime("%H%M%S", timestr)
@classmethod
def pad(cls, text):
"""
计算aes加密填充位数
:param text:
:return:
"""
icount = 16 - (len(text) % 16)
while len(text) % 16 != 0:
text += chr(icount)
return str.encode(text, encoding='utf-8')
def __get_aes_token(self):
"""
用aes方式组织token
:param key: 私钥
:return:
"""
date = time.strftime('%Y%m%d%H%M%S')
aes = AES.new(self.pad(self.key), AES.MODE_ECB)
signature = str(b2a_hex(aes.encrypt(self.pad(date))), encoding='utf-8').upper()
return signature
def __get_header(self):
# 定义requests的请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
'Token': self.__get_aes_token(),
'Connection': 'close',
}
return headers
def __get_md5_token(self):
"""
用md5方式组织token
:return:
"""
token_before = self.publickey+time.strftime('%Y%m%d%H%M%S')
token_after = hashlib.md5(token_before.encode(encoding='utf-8')).hexdigest()
return token_after
def __get_base64_token(self):
"""
用base64方式组织token
:return:
"""
token_before = self.publickey+time.strftime('%Y%m%d%H%M%S')
token_after = str(base64.b64encode(token_before.encode(encoding='utf-8')), encoding='utf-8')
return token_after
def exec_request(self, stype, child_url, headers, params):
"""
执行调取接口
:param stype:
:param child_url:
:param headers:
:param params:
:return:
"""
query_url = urljoin(self.__base_url, child_url)
print(query_url)
if headers == "":
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
}
if stype == 'post':
response = requests.post(query_url, headers=headers, data=params, timeout=self.__timeout)
elif stype == 'get':
response = requests.get(query_url, headers=headers, params=params, timeout=self.__timeout)
else:
response = requests.get(query_url, headers=headers, json=params, timeout=self.__timeout)
return response
def test_http(self, pytpe='text'):
"""
post调取http接口
:return:
"""
headers = self.__get_header()
data = {
"public_key": self.publickey,
"usernames": self.usernames,
"param": self.param
}
response = self.exec_request(stype='post', child_url='post', headers=headers, params=data)
# response = self.exec_request(stype='get', child_url='get', headers=headers, params=data)
if pytpe == 'text':
print(response.text)
else:
print(response.json())
if __name__ == '__main__':
base_url = 'http://192.168.127.131/'
public_key = '123456789'
key = 'A123B456C789D123'
usernames = ['Jike', 'Jone', 'Ada']
param = uuid.uuid1()
ti = HTTPInterfaceTest(publickey=public_key,
key=key,
usernames=usernames,
param=param,
url=base_url)
ti.test_http()