若有任何学习问题,能够添加做者微信:lockingfreehtml
Python接口测试实战1(上)- 接口测试理论
Python接口测试实战1(下)- 接口测试工具的使用
Python接口测试实战2 - 使用Python发送请求
Python接口测试实战3(上)- Python操做数据库
Python接口测试实战3(下)- unittest测试框架
Python接口测试实战4(上) - 接口测试框架实战
Python接口测试实战4(下) - 框架完善:用例基类,用例标签,从新运行上次失败用例
Python接口测试实战5(上) - Git及Jenkins持续集成
Python接口测试实战5(下) - RESTful、Web Service及Mock Serverpython
更多学习资料请加QQ群: 822601020获取git
参考:unittest官方文档github
为何要使用unittest?
在编写接口自动化用例时,咱们通常针对一个接口创建一个.py文件,一条测试用例封装为一个函数(方法),可是在批量执行的过程当中,若是其中一条出错,后面的用例就没法执行。使用测试框架能够互不影响的用例执行及更灵活的执行控制数据库
unittest特色json
unittest几大组成部分api
test_user_login.py
test_user_login.py
# 文件必须test_开头浏览器
import unittest # 导入unittest import requests class TestUserLogin(unittest.TestCase): # 类必须Test开头,继承TestCase才能识别为用例类 url = 'http://115.28.108.130:5000/api/user/login/' def test_user_login_normal(self): # 一条测试用例,必须test_开头 data = {"name": "张三", "password": "123456"} res = requests.post(url=self.url, data=data) self.assertIn('登陆成功', res.text) # 断言 def test_user_login_password_wrong(self): data = {"name": "张三", "password": "1234567"} res = requests.post(url=self.url, data=data) self.assertIn('登陆失败', res.text) # 断言 if __name__ == '__main__': # 若是是直接从当前模块执行(非别的模块调用本模块) unittest.main(verbosity=2) # 运行本测试类全部用例,verbosity为结果显示级别
用例执行顺序:并不是按书写顺序执行,而是按用例名ascii码前后顺序执行微信
用例断言
unittest提供了丰富的断言方法,经常使用为如下几种:网络
示例:
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) # 经过
断言是unittest.TestCase的一种方法,经过断言判断用例是否经过(Pass/Fail)
Test Fixtures(用例包裹方法)
Test Fixtures即setUp(用例准备)及tearDown(测试清理)方法,用于分别在测试前及测试后执行
按照不一样的做用范围分为:
import unittest def setUpModule(): # 当前模块执行前只执行一次 print('=== setUpModule ===') def tearDownModule(): # 当前模块执行后只执行一次 print('=== tearDownModule ===') class TestClass1(unittest.TestCase): @classmethod # 声明为类方法(必须) def setUpClass(cls): # 类方法,注意后面是cls,整个类只执行一次 print('--- setUpClass ---') @classmethod def tearDownClass(cls): print('--- tearDownClass ---') def setUp(self): # 该类中每一个测试用例执行一次 print('... setUp ...') def tearDown(self): print('... tearDown ...') def test_a(self): # 测试用例 print("a") def test_B(self): # 大写B的ascii比小写a靠前,会比test_a先执行 print("B") class TestClass2(unittest.TestCase): # 该模块另外一个测试类 def test_A(self): print("A") if __name__ == '__main__': unittest.main()
执行结果:
=== setUpModule === --- setUpClass --- ... setUp ... B ... tearDown ... ... setUp ... a ... tearDown ... --- tearDownClass --- A === tearDownModule === ... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
完整的接口测试用例
一条完整的测试接口用例须要包含:
test_user_reg.py
import unittest import requests from db import * # 导入db.py文件,源码见上篇 # 数据准备 NOT_EXIST_USER = '范冰冰' EXIST_USER = '张三' class TestUserReg(unittest.TestCase): url = 'http://115.28.108.130:5000/api/user/reg/' def test_user_reg_normal(self): # 环境检查 if check_user(NOT_EXIST_USER): del_user(NOT_EXIST_USER) # 发送请求 data = {'name': NOT_EXIST_USER, 'password': '123456'} res = requests.post(url=self.url, json=data) # 指望响应结果,注意字典格式和json格式的区别(若是有true/false/null要转化为字典格式) except_res = { "code": "100000", "msg": "成功", "data": { "name": NOT_EXIST_USER, "password": "e10adc3949ba59abbe56e057f20f883e" } } # 响应断言(总体断言) self.assertDictEqual(res.json(), except_res) # 数据库断言 self.assertTrue(check_user(NOT_EXIST_USER)) # 环境清理(因为注册接口向数据库写入了用户信息) del_user(NOT_EXIST_USER) def test_user_reg_exist(self): # 环境检查 if not check_user(EXIST_USER): add_user(EXIST_USER) # 发送请求 data = {'name': EXIST_USER, 'password': '123456'} res = requests.post(url=self.url, json=data) # 指望响应结果,注意字典格式和json格式的区别(若是有true/false/null要转化为字典格式) except_res = { "code": "100001", "msg": "失败,用户已存在", "data": { "name": EXIST_USER, "password": "e10adc3949ba59abbe56e057f20f883e" } } # 响应断言(总体断言) self.assertDictEqual(res.json(), except_res) # 数据库断言(没有注册成功,数据库没有添加新用户) # 环境清理(无需清理) if __name__ == '__main__': unittest.main(verbosity=2) # 运行全部用例
除了使用unittest.main()运行整个测试类以外,咱们还能够经过TestSuite来灵活的组织要运行的测试集
import unittest from test_user_login import TestUserLogin from test_user_reg import TestUserReg # 从上面两个例子里导入测试类 suite = unittest.TestSuite() suite.addTest(TestUserLogin('test_user_login_normal')) # 添加单个用例 suite.addTests([TestUserReg('test_user_reg_normal'),TestUserReg('test_user_reg_exist')]) # 添加多个用例 # 运行测试集 unittest.TextTestRunner(verbosity=2).run(suite) # verbosity显示级别,运行顺序为添加到suite中的顺序
import unittest from test_user_login import TestUserLogin suite1 = unittest.makeSuite(TestUserLogin, 'test_user_login_normal') # 使用测试类的单条用例制做测试集 suite2 = unittest.makeSuite(TestUserLogin) # 使用整个测试类制做测试集合(包含该测试类全部用例) unittest.TextTestRunner(verbosity=2).run(suite1)
improt unittest from test_user_login import TestUserLogin suite = unittest.TestLoader().loadTestsFromTestCase(TestUserLogin) # 加载该测试类全部用例并生成测试集 unittest.TextTestRunner(verbosity=2).run(suite)
import unittest suite = unittest.defaultTestLoader.discover("./") # 遍历当前目录及子包中全部test_*.py中全部unittest用例 unittest.TextTestRunner(verbosity=2).run(suite)
注意:
__init__.py
文件,及应为的Python包import unittest from test_user_login import TestUserLogin suite1 = unittest.TestSuite() suite1.addTest(TestUserLogin('test_user_login_normal')) suite2 = makeSuite(TestUserLogin, 'test_user_login_password_wrong') suite = unittest.TestSuite([suite1, suite2]) # 将两个测试集组合为一个 unittest.TextTestRunner(verbosity=2).run(suite)
生成文本报告
import unittest suite = unittest.defaultTestLoader.discover("./") # 输出测试结果到文本文件 with open("result.txt","w") as f: unittest.TextTestRunner(stream=f,verbosity=2).run(suite) # 将输出流stream输出到文件
生成HTML报告
run_all.py
import unittest from HTMLTestReportCN import HTMLTestRunner suite = unittest.defaultTestLoader.discover("./") f = open("report.html", 'wb') # 二进制写格式打开要生成的报告文件 HTMLTestRunner(stream=f,title="Api Test",description="测试描述",runner="卡卡").run(suite) f.close()
源码下载连接:https://pan.baidu.com/s/1gXwYOCL6BfRW4XVgxkCpIA 密码:jdgo
此为北京龙腾育才 Python高级自动化(接口测试部分)授课笔记
课程介绍
想要参加现场(北京)/网络课程的能够联系做者微信:lockingfree
- 高效学习,快速掌握Python自动化全部领域技能
- 同步快速解决各类问题
- 配套实战项目练习