python requests unittest_Python3 + requests + unittest接口测试

一、缘 起

笔者最近完成了基于Python3 + requests + unittest的接口测试脚本,故在此做一下记录,于己为复盘,于彼为学习和参考

二、思 路

接口测试无非三步:

首先,造数据 - Python3连接MySQL,插入测试数据

然后,发请求 - requests模块依次发请求

最后,校验返回值 - 基于unittest框架,assert主要的response值

三、说 明

脚本的工程名为zhtyInterfaceTest,整体结构如下图

.idea为PyChram编辑器自动生成的,不用管

common为通用的模块/方法集合,如接口加密方法、配置parameters方法、配置数据库方法、读Excel方法,等,一切你能想到的辅助测试的方法都可以放到这里

testCase为测试测试用例集合,笔者用unittest框架、用discover方法添加测试用例,那么想按顺序执行测试用例,就必须对测试用例命名按照ASCII顺序,具体如下图

testFile存放测试数据和测试用图,测试数据为Excel格式

testResult为测试结果集合,基于unittest框架,运行完脚本直接生成HTML格式的测试报告

config.ini为配置文件,配置需要测试的URL、数据库及SQL语句

runAll.py为主程序

四、实 现

造测试数据,如果读者对Python3操作数据库不甚熟悉,可以参考笔者之前写的文章《Python3连接MySQL数据库及基本操作》

./zhtyInterfaceTest/common/mysqlCfg.py

#!/usr/bin/python

# coding=utf-8

from pymysql import connect

from pymysql.err import OperationalError

import os

import configparser as cparser

# ------------------读取配置文件及数据库配置----------------------

base_path = str(os.path.dirname(os.path.dirname(__file__)))

base_path = base_path.replace('\\', '/')

cfg_path = base_path + '/config.ini'

cf = cparser.ConfigParser()

cf.read(cfg_path, encoding='utf-8')

host = cf.get('MYSQL', 'host')

port = cf.get('MYSQL', 'port')

user = cf.get('MYSQL', 'user')

password = cf.get('MYSQL', 'password')

db_name = cf.get('MYSQL', 'db_name')

charset = cf.get('MYSQL', 'charset')

# -----------封装MySQL数据库基本操作-----------------

class DB:

def __init__(self):

try:

# 连接数据库

self.conn = connect(

host=host,

port=int(port),

user=user,

password=password,

db=db_name,

charset=charset

)

except OperationalError as e:

print('MySQL error %d: %s' % (e.args[0], e.args[1]))

else:

self.cursor = self.conn.cursor()

def execute_sql(self, command, sql):

"""

插入表数据

:param command:

:param sql:

:return:

"""

if command in ('SELECT', 'select'):

# 如果为查询指令

sql = sql.encode('utf-8')

try:

self.cursor.execute(sql)

result = self.cursor.fetchall()

return result

except Exception as e:

print(e)

finally:

self.conn.close()

elif command in ('delete', 'DELETE', 'update', 'UPDATE', 'insert', 'INSERT'):

# 如果为增删改

sql = sql.encode('utf-8')

try:

self.cursor.execute(sql)

self.conn.commit()

except Exception as e:

self.conn.rollback()

print(e)

finally:

self.conn.close()

else:

print('Command Error!')

if __name__ == '__main__':

# sel_sql = cf.get('SQL', 'SELECT')

# s = DB().execute_sql('select', sel_sql)

print(DB().execute_sql('select', cf.get('SQL', 'SELECT'))[0][0])

./zhtyInterfaceTest/runAll.py

#!/usr/bin/python

# coding=utf-8

from HTMLTestRunner import HTMLTestRunner

import configparser as cparser

from common.mysqlCfg import DB

import unittest

import time

import os

discover = unittest.defaultTestLoader.discover('./testCase/teacher', pattern='test*.py')

if __name__ == '__main__':

# ------------------读取配置文件----------------------

base_path = str(os.path.dirname(__file__))

base_path = base_path.replace('\\', '/')

cfg_path = base_path + '/config.ini'

cf = cparser.ConfigParser()

cf.read(cfg_path, encoding='utf-8')

# 初始化测试数据

ins_tb_user = cf.get('SQL', 'ins_tb_user')

ins_relation_class = cf.get('SQL', 'ins_relation_class')

ins_sport_data_01 = cf.get('SQL', 'ins_sport_data_01')

