• Python单元测试内置库uinttest使用介绍


    目录

    介绍

    概念

    编写规则

    断言类型

    安装依赖(http报表页面)

    传参方法

    实例

    报表


    介绍

    Unittest为Python标准库中自带的单元测试框架。

    若你不想安装或不允许第三方库,那么 unittest 是最好也是唯一的选择。反之,pytest 无疑是最佳选择,众多 Python 开源项目(如大名鼎鼎的 requests)都是使用 pytest 作为单元测试框架。

    总体来说,unittest 用例格式复杂,兼容性无,插件少,二次开发方便。pytest 更加方便快捷,用例格式简单,可以执行 unittest 风格的测试用例,较好的兼容性,插件丰富。

    概念

    unittest 中最核心的四个概念是:**test fixture、test case、test suite、test runner **。

    • test fixture:表示执行一个或多个测试所需的准备,以及任何关联的清理操作。例如这可能涉及创建临时或代理数据库、目录或启动服务器进程。
    • test case:测试用例是最小的测试单元。它检查特定的输入集的响应。单元测试提供了一个基类测试用例,可用于创建新的测试用例。
    • test suite:测试套件是测试用例、测试套件或两者的集合,用于归档需要一起执行的测试。
    • test runner:是一个用于执行和输出结果的组件。这个运行器可能使用图形接口、文本接口,或返回一个特定的值表示运行测试的结果。

    编写规则

    1. 编写单元测试时,我们需要编写一个测试类,从 unittest.TestCase 继承。

    2. 以 test 开头的方法就是测试方法,不以 test 开头的方法不被认为是测试方法,测试的时候不会被执行。

    3. 对每一类测试都需要编写一个 test_xxx() 方法。

    断言类型

    unittest 提供了丰富的断言,常用的包括:

    • assertEqual(是否相同)
    • assertNotEqual(是否不相同)
    • assertTrue(是否为真)
    • assertFalse(是否为假)
    • assertIn(是否包含)
    • assertNotIn(是否不包含)

    安装依赖(http报表页面)

    python3 -m pip install BeautifulReport

    传参方法

    个人方法教简单使用

    赋值类成员变量,再由测试函数自己调用执行

    1. #! /usr/bin/env python
    2. # -*- coding: utf-8 -*-
    3. class SensCheck(unittest.TestCase):
    4. data = None
    5. keyword = None
    6. regular = None
    7. dict1 = None
    8. @classmethod
    9. def setUpClass(cls) -> None:
    10. print("SENS验证开始")
    11. @classmethod
    12. def tearDownClass(cls) -> None:
    13. print("SENS验证结束")
    14. def test_keyword(self):
    15. count = 0
    16. match = self.keyword
    17. count = self.data.count(match)
    18. print("count: ", count)
    19. print("match: ", match)
    20. self.assertTrue(count)
    21. if __name__ == "__main__":
    22. SensCheck.data = "我的电话为13345677777, 请牢记"
    23. SensCheck.keyword = "电话"
    24. suite.addTest(SensCheck("test_keyword"))
    25. runner = unittest.TextTestRunner()
    26. runner.run(suite)

    实例

    cat unit_testing.py

    1. #! /usr/bin/env python
    2. # -*- coding: utf-8 -*-
    3. import unittest
    4. from BeautifulReport import BeautifulReport as bf
    5. import ast
    6. import re
    7. import json
    8. import sys
    9. import os
    10. import os.path
    11. from argparse import ArgumentParser
    12. from sens.modules.app import http
    13. from sens.modules.app import mysql
    14. from sens.modules.app import smtp
    15. from sens.modules.app import api
    16. from sens.modules.file import static
    17. from sens.common.files import get_petype
    18. from sens.detector import detector
    19. parser = ArgumentParser(description='UnitTesting')
    20. """
    21. APP检测,包含http、数据库、邮件
    22. """
    23. class AppCheck(unittest.TestCase):
    24. rule = None
    25. appdata = None
    26. apidata = None
    27. @classmethod
    28. def setUpClass(cls) -> None:
    29. print("APP检测开始")
    30. @classmethod
    31. def tearDownClass(cls) -> None:
    32. print("APP检测结束")
    33. def test_http(self):
    34. success = 0
    35. fail = 0
    36. for data in self.appdata:
    37. alert, res = http.check(self.rule, data)
    38. print("data: ", data)
    39. print("res : ", res)
    40. if alert:
    41. print("alert: ", alert)
    42. self.assertTrue(alert)
    43. success += 1
    44. else:
    45. print("alert: ", alert)
    46. self.assertFalse(alert)
    47. fail += 1
    48. print("success: ", success)
    49. print("fail: ", fail)
    50. def test_mysql(self):
    51. success = 0
    52. fail = 0
    53. for data in self.appdata:
    54. alert, res = mysql.check(self.rule, data)
    55. print("data: ", data)
    56. print("res : ", res)
    57. if alert:
    58. print("alert: ", alert)
    59. self.assertTrue(alert)
    60. success += 1
    61. else:
    62. print("alert: ", alert)
    63. self.assertFalse(alert)
    64. fail += 1
    65. print("success: ", success)
    66. print("fail: ", fail)
    67. def test_smtp(self):
    68. success = 0
    69. fail = 0
    70. for data in self.appdata:
    71. alert, res = smtp.check(self.rule, data)
    72. print("data: ", data)
    73. print("res : ", res)
    74. if alert:
    75. print("alert: ", alert)
    76. self.assertTrue(alert)
    77. success += 1
    78. else:
    79. print("alert: ", alert)
    80. self.assertFalse(alert)
    81. fail += 1
    82. print("success: ", success)
    83. print("fail: ", fail)
    84. def test_api(self):
    85. success = 0
    86. fail = 0
    87. for data in self.apidata:
    88. alert, res = api.check(self.rule, data)
    89. print("data: ", data)
    90. print("res : ", res)
    91. if alert:
    92. print("alert: ", alert)
    93. self.assertTrue(alert)
    94. success += 1
    95. else:
    96. print("alert: ", alert)
    97. self.assertFalse(alert)
    98. fail += 1
    99. print("success: ", success)
    100. print("fail: ", fail)
    101. """
    102. FILE检测,仅包含静态文件检测
    103. """
    104. class FileCheck(unittest.TestCase):
    105. rule = None
    106. folder_path = None
    107. @classmethod
    108. def setUpClass(cls) -> None:
    109. print("FILE检测开始")
    110. @classmethod
    111. def tearDownClass(cls) -> None:
    112. print("FILE检测结束")
    113. def test_static(self):
    114. success = 0
    115. fail = 0
    116. tatic_files = ["txt", "python", "vbs", "js", "hta", "ps1", "wsf", "ie", "c", "sh", "java", "php", "jsp", "aspx", "asp", "cgi"]
    117. file_list = []
    118. dir_or_files = os.listdir(self.folder_path)
    119. for dir_file in dir_or_files:
    120. dir_file_path = os.path.join(self.folder_path, dir_file)
    121. if not os.path.isdir(dir_file_path):
    122. file_list.append(dir_file_path)
    123. for item in file_list:
    124. file_type = get_petype(item)
    125. _, file_name = os.path.split(item)
    126. if file_type in tatic_files:
    127. alert, res = static.check(self.rule, file_name, item, file_type)
    128. print("file: ", item)
    129. print("res : ", res)
    130. if alert:
    131. print("alert: ", alert)
    132. self.assertTrue(alert)
    133. success += 1
    134. else:
    135. print("alert: ", alert)
    136. self.assertFalse(alert)
    137. fail += 1
    138. print("success: ", success)
    139. print("fail: ", fail)
    140. """
    141. AI验证
    142. """
    143. class AICheck(unittest.TestCase):
    144. verify_match = None
    145. @classmethod
    146. def setUpClass(cls) -> None:
    147. print("AI验证开始")
    148. @classmethod
    149. def tearDownClass(cls) -> None:
    150. print("AI验证结束")
    151. def test_identity_card(self):
    152. success = 0
    153. fail = 0
    154. verify_count = len(self.verify_match)
    155. for item in self.verify_match:
    156. count, match = detector.verifyByIDCard(1, [item])
    157. print("card : ", item)
    158. if count:
    159. print("alert: ", True)
    160. self.assertTrue(count)
    161. success += 1
    162. else:
    163. print("alert: ", False)
    164. self.assertFalse(count)
    165. fail += 1
    166. print("success: ", success)
    167. print("fail: ", fail)
    168. """
    169. 验证:关键字、正则、字典
    170. """
    171. class SensCheck(unittest.TestCase):
    172. keyword_data = None
    173. regular_data = None
    174. dict_data = None
    175. keyword = None
    176. regular = None
    177. dict1 = None
    178. @classmethod
    179. def setUpClass(cls) -> None:
    180. print("SENS验证开始")
    181. @classmethod
    182. def tearDownClass(cls) -> None:
    183. print("SENS验证结束")
    184. def test_keyword(self):
    185. count = 0
    186. match = self.keyword
    187. count = self.keyword_data.count(match)
    188. print("count: ", count)
    189. print("match: ", match)
    190. self.assertTrue(count)
    191. def test_regular(self):
    192. count = 0
    193. match = self.regular
    194. res = [x.group() for x in re.finditer(match, self.regular_data)]
    195. count = len(res)
    196. print("count: ", count)
    197. print("match: ", res)
    198. self.assertTrue(count)
    199. def test_dict(self):
    200. count = 0
    201. match = []
    202. for item in self.dict1:
    203. nu = self.dict_data.count(item)
    204. count += nu
    205. match.append(item)
    206. print("count: ", count)
    207. print("match: ", match)
    208. self.assertTrue(count)
    209. if __name__ == "__main__":
    210. group = parser.add_argument_group()
    211. parser.add_argument('-ar', '--apprule', dest='apprule', default=None, help='Please input app rule db path check')
    212. parser.add_argument('-fr', '--filerule', dest='filerule', default=None, help='Please input file rule db path check')
    213. parser.add_argument('-a', '--applog', dest='applog', default=None, help='Please input app log path check')
    214. parser.add_argument('-i', '--apilog', dest='apilog', default=None, help='Please input api log path check')
    215. parser.add_argument('-f', '--filelog', dest='filelog', default=None, help='Please input file folder path check')
    216. parser.add_argument('-ai', '--ailog', dest='ailog', default=None, help='Please input AI data log path check')
    217. parser.add_argument('-k', '--keyword', dest='keyword', default=None, help='Please input keyword data log check')
    218. parser.add_argument('-r', '--regular', dest='regular', default=None, help='Please input regular data log check')
    219. parser.add_argument('-d', '--dictionary', dest='dictionary', default=None, help='Please input dictionary data log check')
    220. args = parser.parse_args()
    221. print("apprule : ", args.apprule)
    222. print("filerule: ", args.filerule)
    223. print("applog : ", args.applog)
    224. print("apilog : ", args.apilog)
    225. print("filelog : ", args.filelog)
    226. print("ailog : ", args.ailog)
    227. print("keyword : ", args.keyword)
    228. print("regular : ", args.regular)
    229. print("dict : ", args.dictionary)
    230. suite = unittest.TestSuite()
    231. """
    232. APP检测,包含http协议、数据库协议、邮件协议
    233. """
    234. if args.apprule and args.applog:
    235. if not os.path.exists(args.apprule):
    236. print("apprule {} 不存在".format(args.apprule))
    237. sys.exit(-1)
    238. if not os.path.exists(args.applog):
    239. print("applog {} 不存在".format(args.applog))
    240. sys.exit(-1)
    241. with open(args.apprule) as f:
    242. apprule = json.load(f)
    243. applog = []
    244. for line in open(args.applog):
    245. applog.append(ast.literal_eval(line.strip()))
    246. AppCheck.rule = apprule
    247. AppCheck.appdata = applog
    248. suite.addTest(AppCheck("test_http"))
    249. """
    250. API检测
    251. """
    252. if args.apprule and args.apilog:
    253. if not os.path.exists(args.apprule):
    254. print("apprule {} 不存在".format(args.apprule))
    255. sys.exit(-1)
    256. if not os.path.exists(args.apilog):
    257. print("apilog {} 不存在".format(args.apilog))
    258. sys.exit(-1)
    259. with open(args.apprule) as f:
    260. apprule = json.load(f)
    261. apilog = []
    262. for line in open(args.apilog):
    263. apilog.append(ast.literal_eval(line.strip()))
    264. AppCheck.rule = apprule
    265. AppCheck.apidata = apilog
    266. suite.addTest(AppCheck("test_api"))
    267. """
    268. FILE检测,仅包含静态文件txt, python, vbs, js, hta, ps1, wsf, ie, c, sh, java, php, jsp, aspx, asp, cgi
    269. """
    270. if args.filerule and args.filelog:
    271. with open(args.filerule) as f:
    272. filerule = json.load(f)
    273. FileCheck.rule = filerule
    274. FileCheck.folder_path = args.filelog
    275. suite.addTest(FileCheck("test_static"))
    276. """
    277. AI验证:包含身份证
    278. """
    279. if args.ailog:
    280. if not os.path.exists(args.ailog):
    281. print("AI check error, {} 不存在".format(args.ailog))
    282. ailog = []
    283. for line in open(args.ailog):
    284. ailog.append("A" + str(ast.literal_eval(line.strip())) + "B")
    285. AICheck.verify_match = ailog
    286. suite.addTest(AICheck("test_identity_card"))
    287. """
    288. 验证:关键字
    289. """
    290. if args.keyword:
    291. if not os.path.exists(args.keyword):
    292. print("keyword check error, {} 不存在".format(args.keyword))
    293. keyword_log = ""
    294. for line in open(args.keyword, encoding="utf-8"):
    295. line = line.strip()
    296. keyword_log += line
    297. SensCheck.keyword = "电话"
    298. SensCheck.keyword_data = keyword_log
    299. suite.addTest(SensCheck("test_keyword"))
    300. """
    301. 验证:正则
    302. """
    303. if args.regular:
    304. if not os.path.exists(args.regular):
    305. print("regular check error, {} 不存在".format(args.regular))
    306. regular_log = ""
    307. for line in open(args.regular, encoding="utf-8"):
    308. line = line.strip()
    309. regular_log += line
    310. SensCheck.regular = "\D(13[0-9]|14[5-9]|15[0-3,5-9]|16[2,5,6,7]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8}\D"
    311. SensCheck.regular_data = regular_log
    312. suite.addTest(SensCheck("test_regular"))
    313. """
    314. 验证:字典
    315. """
    316. if args.dictionary:
    317. if not os.path.exists(args.dictionary):
    318. print("dict check error, {} 不存在".format(args.dictionary))
    319. dictionary_log = ""
    320. for line in open(args.dictionary, encoding="utf-8"):
    321. line = line.strip()
    322. dictionary_log += line
    323. SensCheck.dict1 = ["133", "77777"]
    324. SensCheck.dict_data = dictionary_log
    325. suite.addTest(SensCheck("test_dict"))
    326. #runner = unittest.TextTestRunner()
    327. #runner.run(suite)
    328. runner = bf(suite)
    329. runner.report(filename="单元测试报告", description="单元测试报告")

    报表

  • 相关阅读:
    俄罗斯方块
    MySQL中的分库分表框架-ShardingSphere
    webpack-cl明明已经安装了,但是还是会报未安装
    分析kdump(vmcore)
    GEE——加载ERA5气候再分析参数并使其可视化的脚本示例
    面试官让你说说react状态管理?
    非暴力沟通!
    【vue3 】 创建项目vscode 提示无法找到模块
    calcite 初试-使用sql读取csv文件
    新闻分析报告:Active Directory 证书服务是企业网络的一大安全盲点
  • 原文地址:https://blog.csdn.net/u012206617/article/details/127773785