一、单元测试的定义:
1:什么是单元测试?
还记不记得我们软件测试学习的时候,按照定义:单元测试就是对单个模块或者是单个类或者单个函数进行测试,一般是开发做的,按照阶段来分,一般就是单元测试、集成测试(接口测试)、系统测试(系统之间的联调测试)、验收测试
2:为什么要做单元测试?
1)单元测试之后,才是集成测试,单个单个的功能模块测试通过之后,才能把单个功能模块集成起来做集成测试,为了从底层发现bug,减少合成后出现的问题。
2)越早发现bug越好,这样可以早点发现问题,不然问题累计到后面,如果做错了就要推倒重来-对于时间和经费来说,是非常浪费的!
3)对于我们测试来说:我们就单元测试是为了执行测试用例!校验程序代码之间的运行逻辑
例如:信贷系统提供的接口中关于最长逾期天数的计算,对于有实际逾期的客户,也没有把节假日、宽限期减掉,逾期天数按实际还款日期(或当天) 减 到期还款日期
程序逻辑校验:确保每个字段(逾期天数)计算的准确性,确保被其他模块调用时,是正确的
输入测试数据---->测出测试结果
二、unittest框架以及原理介绍
1、unittest框架最核心的四个概念:
TestCase:测试用例
TestCase:一个TestCase的实例就是一个测试用例
TestSuite:测试套件,测试集合
TestSuite:多个测试用例集合在一起,TestLoader:是用来加载TestCase到TestSuite中的
TextTestRunner:测试运行程序
TextTestRunner:用来执行测试用例
fixture:测试环境搭建和销毁
fixture:测试用例环境的搭建与销毁,测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)
三、编写测试用例
四、测试集合
五、unittest断言介绍
assertEqual(a,b) a==b
六、执行用例&生成报告
HTMLTestRunnerNew存放路径:
七、综合运用:
# login.py def login_check(username,password): """ 登录校验的函数 :param username: 账号 :param password: 密码 :return: dict type """ if 6 <= len(password) <= 18: if username == "python23" and password == "lemonban": return {"code":0,"mgs":"登录成功"} else: return {"code": 1, "mgs": "账号或密码不正确"} else: return {"code":1,"mgs":"密码长度在6-18位之间"} # # 第一步:调用功能函数,传入参数(实际结果) # result = login_check(username = "python23",password = "lemonban" ) # # 预期结果 # excepted = {"code":0,"mgs":"登录成功"} # # 第二步:比对预期结果和实际结果是否一致 # if result == excepted: # print("用例执行通过") # else: # print("用例执行未通过")
# test_login_case.py """ unittest框架最核心的四个概念: TestCase:一个TestCase的实例就是一个测试用例 TestSuite:多个测试用例集合在一起,TestLoader:是用来加载TestCase到TestSuite中的 TextTestRunner:用来执行测试用例 fixture:测试用例环境的搭建与销毁,测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown) unittest是python中的官方库 第一步:设计测试用例 入参 预期 1、正常登录的用例 正确的账号和密码 {"code":0,"mgs":"登录成功"} 2、密码长度低于6位 正确的账号,密码长度低于6位 {"code":1,"mgs":"密码长度在6-18位之间"} 3、密码长度大于18位 正确的账号,密码长度大于18位 {"code":1,"mgs":"密码长度在6-18位之间"} 4、账号正确、密码错误 正确的账号,错误的密码 {"code": 1, "mgs": "账号或密码不正确"} unittest.TestCase(测试用例类),所有的测试用例类,都是继承于unittest.TestCase 每一条测试用例,就是测试用例类中的一个方法(方法名必须要用test开头) 第二步: 第三步: """ import unittest # from login import login_check # 导包标红不是报错,pycharm软件问题 from Day13_2020_03_04.login import login_check # 用unittest对功能函数做单元测试 class TestLogin(unittest.TestCase): """登录校验的测试用例类""" def test_login_pass(self): # 准备测试用例要用到的数据 # 入参 data = ["python23","lemonban"] # 预期结果 excepted = {"code": 0, "mgs": "登录成功"} # 第一步:调用功能函数,传入参数(实际结果) result = login_check(*data) # 第二步:比对预期结果和实际结果是否一致 # if result == excepted: # print("用例执行通过") # else: # print("用例执行未通过") self.assertEqual(excepted,result) def test_login_pwd_6(self): data = ["python23", "12345"] # 预期结果 excepted = {"code":1,"mgs":"密码长度在6-18位之间"} # 第一步:调用功能函数,传入参数(实际结果) result = login_check(*data) # 第二步:比对预期结果和实际结果是否一致 self.assertEqual(excepted, result) def test_login_pwd_18(self): data = ["python23", "1234567891234568787777"] # 预期结果 excepted = {"code":1,"mgs":"密码长度在6-18位之间"} # 第一步:调用功能函数,传入参数(实际结果) result = login_check(*data) # 第二步:比对预期结果和实际结果是否一致 self.assertEqual(excepted, result) def test_login_pwd_error(self): data = ["python23", "lemonba"] # 预期结果 excepted = {"code": 1, "mgs": "账号或密码不正确"} # 第一步:调用功能函数,传入参数(实际结果) result = login_check(*data) # 第二步:比对预期结果和实际结果是否一致 self.assertEqual(excepted, result) def setUp(self): # 每一条测试用例执行之前都会执行 print("{}开始执行了".format(self)) def tearDown(self): # 每一条测试用例执行之后都会执行 print("{}执行完了".format(self)) @classmethod def setUpClass(cls): # 执行这个测试用例类中的测试用例之前会执行 print("{}开始执行测试用例类执行完了".format(cls)) @classmethod def tearDownClass(cls): # 执行测试用例类全部执行完了,就会执行该方法 print("{}执行测试用例类全部执行完了,就会执行该方法".format(cls))
# test_run.py import random from HTMLTestRunnerNew import HTMLTestRunner """ 测试程序启动文件 第一步:创建一个测试套件(unittest.TestSuite) 第二步:将测试用例加入到测试套件中 第三步:创建一个测试运行程序对象(unittest.TextTestRunner) 第四步:通过运行程序,去执行测试套件中的测试用例 """ import unittest # from Day13_2020_03_04.login_test_case import TestLogin # from Day13_2020_03_04 import login_test_case # 创建测试套件对象 suite = unittest.TestSuite() # 第二步:将测试用例加入到测试套件中 # 第一种方法:将一条测试用例加入测试套件中 # 类名加括号,创建测试用例对象 # TestLogin("test_login_pass") # 将测试用例对象,加入测试套件,第一个参数是测试用例的方法名(必须要传) # suite.addTest(TestLogin("test_login_pass")) # 第二种方法:将测试用例类所有的测试用例加入到测试套件 # loader = unittest.TestLoader() # suite.addTest(loader.loadTestsFromTestCase(TestLogin)) # # 第三种方法:将一个模块中的所有测试用例,加载到测试套件 # loader = unittest.TestLoader() # # login_test_case 标黄不影响 # suite.addTest(loader.loadTestsFromModule(login_test_case)) # 第四种方法:通过一个目录,去导入改目录下的所有模块中的测试用例 loader = unittest.TestLoader() # r防止转义,注意测试用例的模块名称,要以test开头 suite.addTest(loader.discover(r"D:projectclass23Day13_2020_03_04")) # 第三步:创建一个测试运行程序对象 # runner = unittest.TextTestRunner() """ stream:测试文件名字 verbosity: title:报告的标题 description:相关的描述 tester:测试人员姓名 """ runner = HTMLTestRunner(stream=open("report.html","wb"), verbosity=2, title="python第一份测试报告", description="登录类测试报告", tester="chen") # 第四步:通过运行程序,去执行测试套件中的测试用例 runner.run(suite)