ins_sport_data_02 = cf.get('SQL', 'ins_sport_data_02')

ins_class_course_data = cf.get('SQL', 'ins_class_course_data')

# 执行SQL

DB().execute_sql('insert', ins_tb_user)

DB().execute_sql('insert', ins_relation_class)

DB().execute_sql('insert', ins_sport_data_01)

DB().execute_sql('insert', ins_sport_data_02)

DB().execute_sql('insert', ins_class_course_data)

~

......

~

【脚 本 说 明】

通过读取config.ini文件的数据库配置信息和需要执行的SQL语句,实现连接数据库以及执行SQL的方法

在主程序runAll.py执行测试用例前提前造好测试数据

发request请求

./zhtyInterfaceTest/reqMethod.py

#!/usr/bin/python

# coding=utf-8

import configparser as cparser

import requests

import os

# ------------------读取配置文件----------------------

base_path = str(os.path.dirname(os.path.dirname(__file__)))

base_path = base_path.replace('\\', '/')

cfg_path = base_path + '/config.ini'

cf = cparser.ConfigParser()

cf.read(cfg_path, encoding='utf-8')

class RequestMethod:

""" 定义请求类型 """

def __init__(self):

"""初始化参数"""

self.base_url = cf.get('URL', 'base_url')

self.data = {}

self.files = {}

def get(self, url, params):

"""

定义get方法请求

:return:

"""

test_url = self.base_url + url

try:

return requests.get(url=test_url, params=params, timeout=60)

except TimeoutError:

return print('%s get request timeout!' % url)

def post(self, url, params):

"""

定义post方法请求

:return:

"""

test_url = self.base_url + url

try:

return requests.post(url=test_url, data=params, timeout=60)

except TimeoutError:

return print('%s post request timeout!' % url)

def post_with_file(self, url, params, fp):

"""

定义post方法请求

:return:

"""

test_url = self.base_url + url

file = {

'head_img': open(fp, 'rb')

}

try:

return requests.post(url=test_url, data=params, files=file, timeout=60)

except TimeoutError:

return print('%s post request timeout!' % url)

./zhtyInterfaceTest/testCase/teacher/test_1_login.py

#!/usr/bin/python

# coding=utf-8

from common.reqMethod import RequestMethod

from common.getParams import *

import unittest

class Login(unittest.TestCase):

"""登录接口测试"""

def setUp(self):

self.url = 'login'

self.sheet = 'login'

def tearDown(self):

print(self.req_result)

def test_login_success(self):

"""

测试正常登录

:return:

"""

case = 'test_login_success'

# 获取请求参数

param = get_req_params(self.sheet, case)

# 发起请求

self.req_result = RequestMethod().post(self.url, param).json()

~

......

~

【脚 本 说 明】

读配置文件获取基础URL,然后依次定义三种常用的HTTP请求方法:get、post、post_with_file

根据请求方法的不同,传参的类型一般为:测试接口(与基础URL拼接为请求URL)、params和fp(上传文件的路径)

在每一个测试用例中,通过调用getParams.py模块的get_req_params方法,从Excel获取请求参数,通过get_resp_params方法从Excel获取响应参数

在测试用例中调用reqMethod.py中封装的请求方法,发接口请求

校验返回值

./zhtyInterfaceTest/testCase/teacher/test_1_login.py

from common.reqMethod import RequestMethod

from common. ......

class Login(unittest.TestCase):

......

def test_login_success(self):

......

# 返回参数断言

self.assertEqual(self.req_result['code'], get_resp_params(self.sheet, case, 'code'))

self.assertEqual(self.req_result['msg'], get_resp_params(self.sheet, case, 'msg'))

self.assertEqual(self.req_result['data']['user_name'], get_resp_params(self.sheet, case, 'user_name'))

......

【脚 本 说 明】

通过调用getParams.py模块的get_resp_params方法从Excel获取响应参数,和接口返回的参数做比对,实现断言

生成测试报告

./zhtyInterfaceTest/runAll.py

......

now = time.strftime('%Y-%m-%d %H_%M_%S') # 获取当前时间

filename = now + ' testReport.html'

fp = open('./testResult/{0}'.format(filename), 'wb')

runner = HTMLTestRunner(stream=fp,

title='智慧体育教师版接口测试报告',

description='用例执行情况:')

runner.run(discover)

fp.close()

......

五、最 后

OK!

~

~

~

不积跬步,无以至千里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值