python之unittest框架使用
一、unittest框架
unittest属于python内置的单元测试框架。
二、unittest框架的核心概念
test case:指测试用例。unittest中提供了一个基本类TestCase,可以用来创建新的测试用例;
test fixure:测试夹具,用于测试用例环境的搭建和销毁。即用例测试前准备环境的搭建(SetUp前置条件),测试后环境的还原(TearDown后置条件),比如测试前需要登录获取token等就是测试用例需要的环境,运行完后执行下一个用例前需要还原环境,以免影响下一条用例的测试结果。(以及数据库的连接和断开等)
test suite:测试套件,用来把需要一起执行的测试用例集中放到一块执行,相当于一个篮子。我们可以使用TestLoader来加载测试用例到测试套件中。
test runner:用来执行测试用例的,并返回测试用例的执行结果。它还可以用图形或者文本接口,把返回的测试结果更形象的展现出来,如:HTMLTestRunner。
三、unittest断言
python中的assert断言,使用方法比较简单,即assert(
;表达式, 提示信息
)
而unittest框架中也提供了一个自带的断言方式,主要有以下几种:
方法 | 检查 |
---|---|
assertEqual(a, b,msg) | a ==b |
assertNotEqual(a, b) | a !=b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | Bool(x) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a,b) |
assertNotIsInstance(a, b) | not isinstance(a,b) |
四、unittest核心概念详解
1、TestCase测试用例:
使用unittest编写用例,必须遵守以下规则:
(1)测试文件必须先import unittest
(2)测试类必须继承unittest.TestCase
(3)测试方法必须以“test”开头,且执行顺序会按照方法名的ASCII值排序,所以,写多个有关联的测试用例的时候请一定注意方法名称。
2、TestFixture测试固件:
unittest的测试固件有两种:
(1)setUp()
和tearDown()
:在每个测试方法执行前后,均会执行该方法。
(2)setUpClass()
和tearDownClass():整个测试类中的用例执行前后,会执行此方法。
(1)unittest.TestSuite()
addTest()
:添加单个测试用例方法。addTest([..])
:添加多个测试用例方法,方法名存在一个列表,用逗号隔开。
loadTestsFromTestCase(测试类名)
:添加一个测试类。loadTestsFromModule(模块名)
:添加一个模块。discover(测试用例的所在目录)
:指定目录去加载,会自动寻找这个目录下所有符合命名规则的测试用例。
if __name__ == "__main__":
# verbosity参数可以控制输出结果的详细程度,默认为1.若为0,则简化输出;若为2,则详细输出。
# unittest.main():搜索该模块下所有以test开头的测试用例方法,并自动执行
# unittest.main(verbosity=1)
suite = unittest.TestSuite() # 方式1:添加单个或多个测试用例
# case1 = MyTest('test_register_success')
# case2 = MyTest('test_pwd_not_cpwd')
# case3 = MyTest('test_username_lt6')
# suite.addTest(case3)
# suite.addTests([case1, case2]) # 方式2:添加一个测试类
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(test_register.TestRegister)) # 方式3:添加一个模块(不过试了不可以,按照提示也不行。。。)
# loader = unittest.TestLoader()
# suite.addTests(loader.loadTestsFromModule(test_register)) # 方式4:指定测试用例所在的路径,进行加载(默认是寻找目录下test*.py
文件)
# pattern正则表达式匹配测试用例的文件名
loader = unittest.TestLoader()
suite.addTest(loader.discover(r"E:", pattern="test_*.py"))
runner = HTMLTestRunner.HTMLTestRunner(
stream=open("report.html", 'wb'),
description="注册接口测试详情",
title="注册接口测试报告"
)
# 使用启动器去执行测试套件里的用例
runner.run(suite)
相关参数说明:
stream
:指定输出的方式tester
:报告中要显示的测试人员的名字description
:报告中要显示的面熟信息title
:测试报告的标题verbosity
:表示测试报告信息的详细程度,一共三个值,默认是2- 0 (静默模式):你只能获得总的测试用例数和总的结果,如:总共100个 失败10 成功90
- 1 (默认模式):类似静默模式,只是在每个成功的用例前面有个. 每个失败的用例前面有个F
- 2 (详细模式):测试结果会显示每个测试用例的所有相关的信息
@unittest.skip(reason):无条件跳过装饰的测试,并说明跳过测试的原因。
@unittest.skipIf(reason):条件为真时,跳过装饰的测试,并说明跳过测试的原因。
@unittest.skipUnless(reason):条件为假时,跳过装饰的测试,并说明跳过测试的原因。
@unittest.expectedFailure():标记该测试预期为失败 ,如果该测试方法运行失败,则该测试不算做失败。
# get_unittest.py
import unittest
from Test1 import Register
import HTMLTestRunner
import test_register # 继承unittest.TestCase
class MyTest(unittest.TestCase):
a = 10
def setUp(self):
self.Reg = Register()
# print("测试开始") def tearDown(self):
pass
# print("测试完成") @classmethod
def setUpClass(cls):
print("注册接口模块 -- 测试开始") @classmethod
def tearDownClass(cls):
print("注册接口模块 -- 测试完成") # 测试方法必须以"test"开头
@unittest.skip("跳过该用例")
def test_register_success(self):
'''注册成功'''
data = ("hahaha15", "Bc123456", "Bc123456")
expected = {"error_code": 0, "msg": "注册成功!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result)
@unittest.skipIf(3>2, "跳过该用例")
def test_pwd_not_cpwd(self):
'''
注册失败,两次输入密码不一样
data: 测试数据
expected: 预期结果
result: 实际结果
''' data = ("hahaha14", "Bc123456", "Bc12345")
expected = {"error_code": 3004, "msg": "两次输入密码不一致!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) @unittest.skipUnless(3<2, "跳过该用例")
def test_username_lt6(self):
'''注册失败,用户名长度小于6位'''
data = ("haha", "Bc123456", "Bc123456")
expected = {"error_code": 3002, "msg": "用户名长度为6-10位!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) if __name__ == "__main__":
# unittest.main():搜索该模块下所有以test开头的测试用例方法,并自动执行
# unittest.main(verbosity=1)
suite = unittest.TestSuite() # 方式1:添加单个或多个测试用例
# case1 = MyTest('test_register_success')
# case2 = MyTest('test_pwd_not_cpwd')
# case3 = MyTest('test_username_lt6')
# suite.addTest(case3)
# suite.addTests([case1, case2]) # 方式2:添加一个测试类
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(test_register.TestRegister)) # 方式3:添加一个模块(不过试了不可以,按照提示也不行。。。)
# loader = unittest.TestLoader()
# suite.addTests(loader.loadTestsFromModule(test_register)) # 方式4:指定测试用例所在的路径,进行加载
# pattern匹配了加载的测试用例文件
loader = unittest.TestLoader()
suite.addTest(loader.discover(r"E:", pattern="test_*.py"))
runner = HTMLTestRunner.HTMLTestRunner(
stream=open("report.html", 'wb'),
description="注册接口测试详情",
title="注册接口测试报告"
)
# 使用启动器去执行测试套件里的用例
runner.run(suite)
# test_register.py import unittest
from Test1 import Register class TestRegister(unittest.TestCase): def setUp(self):
self.Reg = Register()
# print("测试开始") def tearDown(self):
pass
# print("测试完成") @classmethod
def setUpClass(cls):
print("注册接口模块 -- 测试开始") @classmethod
def tearDownClass(cls):
print("注册接口模块 -- 测试完成") # 测试方法必须以"test"开头
def test_register_success(self):
'''注册成功'''
data = ("hahaha15", "Bc123456", "Bc123456")
expected = {"error_code": 0, "msg": "注册成功!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) def test_pwd_not_cpwd(self):
'''
注册失败,两次输入密码不一样
data: 测试数据
expected: 预期结果
result: 实际结果
''' data = ("hahaha14", "Bc123456", "Bc12345")
expected = {"error_code": 3004, "msg": "两次输入密码不一致!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) def test_username_lt6(self):
'''注册失败,用户名长度小于6位'''
data = ("haha", "Bc123456", "Bc123456")
expected = {"error_code": 3002, "msg": "用户名长度为6-10位!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result)
# Test1.py import requests
import json class Register(): def register(self, username, pwd, cpwd):
url = "http://api.nnzhp.cn/api/user/user_reg"
method = "post"
form_body = {
"username": username,
"pwd": pwd,
"cpwd": cpwd
}
response = requests.request(url=url, method=method, data=form_body).text
return json.loads(response) if __name__ == "__main__":
reg = Register()
data = ("hahaha1", "Bc123456", "Bc123456")
expected = {"error_code": 0, "msg": "注册成功!"}
result = reg.register(*data)
print(result)
print(type(result))
参考:https://www.cnblogs.com/miki-peng/p/12501341.html
最新文章
- [daily][toolchain] 我的日常软件集
- QT5.5.0版本添加icon图标步骤
- UOJ147 斗地主
- hadoop2.x NameNode 的共享存储实现
- Dockerfile指令
- linux安全体系
- centos安装crontab:
- Chrome 建立SOCKS5代理
- python中从文件中读取数据
- [C#] BarcodeLib -- 一个精简而不失优雅的条形码生成库
- nyoj49 开心的小明 01背包
- hdu 5538(水)
- 基于容器的ETCD集群脚本
- 最全,可直接用的一些正则校验,判断邮箱,手机号码,车牌号,身份证号,网址,账号,密码,ip,去掉html格式,工商税号等。
- 洛谷 P4074 [WC2013]糖果公园 解题报告
- 1. 感知机原理(Perceptron)
- 为已经存在的本地项目添加git,以及从远程仓库拉取代码并切换远程分支
- spring boot(9)-mybatis关联映射
- 第十章I/O
- ajax的坑
热门文章
- Android 开发学习进程0.19 webview 的使用
- 《MySQL必知必会》简介、使用
- Salesforce学习笔记之Actions and Recommendations(续)
- 几种定时任务(Timer、TimerTask、ScheduledFuture)的退出—结合真实案例【JAVA】
- java自动拆装箱
- gpio模拟i2c驱动
- C++ Templates (1.5 重载函数模板 Overloading Function Templates)
- 易盛信息9.0外盘期货行情数据API接口公共授权开发包例子代码
- 利用python爬取贝壳网租房信息
- 温故知新——Spring AOP