一、单元测试的定义
1. 什么是单元测试?
单元测试就是对单个模块或者单个类或者单个函数进行测试,一般是开发做的,按照阶段来分,一般就是单元测试、集成测试、系统测试、验收测试
2. 为什么要做单元测试?
1)单元测试之后,才是集成测试,单个的功能模块测试通过之后,才能把单个功能模块集成起来做集成测试,为了从底层发现bug,减少合成之后出现的问题。
2)越早发现bug越好,不然问题都累积到后面,可能会导致很多代码要推倒重来,对于时间和成本来说,都是非常浪费的。
对于测试来说:做单元测试就是执行测试用例!
输入测试数据-----→输出测试结果
二、unittest框架以及原理介绍
1. unittest框架最核心的四个概念
1)测试用例TestCase
- TestCase:使用用例类
- 测试用例类中以test开头的方法就是一个测试用例
2)测试套件TestSuite:
- TestSuite:创建测试套件
- TestLoader:是用来加载TestCase到TestSuite中的。
- 添加用例到套件的方法:单条 类 模块 目录
3)测试运行程序TextTestRunner:用来执行测试用例
#创建运行程序,生成测试报告
from HTMLTestRunnerNew import HTMLTestRunner
4)测试环境搭建和销毁fixture:测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)
- setUp:每条用例执行之前执行
- tearDown:每条用例执行之后执行
2. 单元测试案例
- 测试需求一
def login_check(username, password):
'''
登录校验的函数
:param username: 账号
:param password: 密码
:return: dict type
'''
if 6 <= len(password) <= 18:
if username == 'xiaohuan' and password == '123456':
return {'code': 0, 'msg': '登录成功'}
else:
return {'code': 1, 'msg': '账号或密码不正确'}
else:
return {'code': 1, 'mgs': '密码长度在6-18位之间'}
备注:
unittest是python中的官方库
unittest.TestCase(测试用例类),所有的测试用例类,都是继承于unittest.TestCase
每一条测试用例,就是测试用例类中的一个方法(方法名必须要用test开头)
- 设计用例测试上面的登录校验功能是否正常
'''
1 正常登录的用例 正确的账号密码 {'code': 0, 'msg': '登录成功'}
2 密码长度小于6位 正确的账号,密码长度小于6位 {'code': 1, 'mgs': '密码长度在6-18位之间'}
3 密码长度大于18位 正确的账号,密码长度大于18位 {'code': 1, 'mgs': '密码长度在6-18位之间'}
4 账号正确,密码错误 正确的账号,错误的密码 {'code': 1, 'msg': '账号或密码不正确'}
5 账号错误,密码正确 错误的账号,正确的密码 {'code': 1, 'msg': '账号或密码不正确'}
'''
- 编写测试用例程序
import unittest
from login import login_check
class TestLogin(unittest.TestCase):
'''登录校验的测试用例类'''
def test_login_pass(self):
# 准备测试用例 要用到的数据
# 入参
data = ['xiaohuan', '123456']
# 预期结果
excepted = {'code': 0, 'msg': '登录成功'}
# 第一步:调用功能函数,传入参数
result = login_check(*data)
# 第二步:比对预期结果和实际结果是否一致
self.assertEqual(excepted, result)
def test_login_pwd_6(self):
data = ['xiaohuan', '12345']
excepted = {'code': 1, 'mgs': '密码长度在6-18位之间'}
result = login_check(*data)
self.assertEqual(excepted, result)
def test_login_pwd_18(self):
data = ['xiaohuan', '123456123456123456123456']
excepted = {'code': 1, 'mgs': '密码长度在6-18位之间'}
result = login_check(*data)
self.assertEqual(excepted, result)
def test_login_pwd_error(self):
data = ['xiaohuan', '1234567']
excepted = {'code': 1, 'msg': '账号或密码不正确'}
result = login_check(*data)
self.assertEqual(excepted, result)
def test_login_username_error(self):
data = ['xiaohuan01', '123456']
excepted = {'code': 1, 'msg': '账号或密码不正确'}
result = login_check(*data)
self.assertEqual(excepted, result)
- 编写测试用例运行程序
import unittest
from py23_13day.HTMLTestRunnerNew import HTMLTestRunner
# from py23_13day.test_login_case import TestLogin
# from py23_13day import test_login_case
'''
这个是测试程序的启动文件
第一步:创建一个测试套件对象(unittest.TestSuite)
第二步:将测试用例 加入到测试套件中
unittest.TestLoader():专门用来加载测试用例到套件
第三步:创建一个测试运行程序对象(unittest.TextTestRunner)
第四步:通过运行程序,执行测试套件中的测试用例
'''
# 创建测试套件对象
suite = unittest.TestSuite()
# 第二步:将测试用例 加入到测试套件中
# # 第一种方法:将一条用例加入到测试套件中
#
# # 创建测试用例对象:第一个参数是测试用例的方法名(必传)
# case = TestLogin('test_login_pass')
# # 将测试用例对象加入到测试套件
# suite.addTest(case)
#
# case2 = TestLogin('test_login_pwd_6')
# suite.addTest(case2)
# 第二种方法:将一个测试用例类加入到测试套件中
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(TestLogin))
# 第三种方法:将一个模块中的所有测试用例加入到测试套件中
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromModule(test_login_case))
# 第三种方法:将一个包中的所有测试用例类加入到测试套件中
loader = unittest.TestLoader()
suite.addTest(loader.discover(r'E:\PycharmProjects\py23_class\py23_13day'))
# 第三步:创建一个测试运行程序对象(unittest.TextTestRunner)
# runner = unittest.TextTestRunner()
runner = HTMLTestRunner(stream=open('report.html', 'wb'),
# verbosity=2,
title='小欢的第一份测试报告',
description='登录的单元测试',
tester='xiaohuan')
# 第四步:通过运行程序,执行测试套件中的测试用例
runner.run(suite)
三、编写测试用例
1. TestCase类编写测试用例
- 继承
unittest
里面的TestCase
类,继承这个类,编写测试用例。每个用例都要引入fixture
,做一些准备以及结束的工作。 - 编写用例步骤如下:
- 导入
unittest
模块,被测文件或者其中的类 - 创建一个测试类,并继承
unittest.TestCase
- 重写
setUp
和tearDown
方法(如果有初始化条件和结束条件) - 定义测试函数,函数名以
test
开头,测试用例 - 调用
unittest.main()
方法运行测试用例
- 导入
2. 用例的执行顺利
- 执行顺序是按照ASCII编码来的
四、测试集合
1. TestSuite&TestLoader的使用
-
TestSuite:测试集,把所有的用例都存进来。常用的方法如下:
-
unittest.TestSuite()
方法一:`addTest()` 添加一个测试用例
-
unittest.TestLoader()
方法二:unittest.TestLoader.loadTestsFromModule(模块名)不需要加引号(注意要导入模块) 方法三:unittest.TestLoader.loadTestsFromTestCase(模块名)不需要加引号
五、unittest断言介绍
方法 | 检查 |
---|---|
assertEqual(a,b) | a==b |
assertNotEqual(a,b) | a!=b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a,b) | a is b |
assertIsNot(a,b) | a is not b |
assertIn(a,b) | a in b |
assertNotIn(a,b) | a not in b |
六、执行测试用例&生成报告
1. TextTestRunner的用法
- 测试用例已经集合完毕,如何执行测试用例?
需要用到TextTestRunner,执行测试集,用到的是TextTestRunner()
,用run方法
# 创建一个测试运行程序对象(unittest.TextTestRuner)
# runner = unittest.TextTestRunner()
runner = HTMLTestRunner(stream=open('report.html', 'wb'),
# verbosity=2,
title='小欢的第一份测试报告',
description='注册账号的单元测试',
tester='xiaohuan')
# 通过运行程序,去执行测试套件中的测试用例
runner.run(suite)