目录
Unittest为Python标准库中自带的单元测试框架。
若你不想安装或不允许第三方库,那么 unittest 是最好也是唯一的选择。反之,pytest 无疑是最佳选择,众多 Python 开源项目(如大名鼎鼎的 requests)都是使用 pytest 作为单元测试框架。
总体来说,unittest 用例格式复杂,兼容性无,插件少,二次开发方便。pytest 更加方便快捷,用例格式简单,可以执行 unittest 风格的测试用例,较好的兼容性,插件丰富。
unittest 中最核心的四个概念是:**test fixture、test case、test suite、test runner **。
编写单元测试时,我们需要编写一个测试类,从 unittest.TestCase 继承。
以 test 开头的方法就是测试方法,不以 test 开头的方法不被认为是测试方法,测试的时候不会被执行。
对每一类测试都需要编写一个 test_xxx() 方法。
unittest 提供了丰富的断言,常用的包括:
python3 -m pip install BeautifulReport
个人方法教简单使用
赋值类成员变量,再由测试函数自己调用执行
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
-
-
- class SensCheck(unittest.TestCase):
- data = None
- keyword = None
- regular = None
- dict1 = None
-
- @classmethod
- def setUpClass(cls) -> None:
- print("SENS验证开始")
-
- @classmethod
- def tearDownClass(cls) -> None:
- print("SENS验证结束")
-
- def test_keyword(self):
- count = 0
- match = self.keyword
- count = self.data.count(match)
- print("count: ", count)
- print("match: ", match)
- self.assertTrue(count)
-
-
- if __name__ == "__main__":
- SensCheck.data = "我的电话为13345677777, 请牢记"
- SensCheck.keyword = "电话"
-
- suite.addTest(SensCheck("test_keyword"))
-
- runner = unittest.TextTestRunner()
- runner.run(suite)
cat unit_testing.py
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
-
-
- import unittest
- from BeautifulReport import BeautifulReport as bf
-
- import ast
- import re
- import json
- import sys
- import os
- import os.path
- from argparse import ArgumentParser
-
- from sens.modules.app import http
- from sens.modules.app import mysql
- from sens.modules.app import smtp
- from sens.modules.app import api
-
- from sens.modules.file import static
- from sens.common.files import get_petype
-
- from sens.detector import detector
-
- parser = ArgumentParser(description='UnitTesting')
-
-
- """
- APP检测,包含http、数据库、邮件
- """
- class AppCheck(unittest.TestCase):
- rule = None
- appdata = None
- apidata = None
-
- @classmethod
- def setUpClass(cls) -> None:
- print("APP检测开始")
-
- @classmethod
- def tearDownClass(cls) -> None:
- print("APP检测结束")
-
- def test_http(self):
- success = 0
- fail = 0
- for data in self.appdata:
- alert, res = http.check(self.rule, data)
- print("data: ", data)
- print("res : ", res)
- if alert:
- print("alert: ", alert)
- self.assertTrue(alert)
- success += 1
- else:
- print("alert: ", alert)
- self.assertFalse(alert)
- fail += 1
- print("success: ", success)
- print("fail: ", fail)
-
- def test_mysql(self):
- success = 0
- fail = 0
- for data in self.appdata:
- alert, res = mysql.check(self.rule, data)
- print("data: ", data)
- print("res : ", res)
- if alert:
- print("alert: ", alert)
- self.assertTrue(alert)
- success += 1
- else:
- print("alert: ", alert)
- self.assertFalse(alert)
- fail += 1
- print("success: ", success)
- print("fail: ", fail)
-
- def test_smtp(self):
- success = 0
- fail = 0
- for data in self.appdata:
- alert, res = smtp.check(self.rule, data)
- print("data: ", data)
- print("res : ", res)
- if alert:
- print("alert: ", alert)
- self.assertTrue(alert)
- success += 1
- else:
- print("alert: ", alert)
- self.assertFalse(alert)
- fail += 1
- print("success: ", success)
- print("fail: ", fail)
-
- def test_api(self):
- success = 0
- fail = 0
- for data in self.apidata:
- alert, res = api.check(self.rule, data)
- print("data: ", data)
- print("res : ", res)
- if alert:
- print("alert: ", alert)
- self.assertTrue(alert)
- success += 1
- else:
- print("alert: ", alert)
- self.assertFalse(alert)
- fail += 1
- print("success: ", success)
- print("fail: ", fail)
-
-
- """
- FILE检测,仅包含静态文件检测
- """
- class FileCheck(unittest.TestCase):
- rule = None
- folder_path = None
-
- @classmethod
- def setUpClass(cls) -> None:
- print("FILE检测开始")
-
- @classmethod
- def tearDownClass(cls) -> None:
- print("FILE检测结束")
-
- def test_static(self):
- success = 0
- fail = 0
- tatic_files = ["txt", "python", "vbs", "js", "hta", "ps1", "wsf", "ie", "c", "sh", "java", "php", "jsp", "aspx", "asp", "cgi"]
-
- file_list = []
- dir_or_files = os.listdir(self.folder_path)
- for dir_file in dir_or_files:
- dir_file_path = os.path.join(self.folder_path, dir_file)
- if not os.path.isdir(dir_file_path):
- file_list.append(dir_file_path)
-
- for item in file_list:
- file_type = get_petype(item)
- _, file_name = os.path.split(item)
- if file_type in tatic_files:
- alert, res = static.check(self.rule, file_name, item, file_type)
- print("file: ", item)
- print("res : ", res)
- if alert:
- print("alert: ", alert)
- self.assertTrue(alert)
- success += 1
- else:
- print("alert: ", alert)
- self.assertFalse(alert)
- fail += 1
- print("success: ", success)
- print("fail: ", fail)
-
-
- """
- AI验证
- """
- class AICheck(unittest.TestCase):
- verify_match = None
-
- @classmethod
- def setUpClass(cls) -> None:
- print("AI验证开始")
-
- @classmethod
- def tearDownClass(cls) -> None:
- print("AI验证结束")
-
- def test_identity_card(self):
- success = 0
- fail = 0
- verify_count = len(self.verify_match)
- for item in self.verify_match:
- count, match = detector.verifyByIDCard(1, [item])
- print("card : ", item)
- if count:
- print("alert: ", True)
- self.assertTrue(count)
- success += 1
- else:
- print("alert: ", False)
- self.assertFalse(count)
- fail += 1
- print("success: ", success)
- print("fail: ", fail)
-
-
- """
- 验证:关键字、正则、字典
- """
- class SensCheck(unittest.TestCase):
- keyword_data = None
- regular_data = None
- dict_data = None
- keyword = None
- regular = None
- dict1 = None
-
- @classmethod
- def setUpClass(cls) -> None:
- print("SENS验证开始")
-
- @classmethod
- def tearDownClass(cls) -> None:
- print("SENS验证结束")
-
- def test_keyword(self):
- count = 0
- match = self.keyword
- count = self.keyword_data.count(match)
- print("count: ", count)
- print("match: ", match)
- self.assertTrue(count)
-
- def test_regular(self):
- count = 0
- match = self.regular
- res = [x.group() for x in re.finditer(match, self.regular_data)]
- count = len(res)
- print("count: ", count)
- print("match: ", res)
- self.assertTrue(count)
-
- def test_dict(self):
- count = 0
- match = []
- for item in self.dict1:
- nu = self.dict_data.count(item)
- count += nu
- match.append(item)
- print("count: ", count)
- print("match: ", match)
- self.assertTrue(count)
-
-
-
- if __name__ == "__main__":
- group = parser.add_argument_group()
- parser.add_argument('-ar', '--apprule', dest='apprule', default=None, help='Please input app rule db path check')
- parser.add_argument('-fr', '--filerule', dest='filerule', default=None, help='Please input file rule db path check')
- parser.add_argument('-a', '--applog', dest='applog', default=None, help='Please input app log path check')
- parser.add_argument('-i', '--apilog', dest='apilog', default=None, help='Please input api log path check')
- parser.add_argument('-f', '--filelog', dest='filelog', default=None, help='Please input file folder path check')
- parser.add_argument('-ai', '--ailog', dest='ailog', default=None, help='Please input AI data log path check')
- parser.add_argument('-k', '--keyword', dest='keyword', default=None, help='Please input keyword data log check')
- parser.add_argument('-r', '--regular', dest='regular', default=None, help='Please input regular data log check')
- parser.add_argument('-d', '--dictionary', dest='dictionary', default=None, help='Please input dictionary data log check')
- args = parser.parse_args()
-
- print("apprule : ", args.apprule)
- print("filerule: ", args.filerule)
- print("applog : ", args.applog)
- print("apilog : ", args.apilog)
- print("filelog : ", args.filelog)
- print("ailog : ", args.ailog)
- print("keyword : ", args.keyword)
- print("regular : ", args.regular)
- print("dict : ", args.dictionary)
-
- suite = unittest.TestSuite()
-
- """
- APP检测,包含http协议、数据库协议、邮件协议
- """
- if args.apprule and args.applog:
- if not os.path.exists(args.apprule):
- print("apprule {} 不存在".format(args.apprule))
- sys.exit(-1)
- if not os.path.exists(args.applog):
- print("applog {} 不存在".format(args.applog))
- sys.exit(-1)
-
- with open(args.apprule) as f:
- apprule = json.load(f)
- applog = []
- for line in open(args.applog):
- applog.append(ast.literal_eval(line.strip()))
-
- AppCheck.rule = apprule
- AppCheck.appdata = applog
- suite.addTest(AppCheck("test_http"))
-
-
- """
- API检测
- """
- if args.apprule and args.apilog:
- if not os.path.exists(args.apprule):
- print("apprule {} 不存在".format(args.apprule))
- sys.exit(-1)
- if not os.path.exists(args.apilog):
- print("apilog {} 不存在".format(args.apilog))
- sys.exit(-1)
-
- with open(args.apprule) as f:
- apprule = json.load(f)
- apilog = []
- for line in open(args.apilog):
- apilog.append(ast.literal_eval(line.strip()))
-
- AppCheck.rule = apprule
- AppCheck.apidata = apilog
- suite.addTest(AppCheck("test_api"))
-
-
- """
- FILE检测,仅包含静态文件txt, python, vbs, js, hta, ps1, wsf, ie, c, sh, java, php, jsp, aspx, asp, cgi
- """
- if args.filerule and args.filelog:
- with open(args.filerule) as f:
- filerule = json.load(f)
- FileCheck.rule = filerule
- FileCheck.folder_path = args.filelog
- suite.addTest(FileCheck("test_static"))
-
-
- """
- AI验证:包含身份证
- """
- if args.ailog:
- if not os.path.exists(args.ailog):
- print("AI check error, {} 不存在".format(args.ailog))
- ailog = []
- for line in open(args.ailog):
- ailog.append("A" + str(ast.literal_eval(line.strip())) + "B")
-
- AICheck.verify_match = ailog
- suite.addTest(AICheck("test_identity_card"))
-
-
- """
- 验证:关键字
- """
- if args.keyword:
- if not os.path.exists(args.keyword):
- print("keyword check error, {} 不存在".format(args.keyword))
- keyword_log = ""
- for line in open(args.keyword, encoding="utf-8"):
- line = line.strip()
- keyword_log += line
-
- SensCheck.keyword = "电话"
- SensCheck.keyword_data = keyword_log
- suite.addTest(SensCheck("test_keyword"))
-
-
- """
- 验证:正则
- """
- if args.regular:
- if not os.path.exists(args.regular):
- print("regular check error, {} 不存在".format(args.regular))
- regular_log = ""
- for line in open(args.regular, encoding="utf-8"):
- line = line.strip()
- regular_log += line
-
- 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"
- SensCheck.regular_data = regular_log
- suite.addTest(SensCheck("test_regular"))
-
-
- """
- 验证:字典
- """
- if args.dictionary:
- if not os.path.exists(args.dictionary):
- print("dict check error, {} 不存在".format(args.dictionary))
- dictionary_log = ""
- for line in open(args.dictionary, encoding="utf-8"):
- line = line.strip()
- dictionary_log += line
-
- SensCheck.dict1 = ["133", "77777"]
- SensCheck.dict_data = dictionary_log
- suite.addTest(SensCheck("test_dict"))
-
-
- #runner = unittest.TextTestRunner()
- #runner.run(suite)
-
- runner = bf(suite)
- runner.report(filename="单元测试报告", description="单元测试报告")