一、缘 起

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

二、思 路

接口测试无非三步:

  • 首先,造数据 - Python3连接MySQL,插入测试数据
  • 然后,发请求 - requests模块依次发请求
  • 最后,校验返回值 - 基于unittest框架,assert主要的response

三、说 明

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

  1. .ideaPyChram编辑器自动生成的,不用管
  2. common为通用的模块/方法集合,如接口加密方法、配置parameters方法、配置数据库方法、读Excel方法,等,一切你能想到的辅助测试的方法都可以放到这里
  3. testCase为测试测试用例集合,笔者用unittest框架、用discover方法添加测试用例,那么想按顺序执行测试用例,就必须对测试用例命名按照ASCII顺序,具体如下图

  4. testFile存放测试数据和测试用图,测试数据为Excel格式
  5. testResult为测试结果集合,基于unittest框架,运行完脚本直接生成HTML格式的测试报告
  6. config.ini为配置文件,配置需要测试的URL、数据库及SQL语句
  7. runAll.py为主程序

四、实 现

  1. 造测试数据,如果读者对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执行测试用例前提前造好测试数据
  1. 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请求方法:getpostpost_with_file
  • 根据请求方法的不同,传参的类型一般为:测试接口(与基础URL拼接为请求URL)、paramsfp(上传文件的路径)
  • 在每一个测试用例中,通过调用getParams.py模块的get_req_params方法,从Excel获取请求参数,通过get_resp_params方法从Excel获取响应参数
  • 在测试用例中调用reqMethod.py中封装的请求方法,发接口请求
  1. 校验返回值
  • ./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获取响应参数,和接口返回的参数做比对,实现断言
  1. 生成测试报告
  • ./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()
......

五、最 后

运行结果



Git地址:https://gitee.com/freedomlidi/zhtyInterfaceTestPublic.git

OK!

~

~

~

不积跬步,无以至千里

Python3 + requests + unittest接口测试的更多相关文章

  1. python3+requests+unittest:接口自动化测试(一)

    转载请表明出处:https://www.cnblogs.com/shapeL/p/9179484.html 简单介绍框架的实现逻辑,参考代码的git地址: https://github.com/zha ...

  2. python3 requests 进行接口测试、爬虫使用总结

    Requests 是第三方模块,如果要使用的话需要导入.Requests也可以说是urllib模块的升级版,使用上更方便. 这是使用urllib的例子. import urllib.request i ...

  3. python3+requests:接口自动化测试(二)

    转载请注明出处:https://www.cnblogs.com/shapeL/p/9188495.html 前言:上篇文章python3+requests+unittest:接口自动化测试(一):ht ...

  4. 对比3种接口测试的工具:jmeter+ant;postman;python的requests+unittest或requests+excel

    这篇随笔主要是对比下笔者接触过的3种接口测试工具,从实际使用的角度来分析下3种工具各自的特点 分别为:jmeter.postman.python的requests+unittest或requests+ ...

  5. 【python3+request】python3+requests接口自动化测试框架实例详解教程

    转自:https://my.oschina.net/u/3041656/blog/820023 [python3+request]python3+requests接口自动化测试框架实例详解教程 前段时 ...

  6. python3+requests库框架设计01-自动化测试框架需要什么?

    什么是自动化测试框架 关于自动化测试框架的定义有很多,在我大致理解下就是把能实现不同功能的软件组合在一起,实现特定的目的,这就是一个简单的自动化测试框架. 接口自动化测试框架核心无非是选择 一个用来编 ...

  7. requests,unittest——多接口用例,以及需要先登录再发报的用例

    之前写过最简单的接口测试用例,本次利用unittest进行用例管理,并出测试报告,前两个用例是两个不同网页的get用例,第三个是需要登录才能访问的网页A,并在其基础上访问一个需要在A页面点开链接才能访 ...

  8. Python3+Requests+Excel完整接口自动化框架

    框架整体使用Python3+Requests+Excel:包含对实时token的获取 框架结构图 1.------base -------runmethond.py runmethond:对不同的请求 ...

  9. requests+unittest+ddt+xlrd+pymysql+BeautifulReport数据驱动

    # ddcapitestpython XXX接口自动化测试 # 一.数据驱动的思路 1.采用requests+unittest+ddt+xlrd+pymysql+BeautifulReport 2.r ...

随机推荐

  1. win7+centos6.5安装双系统

    前言:之前在琢磨怎么安装双系统 倒腾了两天终于给装上了 使用软件 镜像:CentOS-6.5-x86_64-bin-DVD1.iso 开机引导软件 easybcd2.2 u盘制作软件 USBWrite ...

  2. [LC] 17. Letter Combinations of a Phone Number

    Given a string containing digits from 2-9 inclusive, return all possible letter combinations that th ...

  3. <JZOJ5938>分离计划

    emm骚操作 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm ...

  4. 修改 commit message

    本文为原创文章,转载请标明出处 目录 修改上一条提交的 commit message 修改之前提交的 commit message 1. 修改上一条提交的 commit message git com ...

  5. Docker学习笔记_08使用Rancher pipeline搭建基于容器的CICD

    CICD概述 CI-持续集成(Continuous Integration):频繁地将代码集成到主干的一种开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错 ...

  6. C++求解N阶幻方

    由一道数学题的联想然后根据网上的做法瞎jb乱打了一下,居然对了代码精心附上了注释,有兴趣的童鞋可以看一看..不说了,上代码!(自认为结构很清晰易懂) 1234567891011121314151617 ...

  7. ES:在线迁移集群索引,数据不丢失

    一.背景 生产环境由于某些原因需要跨机房迁移ES集群,或者同机房原有集群中所有节点全部更换,期间ES索引要求完整,客户端请求中断不超过五分钟. 二.应用场景 1.同机房不同集群之间数据迁移: 2.跨机 ...

  8. GCD学习 —— 三

    ​ 学习学习dispatch_block,在向队列中添加任务时,可以直接在对应的函数中添加 block.但是如果想对任务进行操作,比如监听任务.取消任务,就需要获取对应的 block. 1 创建Blo ...

  9. 压力测试(七)-html可视化压测报告细讲

    1.阿里云Linux服务器 Jmeter压测实战之jtl文件生成和查看 简介: 利用软件从阿里云Centos服务器下载压测报告,讲解Jtl文件,并怎么查看文件 可以通过打开jmeter,新建线程组-& ...

  10. 一起了解 .Net Foundation 项目 No.12

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Cecil Cecil 是 ...