Python接口自动化实战(第二阶段)- unittest框架
时间:2019-08-21
本文章向大家介绍Python接口自动化实战(第二阶段)- unittest框架,主要包括Python接口自动化实战(第二阶段)- unittest框架使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
转载:https://www.cnblogs.com/testjiali/p/10415397.html
1.unitttest简介
为什么要使用unittest?
前面我们已经写代码实现了注册接口的处理调用,但是一个接口往往需要多条测试用例才能完整的覆盖到每一种情况,针对于单接口多条测试用例需要执行的情况,我们该如何处理呢?
在unittest的测试类中定义多个测试方法来完成测试,这可能是大家最先想到的一个解决方法,当然也是能够达到目的的,以下面的注册接口为例,我们基于此思路来编码实现接口的完整测试。
unittest特点
- python自带的单元测试框架,无需安装
- 用例执行互不干扰
- 提供不同范围的setUp(测试准备)和tearDown(测试清理)方法
- 提供丰富的断言方法
- 可以通过discover批量执行所有模块的用例
- 可以通过TestSuite(测试集)灵活的组织用例
unittest几大组成部分
- TestCase: 用例对象,编写测试用例时要继承该类,以具有TestCase的属性和方法
- TestSuite: 测试集或测试套件,测试用例的集合,用来组织用例,支持嵌套
- TestLoader: 用例加载器,用于向TestSuite中添加用例
- TextTestRunner: 用例执行器(输出文本结果),一般以TestSuite为单位执行用例
- TestResult: 测试结果
2.接口分析
通过接口的需求分析,我整理了注册接口的三条测试用例:
1)正确的邮箱账号注册
2)输入无效的邮箱账号注册
3)输入已经存在的邮箱账号注册
3.用例编写
根据上面的三条测试用例,把每条用例都转化成unittest里面的测试用例。
编写规则
- 新建一个test_开头(必须)的.py文件,如
test_register.py
- 导入unittest
- 编写一个Test开头(必须)的类,并继承unittest.TestCase,做为测试类
- 在类中编写一个test_开头(必须)的方法,作为用例。注意:用例执行顺序并非按书写顺序执行,而是按用例名ascii码先后顺序执行
完整的接口测试用例包含:
1.数据准备:准备测试数据,可手工准备,也可使用代码准备(通常会涉及数据库的操作,比如发送验证码后)
2.发送请求:发送接口请求
3.响应断言、数据库断言:这个根据需要,一般响应断言后还需要进行数据库断言,以确保接口数据库操作的正确性
5.数据清理:如果接口有更新数据库操作,断言结束后需要还原更改
4.用例断言
unittest提供了丰富的断言方法
5.Fixtures
Test Fixtures即setUp(用例准备)及tearDown(测试清理)方法,用于分别在测试前及测试后执行
按照不同的作用范围分为:
- setUp()/tearDown(): 每个用例执行前/后执行一次
- setUpClass()/tearDownClass(): 每个测试类加载时/结束时执行一次
- setUpMoudle()/tearDownMoudle(): 每个测试模块(一个py文件为一个模块)加载/结束时执行一次
6.代码实现
# 导入 import unittest import requests class TestRegister(unittest.TestCase): # 类必须以Test开头,继承TestCase def setUp(self): print("======开始执行测试用例======") self.url = 'http://27.154.55.14:8180/api/fcb2bcrm/webRegister' def tearDown(self): print("======测试用例执行完毕======") # 测试用例 - 正常注册 def test_register_normal(self): # 每一条测试用例以test_开头 # 发送请求 params = {'LoginAccount': 'apitest08@emai.com', 'Password': '123456', 'Type': 'Pro'} res = requests.post(self.url,params) # 断言:根据实际测试场景,可以查询数据库是否有新注册的用户、对比接口的返回信息、对比状态码等等 self.assertEqual(200, res.status_code) # 测试用例 - 重复注册 def test_register_existing(self): # 发送请求 params = {'LoginAccount': 'apitest05@emai.com', 'Password': '123456', 'Type': 'Pro'} res = requests.post(self.url,params) # 断言 print("执行结果:", res.json()['Message']) self.assertIn("The email has been registered", res.json()['Message']) # 测试用例 - 无效的邮箱格式去注册 def test_register_invalid_email(self): # 发送请求 params = {'LoginAccount': 'testapi@emai', 'Password': '123456', 'Type': 'Pro'} res = requests.post(self.url,params) # 断言 print("执行结果:", res.json()['Message']) self.assertIn("valid email", res.json()['Message']) if __name__ == '__main__': # 从当前模块执行 unittest.main()
7.用例组织以及运行
TestSuite()加载测试用例,创建一个实例, TestSuit的父类是BaseTestSuite
生成Html测试报告
1.下载 HTMLTestRunnerNew.py文件 ,拷贝到项目目录
2.在run.py中导入该模块
3.运行脚本,会在指定的文件夹下生成测试报告.html ,用浏览器打开即可查看
import unittest import HTMLTestRunnerNew # 导入用于生成测试报告 from Common import project_path # 读取文件路径 from Common.test_register import TestRegister # 导入测试类 suite=unittest.TestSuite() # 1. 加载测试用例:把测试用例放到测试套件suite里面 suite.addTest(TestRegister('test_register_normal')) suite.addTest(TestRegister('test_register_existing')) suite.addTest(TestRegister('test_register_invalid_email')) # 2.运行测试集, 并生成Html测试报告 with open(project_path.report_path,'wb') as file: runner=HTMLTestRunnerNew.HTMLTestRunner(stream=file, verbosity=2,title='ServiceX API Testing',description='ServiceX API Testing',tester='Jiali') runner.run(suite)
8.测试报告
原文地址:https://www.cnblogs.com/yuany66/p/11387739.html
- React多页面应用6(gulp自动化发布到多个环境、生成版本号、压缩成zip等)
- SDIBT 1046 Primary Arithmetic
- 洛谷P2415 集合求和
- React多页面应用5(webpack生产环境配置,包括压缩js代码,图片转码等)
- SDIBT 1046 Primary Arithmetic
- React多页面应用4(webpack自动化生成多入口页面)
- 第二周神经网络基础2.1 二分分类2.2 logistic回归2.3 logistic 回归损失函数2.4 梯度下降2.5 导数2.14 向量化logistic 回归的输出2.15 Python中的广
- 1031 SDIBT Where's Waldorf?
- poj 2469 Stack 'em Up
- React多页面应用3(webpack性能提升,包括打包性能、提取公共包等)
- POJ 2646 The Trip
- React多页面应用2(处理CSS及图片,引入postCSS,及图片处理等)
- 图的广度优先搜索和深度优先搜索(邻接链表表示)邻接链表广度优先搜索深度优先搜索运行结果
- JOJ 2680 Problem F: Coin Game
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android图片等比例缩放和填充屏幕效果
- Android中自定义ImageView添加文字说明详解
- Android 中ThreadLocal的深入理解
- 100行Android代码轻松实现带动画柱状图
- Android编程绘图操作之弧形绘制方法示例
- 详解Android中Application设置全局变量以及传值
- Android编程调用红外线遥控功能示例
- Android实现图文垂直跑马灯效果
- Android 实现截屏功能的实例
- android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)
- Android通过overScrollBy实现下拉视差特效
- Android使用手势实现翻页效果
- Android应用内悬浮窗的实现方案示例
- Android实现View拖拽跟随手指移动效果
- Android中button的onClick事件几种方法