目录
一、http请求模块的封装
1.1 __name__函数
__name__是一个特殊的全局变量
它输出当前脚本的名字,如果该脚本被导入到其他脚本执行,那么它就是当前执行脚本的文件名
如果直接运行当前脚本,那么它等于“__main__”
#文件名为test123.py
print(__init__)
#直接执行运行test.py文件,打印内容为__main__
#文件名为haha.py
import test123
#导入到haha.py后,运行haha.py文件,打印内容为test123
使用:在当前脚本调试页面代码
if __name__ == '__main__':
"""执行当前脚本时执行这里的代码,其他文件调用该文件时不执行此处代码"""
print('仅在当前脚本执行时有效')
调试unittest中用例脚本
if __name__ == '__main__':
unittest.main()
1.2http请求的封装
因为发送请求需要在多个地方使用,为了代码复用,需对该功能进行封装
import requests
#此处->requests.Response的作用是表示返回的类型,其他模块调用时,pycharm可以进行提示
def send_http_requests(url,method,**kwargs) ->requests.Response:
"""
发送http请求
:param url:请求路径
:param method:请求方式
:param kwargs:params、data、json、headers.....
:return:response
"""
#把方法名小写化,防止误传
method=method.lower()
#获取对应的方法
return getattr(requests,method)(url,**kwargs)
#方法的调用
res=send_http_requests(url='http://www.baidu.com',method='get')
print(res.json)
函数注释自动生成
-
修改File > Settings > Tools > Python Integrated Tools > Docstring format > reStructuredText
-
在函数方法名下输入三个双(单)引号,回车之后自动生成
二、单元测试框架unittest
unittest是Python自带的一个单元测试框架
2.1作用
-
管理用例
-
批量执行用例
-
组织运行结果/报告
-
让代码更稳健
-
可拓展
2.2测试用例(TestCase)
unittest提供了一个基类TestCase用来创建测试用例;
创建测试用例,导入unittest模块后,需要创建一个类,来继承TestCase;
2.2.1单元测试函数
类中每个方法代表一个测试用例,方法名必须以test开头,unittest只会识别以test开头的方法为测试用例
import unittest
class TestAbs(unittest.TestCase):
name='测试abs函数'
def test_negative_num(self):
'''
测试负数
:return:
'''
# 1.测试数据
data=-1
except_data=1
# 2.测试步骤
res=abs(data)
# 3.断言
print(1)
self.assertEqual(res,except_data,msg='断言运行结果')
def test_zero(self):
'''
测试0
:return:
'''
# 1.测试数据
data=0
except_data=0
# 2.测试步骤
res=abs(data)
# 3.断言
print(2)
self.assertEqual(res,except_data,msg='断言运行结果')
def test_postive_num(self):
'''
测试正数
:return:
'''
# 1.测试数据
data=1
except_data=1
# 2.测试步骤
res=abs(data)
# 3.断言
print(3)
self.assertEqual(res,except_data,msg='断言运行结果')
选择运行方式:
2.2.2测试函数的执行顺序
测试用例执行时不是按照定义的顺序执行,而是按照ascii码排序,可以在test_后加上数字,定义执行顺序
test_1.... 、 test_2.....
#文件名test_abs.py
import unittest
class TestAbs(unittest.TestCase):
name='测试abs函数'
#修改测试用例名称
def test_1negative_num(self):
'''
测试负数
:return:
'''
# 1.测试数据
data=-1
except_data=1
# 2.测试步骤
res=abs(data)
# 3.断言
print(1)
self.assertEqual(res,except_data,msg='断言运行结果')
#修改测试用例名称
def test_2zero(self):
'''
测试0
:return:
'''
# 1.测试数据
data=0
except_data=0
# 2.测试步骤
res=abs(data)
# 3.断言
print(2)
self.assertEqual(res,except_data,msg='断言运行结果')
#修改测试用例名称
def test_3postive_num(self):
'''
测试正数
:return:
'''
# 1.测试数据
data=1
except_data=1
# 2.测试步骤
res=abs(data)
# 3.断言
print(3)
self.assertEqual(res,except_data,msg='断言运行结果')
2.3用例收集器(TestLoader)
if __name__ == '__main__':
#testcase为文件路径
re=unittest.TestLoader().discover('testcase')
print(re)
收集规则可以通过patterns自定义,默认是以test开头的模块,一般不做修改。
会到指定目录下递归去寻找符合patterns规则的模块中继承了TestCase的类。
注意:如果有嵌套的文件夹,一定要在文件夹中加入__init__.py,其实就是把文件夹变成一个Python的包。
2.4测试套件(TestSuite)
用例收集器,会返回能够收集到的所有的用例,封装成测试套件类型。
测试套件,其实就是一系列的测试用例类。
添加单个测试用例:
import unittest
import testcase01
suite = unittest.TestSuite()
suite.addTest(testcase01.MyTest("test_001"))
suite.addTest(testcase01.MyTest("test_002"))
# 只是把测试用例添加到了测试套件中,并不是执行测试用例
添加测试用例类:
import unittest
import testcase01
suite = unittest.TestSuite()
# 只是把测试用例添加到了测试套件中,并不是执行测试用例
suite.addTest(unittest.makeSuite(testcase01.MyTest))
2.5测试运行器(TextTestRunner)
TextTestRunner是用来执行和输出测试用例和测试套件的结果的。
import unittest
#输出内容在控制台
if __name__ == '__main__':
re=unittest.TestLoader().discover('testcase')
#实例化TextTestRunner对象
runner=unittest.TextTestRunner()
#调用对象的run方法,执行测试用例
runner.run(re)
#输出内容问txt报告
if __name__ == '__main__':
re=unittest.TestLoader().discover('testcase')
# 保存在报告文件中
with open('reports/测试报告.txt','w',encoding='utf-8') as f:
runner=unittest.TextTestRunner(f)
runner.run(re)
2.6测试脚手架(FIXture)
可以在测试用例执行之前自动调用指定的函数,在测试用例执行之后自动调用指定的函数。
对象、方法:
-setUp会在每个单元函数测试开始前执行。
import unittest
class MyTest(unittest.TestCase):
def setUp(self) -> None:
print('setup被自动调用了')
def test_01(self):
print('测试用例01')
def test_02(self):
print('测试用例02')
if __name__ == '__main__':
MyTest()
-tearDown会在每个单元测试函数执行结束之后执行。
import unittest
class MyTest(unittest.TestCase):
def tearDown(self) :
print('teardown被自动调用了')
def test_01(self):
print('测试用例01')
def test_02(self):
print('测试用例02')
if __name__ == '__main__':
MyTest()
类方法,记得使用@classmethod去修饰:
-setUpclass在整个测试用例类开始执行前执行。
import unittest
class MyTest(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print('setupclass自动调用了')
def test_01(self):
print('测试用例01')
def test_02(self):
print('测试用例02')
if __name__ == '__main__':
MyTest()
-tearDownclass在整个测试用例类执行结束之后执行。
import unittest
class MyTest(unittest.TestCase):
@classmethod
def tearDownClass(cls):
print('teardownclass自动调用了')
def test_01(self):
print('测试用例01')
def test_02(self):
print('测试用例02')
if __name__ == '__main__':
MyTest()
模块方法:
-setUpModule在.py文件开始执行前时调用
import unittest
def setUpModule():
print('setUpModule自动调用了')
class MyTest(unittest.TestCase):
def test_01(self):
print('测试用例01')
class HerTest(unittest.TestCase):
def test_02(self):
print('测试用例02')
if __name__ == '__main__':
MyTest()
-tearDownModule在.py文件执行完成时调用
import unittest
def tearDownModule():
print('tearDownModule自动调用了')
class MyTest(unittest.TestCase):
def test_01(self):
print('测试用例01')
class HerTest(unittest.TestCase):
def test_02(self):
print('测试用例02')
if __name__ == '__main__':
MyTest()
2.7断言
断言方法 | 断言描述 |
---|---|
assertTrue(expr, msg=None) | 验证 expr 是 true,如果为 false,则 fail |
assertFalse(expr, msg=None) | 验证 expr 是 false,如果为 true,则 fail |
assertEqual(expected, actual, msg=None) | 验证 expected==actual , 不等则 fail |
assertNotEqual(first, second, msg=None) | 验证 first != second, 相等则 fail |
assertIsNone(obj, msg=None) | 验证 obj 是 None , 不是则 fail |
assertIsNotNone(obj, msg=None) | 验证 obj 不是 None , 是则 fail |
assertIn(member, container, msg=None) | 验证是否 member in container |
assertNotIn(member, container, msg=None) | 验证是否 member not in container |
三、unittest测试流程
3.1编写用例
1.导入unittest和被测试的函数
创建测试用例类,继承unittest.TestCase
2.创建单元测试函数
以test开头,编写测试数据,测试步骤,断言
#在test_case文件夹下创建test_abs.py文件
import unittest
class TestAbs(unittest.TestCase):
name='测试abs函数'
#修改测试用例名称
def test_1negative_num(self):
'''
测试负数
:return:
'''
# 1.测试数据
data=-1
except_data=1
# 2.测试步骤
res=abs(data)
# 3.断言
print(1)
self.assertEqual(res,except_data,msg='断言运行结果')
3.2收集用例
unittest.TestLoader().discover(路径/模块名)
用例模块名默认为test*.py
返回测试套件unittest.TestSuit
3.3运行用例并生成测试报告
testrunner 测试运行器
unittest.TextTestRunner 文本报告
#创建main.py入口函数
import unittest
if __name__ == '__main__':
#收集用例并返回测试套件
re=unittest.TestLoader().discover('testcase')
#运行器运行并生成报告
with open('reports/测试报告.txt','w',encoding='utf-8') as f:
runner=unittest.TextTestRunner(f)
runner.run(re)
3.4目录情况
四、生成html报告
导入模块顺序:系统级模块、第三方模块、自定义模块
4.1HTMLTestRunner
可修改HTMLTestRunner.py中默认信息
将HTMLTestRunner.py文件放在common文件夹下
#main.py文件
import unittest
from common.HTMLTestRunner import HTMLTestRunner
if __name__ == '__main__':
re=unittest.TestLoader().discover('testcase')
with open('reports/测试报告.html','wb') as f:
runner=HTMLTestRunner(f)
runner.run(re)
4.2 BeautifulReport
安装:
pip install beautifulreport
使用:
#main.py文件
import unittest
from BeautifulReport import BeautifulReport
if __name__ == '__main__':
re=unittest.TestLoader().discover('testcase')
br=BeautifulReport(re)
br.report(description='项目描述',filename='reports/测试报告.html')