Python单元测试框架unittest/反射
1)写用例 TestCase
2)执行用例 1:TestSuite存储用例,2:TestLoader找用例,存储用例,存放指定的TestSuite
3)对比实际结果/期望结果,判定用例是否通过#断言Assert
4)出局测试报告TextTestRunner
1.测试类
import requests class HttpRequest(): def __init__ (self, method, url, param=None, headers=None, cookie= None):
self.method =method # method:请求方式 self.url=url # url:请求的url self.param=param # param:请求参数 self.headers=headers # headers:请求头 self.cookie=cookie # cookie:请求的cookie值 def http_request(self): if self.method.lower()== " post " : return requests.post(self.url,self.param) elif self.method.lower()== " get " : return requests.get(self.url,self.param,headers=self.headers,cookies= self.cookie) else : print ( " 请求方式错误:{0} " .format(self.method))
2.TestCase/断言/异常处理
import unittest # 引入unittest框架 from test01.qabujiaban_class import HttpRequest # 引入测试类 # 编写一个存储测试用例的类 class TestHttp(unittest.TestCase): # 用例类继承unittest.TestCase用于编写测试用例 # 正确登陆测试用例 def test_login_yes(self): # 测试用例函数必须test_开头,否则框架无法识别当前是用例 login_url = " http://www.qabujiaban.com/user/login " data = { " username " : " uuuu222都44 " , " password " : " WJHasb124*1 " }
res = HttpRequest( " Post " , login_url, data).http_request() print ( " 登陆响应文本: " , res.json()) # try :
self. assertEqual ( " 0000 " , res.json()[ " code " ]) # 断言,期望值==实际值 except AssertionError as e: print ( " 断言错误异常抛出:{0} " .format(e)) raise e # 抛出异常 # 错误登陆测试用例 def test_login_no(self):
login_url = " http://www.qabujiaban.com/user/login " data = { " username " : " uuuu222都44 " , " password " : " 123456 " } # 密码错误 res = HttpRequest( " Post " , login_url, data).http_request() print ( " 登陆响应文本: " , res.json()) # try :
self. assertEqual ( " 0000 " , res.json()[ " code " ]) # 断言,期望值==实际值 except AssertionError as e: print ( " 断言错误异常抛出:{0} " .format(e)) raise e # 抛出异常 if __name__ == ' __main__ ' :
unittest.main() # 执行全部测试用例
执行结果: ============================= test session starts ============================= platform win32 -- Python 3.7.3, pytest-7.2.0, pluggy-1.0 .0
rootdir: C:\Users\Administrator\PycharmProjects\demo\test01
plugins: html -3.2.0, metadata-2.0.4collected 2 items
testdemo01.py [ 100% ] ============================== 2 passed in 0.35s ============================== Process finished with exit code 0
.登陆响应文本: { ' code ' : ' 0002 ' , ' message ' : ' 登陆失败,密码错误 ' }
.登陆响应文本: { ' code ' : ' 0000 ' , ' message ' : ' 登陆成功 ' , ' login_time ' : ' 2022-59-19 11:12:04 ' , ' create_time ' : ' 2021-23-28 04:12:19 ' }
注意:
执行结果中,E表示错误,F表示失败, . 点表示成功
3.unittest.addTest()
import unittest from test01.demo_case import TestHttp # 引入测试用例类 suite = unittest.TestSuite() # 存储器,存储用例 # 第一个用例 suite.addTest(TestHttp("test_login_yes")) # 添加要执行的用例 # 第二个用例 suite.addTest(TestHttp("test_login_no" ))
runner = unittest.TextTestRunner()
runner.run(suite) # 执行
执行结果:
.登陆响应文本: { ' code ' : ' 0000 ' , ' message ' : ' 登陆成功 ' , ' login_time ' : ' 2022-12-20 12:12:33 ' , ' create_time ' : ' 2021-23-28 04:12:19 ' }
登陆响应文本: { ' code ' : ' 0002 ' , ' message ' : ' 登陆失败,密码错误 ' }
. ---------------------------------------------------------------------- Ran 2 tests in 0.275s
OK
Process finished with exit code 0
4.loader.loadTestsFromTestCase()
import unittest from test01.demo_case import TestHttp # 引入测试用例类 suite = unittest.TestSuite() # 存储器,存储用例 # #第一个用例 # suite.addTest(TestHttp("test_login_yes"))#添加要执行的用例 # #第二个用例 # suite.addTest(TestHttp("test_login_no")) loader = unittest.TestLoader() # 创建加载器 suite.addTest(loader.loadTestsFromTestCase(TestHttp)) # 通过类名加载 runner = unittest.TextTestRunner()
runner.run(suite) # 执行
执行结果:
登陆响应文本: { ' code ' : ' 0002 ' , ' message ' : ' 登陆失败,密码错误 ' }
..
登陆响应文本: { ' code ' : ' 0000 ' , ' message ' : ' 登陆成功 ' , ' login_time ' : ' 2022-23-20 12:12:16 ' , ' create_time ' : ' 2021-23-28 04:12:19 ' } ---------------------------------------------------------------------- Ran 2 tests in 0.288s
OK
Process finished with exit code 0
5.loader.loadTestFromModule()
import unittest # from test01.demo_case import TestHttp#引入测试用例类 from test01 import demo_case#引入模块
suite = unittest.TestSuite() # 存储器,存储用例 # #第一个用例 # suite.addTest(TestHttp("test_login_yes"))#添加要执行的用例 # #第二个用例 # suite.addTest(TestHttp("test_login_no")) loader = unittest.TestLoader() # 创建加载器 # suite.addTest(loader.loadTestsFromTestCase(TestHttp))#通过类名加载 suite.addTest(loader.loadTestsFromModule(demo_case)) # 通过类名加载 runner = unittest.TextTestRunner()
runner.run(suite) # 执行
执行结果:
.登陆响应文本: { ' code ' : ' 0002 ' , ' message ' : ' 登陆失败,密码错误 ' }
. ---------------------------------------------------------------------- Ran 2 tests in 0.259s
OK
登陆响应文本: { ' code ' : ' 0000 ' , ' message ' : ' 登陆成功 ' , ' login_time ' : ' 2022-26-20 12:12:51 ' , ' create_time ' : ' 2021-23-28 04:12:19 ' }
Process finished with exit code 0
6.TextTestRunner()
import unittest # from test01.demo_case import TestHttp#引入测试用例类 from test01 import demo_case
suite = unittest.TestSuite() # 存储器,存储用例 # #第一个用例 # suite.addTest(TestHttp("test_login_yes"))#添加要执行的用例 # #第二个用例 # suite.addTest(TestHttp("test_login_no")) loader = unittest.TestLoader() # 创建加载器 # suite.addTest(loader.loadTestsFromTestCase(TestHttp))#通过类名加载 suite.addTest(loader.loadTestsFromModule(demo_case)) # 通过类名加载 file = open(file="log.txt",mode="w",encoding="utf8" )
runner = unittest.TextTestRunner(stream=file,verbosity=2) # stream为日志存储路径,verbosity=0/1/2 打印日志的详细等级,2最详细 runner.run(suite) # 执行 file.close() # 关闭资源
执行结果:
7.上下文管理器with open()
import unittest # from test01.demo_case import TestHttp#引入测试用例类 from test01 import demo_case
suite = unittest.TestSuite() # 存储器,存储用例 # #第一个用例 # suite.addTest(TestHttp("test_login_yes"))#添加要执行的用例 # #第二个用例 # suite.addTest(TestHttp("test_login_no")) loader = unittest.TestLoader() # 创建加载器 # suite.addTest(loader.loadTestsFromTestCase(TestHttp))#通过类名加载 suite.addTest(loader.loadTestsFromModule(demo_case)) # 通过类名加载 with open(file="log.txt",mode="w",encoding="utf8") as file: # 执行完后自动关闭 runner = unittest.TextTestRunner(stream=file,verbosity=2) # stream为日志存储路径,verbosity=0/1/2 打印日志的详细等级,2最详细 runner.run(suite) # 执行 # print(file.closed)#判断状态,True=关闭
执行结果与open()一致
8.HTMLTestRunnerNew
import unittest import HTMLTestRunnerNew # 引入模板类 # from test01.demo_case import TestHttp#引入测试用例类 from test01 import demo_case
suite = unittest.TestSuite() # 存储器,存储用例 loader = unittest.TestLoader() # 创建加载器 suite.addTest(loader.loadTestsFromModule(demo_case)) # 通过类名加载 with open(file = " qabujiaban_report.html " ,mode= " wb " ) as file: # 执行完后自动关闭 runner = HTMLTestRunnerNew.HTMLTestRunner(stream=file, verbosity=2,title="这里是标题",description="这里写描述",tester="这里写谁测试的" )
runner.run(suite)
生成报告:
9.接口关联传参方式
9.1.反射
class GetDate():
Cookie="ABCDEFG"
if __name__ == '__main__' :
print(getattr(GetDate,"Cookie")) #getattr(类名,属性名) 获取指定类的属性值
setattr(GetDate,"Cookie","三好学生")#修改指定类里的已有属性值
print(getattr(GetDate,"Cookie"))#三好学生
print(hasattr(GetDate,"Cookie"))#判断指定类是否有指定属性值
delattr(GetDate,"Cookie")#删除指定类的已有属性值
print(hasattr(GetDate,"Cookie"))#False
9.2.全局变量global
9.3.setUp()/tearDown()
import unittest # 引入unittest框架 from test01.qabujiaban_class import HttpRequest # 引入测试类 # 编写一个存储测试用例的类 class TestHttp(unittest.TestCase): # 用例类继承unittest.TestCase用于编写测试用例 def setUp (self) -> None: print ( " 每一条用例执行前执行... " ) def tearDown (self) -> None: print ( " 每一条用例执行结束后执行...(一般放到用例之后) " ) # 正确登陆测试用例 def test_login_yes(self): # 测试用例函数必须test_开头,否则框架无法识别当前是用例 print ( " 执行用例11111111111111111 " ) def test_login_no(self): print ( " 执行用例22222222222222222 " ) if __name__ == ' __main__ ' :
unittest.main() # 执行全部测试用例
执行结果:
============================= test session starts ============================= platform win32 -- Python 3.7.3, pytest-7.2.0, pluggy-1.0 .0
plugins: html -3.2.0, metadata-2.0.4collected 2 items
demo_case.py .每一条用例执行前执行...
执行用例22222222222222222
每一条用例执行结束后执行...(一般放到用例之后)
.每一条用例执行前执行...
执行用例11111111111111111
每一条用例执行结束后执行...(一般放到用例之后)
[ 100% ] ============================== 2 passed in 0.10s ============================== Process finished with exit code 0