【接口测试】-Unitttest测试框架
2021-09-27
领导安排要做接口自动化,也没说怎么搞,那就按照自己的想法搞呗。
调研了几款框架,有利有弊,先从简单的用起来吧,利用空闲时间,写了几个简单的接口,初步实现,后续慢慢优化吧。
为什么要使用unittest?
在编写接口自动化用例时,一般一个接口建立一个.py文件,一条测试用例封装为一个方法,但是在批量执行的过程中,如果有一条出错,后面的用例就无法执行。使用测试框架可以避免这种情况。
当然我们要用还是简单了解下unittest
unittest有哪些特点
- python自带测试框架,不用安装
- 用例执行互相不干扰
- 提供不同范围的setUp(测试准备)和tearDown(测试清理)方法
- 提供丰富的断言方法
- 可以通过discover批量执行所有模块的用例
- 可以通过TestSuite(测试集)比较灵活的组织用例
编写用例
- 新建一个test_开头(必须)的.py文件,如test_user_login.py
- 导入unittest
- 编写一个Test开头(必须)的类,并继承unittest.TestCase,做为测试类
- 在类中编写一个test_开头(必须)的方法,作为用例
文件必须test_开头 test_teacher.py
import requests
import unittest
class TestTeacherEdit(unittest.TestCase): # 类必须Test开头,继承TestCase才能识别为用例类
url = "http://api/xxx/teacher/xxx"
def test_teacher_edit(self): # 一条测试用例,test_开头
data = {
'wechat_id': '',
'auth_username': 'caolihui',
'real_name': '曹立辉',
'wx_nickname': '帅辉55',
'auth_uid': '1000002640',
'mid': '1627976031427201',
'employee_id': 'W0006634',
'id': '368',
'type': '1',
'auth_role': '',
'owner_id': '0',
'status': '1',
'create_time': '2021-09-07 16:28:06',
'update_time': '2021-09-07 16:28:06'
}
files=[
]
headers = {
'Cookie': c_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ8rliLrbhe-hoOSQFs7Na6PGY}'
}
response = requests.post(url=self.url, headers=headers, files=files, data=data)
self.assertIn('200', response.text) # 断言
print('老师编辑成功')
if __name__ == '__main__': # 如果是直接从当前模块执行(非别的模块调用本模块)
unittest.main(verbosity=2) # 运行本测试类所有用例,verbosity为结果显示级别
用例断言
unittest断言方法,常用的以下几种:
判断相等
- assertEqual(a,b)/assertNotEqual(a,b): 断言值是否相等
- assertIs(a,b)/assertIsNot(a,b): 断言是否同一对象(内存地址一样)
- assertListEqual(list1, list2)/assertItemNotEqual(list1, list2): 断言列表是否相等
- assertDictEqual(dict1, dict2)/assertDictNotEqual(dict1, dict2): 断言字典是否相等
是否为空
- assertIsNone(a)/assertIsNotNone(a)
判断真假
- assertTrue(a)/assertFalse(a)
是否包含
- assertIn(a,b)/assertNotIn(a,b) # b中是否包含a
大小判断
- assertGreater(a,b)/assertLess(a,b) : 断言a>b / 断言a<b
- assertGreaterEqual(a,b)/assertLessEqual: 断言a>=b / 断言a<=b
类型判断
- assertIsInstance(a,dict)/assertNotIsInstance(a,list) # 断言a为字典 / 断言a非列表
实例
import unittest
case = unittest.TestCase()
case.assertEqual(1,2.0/2) # 通过1=2.0/2
case.assertEqual(1, True) # 通过
case.assertIs(1.0, 2.0/2) # 失败,不是同一对象
case.assertListEqual([1,2],[1,2]) # 通过(顺序要一致)
case.assertDictEqual({"a":1,"b":2},{"b":2,"a":1}) # 通过,字典本无序
case.assertIsNone({}) # 失败
case.assertFalse({}) # 通过,空字典为False
case.assertIn("h","hello") # 通过
case.assertGreater(3,2) # 通过,3>2
case.assertIsInstance({"a":1}, dict) # 通过
执行结果
完整的接口测试用例
- 数据准备:准备测试数据,可手工准备,也可使用代码准备(通常涉及数据库操作)
- 环境检查:如果手工准备的数据,连接数据库进行环境检查会使用例更健壮
- 发送请求:发送接口请求
- 响应断言/数据库断言:响应断言后,还需要进行数据库断言,以确保接口数据库操作的正确性
- 数据清理:如果接口有更数据库操作,断言结束后需要还原更改
本次教程暂不涉及
用例组织及运行
import unittest
# 从两个用例里导入测试类
from test_teacher import TestTeacherEdit
from test_query import Testquery
from HTMLTestReportCN import HTMLTestRunner
suite = unittest.TestSuite()
# 添加单个用例
suite.addTest(TestTeacherEdit('test_teacher_edit'))
# 添加多个用例
suite.addTests([Testquery('test_teacher_c'),Testquery('test_periods_c'),Testquery('test_class_c'),Testquery('test_first_polling')])
# 运行测试集,verbosity显示级别,运行顺序为添加到suite中的顺序
unittest.TextTestRunner(verbosity=2).run(suite)
生成测试报告
生成文本报告
import unittest
# 从两个用例里导入测试类
from test_teacher import TestTeacherEdit
from test_query import Testquery
from HTMLTestReportCN import HTMLTestRunner
suite = unittest.defaultTestLoader.discover("./")
生成HTML报告
- 下载HTMLTestRunnerCN
- 解压并将解压包中python3x文件夹下的HTMLTestRunnerCN.py拷贝到项目目录
- 在目录下新建脚本run_all_xxx.py
import unittest
# 从两个用例里导入测试类
from test_teacher import TestTeacherEdit
from test_query import Testquery
from HTMLTestReportCN import HTMLTestRunner
suite = unittest.defaultTestLoader.discover("./")
f = open("report.html", 'wb') # 二进制写格式打开要生成的报告文件
HTMLTestRunner(stream=f,title="自动化测试系统",description="xxxx接口测试",tester="曹立辉").run(suite)
f.close()
- 运行程序,会在当前文件夹下生成report.html,用浏览器打开即可
到此基本实现了一个简单的接口自动化。