最好的状态是一点点向喜欢的东西靠近!
文章目录
一、什么单元测试
单元:函数或者是类
单元测试:测试类或者函数
1.为什么要做单元测试
好处:投入小,收益大。能够精准的,更早的发现问题。
对于我们测试来说:我们就单元测试是为了执行测试用例!
输入测试数据---->输出测试结果
用到unittest模块
2.单元测试框架
内置的单元测试框架:unittest
unittest中最核心的四个概念是:test case, test suite, test runner, test fixture。
TestCase:一个testcase的实例就是一个测试用例:
TestSuite:多个测试用例集合在一起
TestLoader:是用来加载TestCase到TestSuite中的
TextTestRunner:用来执行测试用例的。其中的run(test)会执行
TestSuite/TestCase中的run(result)方法。
TextTestResult:保存TextTestRunner执行的测试结果。
fixture:测试用例环境的搭建和销毁。测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)
3.unittest 的注意事项
- 模块名称 test_ …
- 类名: Test…
- 测试用例的方法名称 test_…
- TestLogin(unittest.TestCase)
二、unittest 如何测试测试用例
1.unittest 测试用例执行顺序
- 不是从上到下
- 根据测试用例的名称 ==》 ASCII
2.用例执行:
- 右击 unittest 运行
- python 运行 unittest.main()
- 运行所有的测试用例
3.用例的组织
会把测试用例的代码放到一个统一的文件夹当中,
目录当中。
tests/ testcases
4.收集用例
需要把每个测试用例模块当中的测试用例收集到一起,一起执行。
三、运行用例的流程
- 1.写用例方法。用例方法当道一个目录当中。
- 2.写脚本 run.py, (收集用例,运行用例)
- 3.loader 收集用例, suite = discover()
- 4.得到测试集 suite
- 5.运行, test_runner = HTMLTestRuner()
"""运行程序。
收集所有的测试用例,
执行。
生成测试报告。
"""
import unittest
import os
# 初始化一个加载器, test_loader
from HTMLTestRunnerNew import HTMLTestRunner
from 绝对路径 import test_login, test_register
loader = unittest.TestLoader()
# 获取测试用例目录的路径
dir_path = os.path.dirname(os.path.abspath(__file__))
case_path = os.path.join(dir_path, 'tests')
# 使用 loader 收集所有的测试用例
test_suit = loader.discover(case_path)
print(test_suit)
# 只加载注册的和登录的用例
suite_login = loader.loadTestsFromModule(test_login)
suite_register = loader.loadTestsFromModule(test_register)
# 初始化一个 suite
suit_total = unittest.TestSuite()
suit_total.addTests([suite_login, suite_register])
# # 执行测试用例
# runner = unittest.TextTestRunner()
# runner.run(test_suit)
# 生成测试报告
# with open("test_reports.txt", 'w', encoding='utf-8') as f:
# runner = unittest.TextTestRunner(f)
# runner.run(test_suit)
# HTML 测试报告 不是内置。是需要自己准备的。
with open("test_reports.html", 'wb') as f:
runner = HTMLTestRunner(
f,
title='XXX测试报告',
description="测试报告的描述",
tester='蘑菇'
)
runner.run(suit_total)
TestCase
1.TestCase
继承unittest里面的TestCase类,继承这个类,写能写测试用例。
每个用例我们都要记得引入fixture,做一些准备以及结束的工作。
我们来操作写个用例,编写步骤如下:
1、导入unittest模块、被测文件或者其中的类
2、创建一个测试类,并继承unittest.TestCase
3、重写setUp和tearDown方法(如果有初始化条件和结束条件)
4、定义测试函数,函数名以test_开头。 测试用例
5、调用unittest.main()方法运行测试用例。
2.TestSuite&TestLoader的使用
TestSuite:测试集,把所有的用例都存进来。常用的方法如下:
unittest.TestSuite()
方法一:addTest() 添加一个测试用例
方法二:addTests([,]) 添加多个测试用例 添加用例的方式是一样的。
unittest.TestLoader()
方法一:unittest.TestLoader.loadTestsFromModule(模块名)#不需要加引号
方法二:unittest.TestLoader.loadTestsFromTestCase
3.TextTestRunner的用法
测试用例已经集合完毕,如何来执行用例?
----->需要用到TextTestRunner,执行测试集,用到的是TextTestRunner(),用 run方法。
runner=unittest.TextTestRunner()
runner.run(suite)#这里传入测试集合
这个就解决了这个问题:多个测试类文件的情况下,如何一起运行?
.表示用例通过 一个点表示一个用例
E 表示出错了
F表示不通过
4.输出测试报告-text or html
text类型报告:
#创建一个文件,以写的方式的打开
fs = open(“test_result.txt”,“w”)
runner = unittest.TextTestRunner(fs)
runner.run(suite)
html类型报告:
now = time.strftime(’%Y-%m-%d_%H_%M_%S’)#随机生成时间
#关键代码:
#执行测试集合
filePath = “pyResult”+now+".html"
fp = open(filePath,‘wb’)
#生成报告的Title,描述
runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title=‘Python Test Report’,description=‘This is Python Report’)
runner.run(suite)
5.断言简介
四、运行代码
"""测试登录功能(函数)"""
import unittest
def login(username=None, password=None):
"""登录"""
if (not username) or (not password):
# 用户名或者密码为空
return {"msg": "empty"}
if username == 'mogu' and password == '123456':
# 正确的用户名和密码
return {"msg": "success"}
return {"msg": "error"}
def login(username=None, password=None):
"""登录"""
if username != None and password != None:
if username == 'mogu' and password == '123456':
return {"msg": "login success"}
else:
return {"msg": "username or password error"}
else:
return {"msg": "username or password is empty"}
class TestLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("一个测试类只执行一次的前置")
@classmethod
def tearDownClass(cls):
print("一个测试类只执行一次的后置")
# 固定的名称,不改
def setUp(self):
"""前置"""
print("链接数据库")
def tearDown(self):
"""后置"""
print("断开数据库")
# 测试用例的方法
def test_login_01_success(self):
"""登录成功用例"""
username = 'mogu'
password = '123456'
expected_response = {"msg": "login success"}
# 调用被测试的单元,
actual_response = login(username, password)
# 判断预期结果和实际结果是否存在某种关系 , 断言 assert
# self.assertEqual()
# TODO:
# AssertionError
self.assertTrue( expected_response == actual_response )
# if expected_response == actual_response:
# print("测试用例")
# else:
# print("测试用例")
def test_login_02_error(self):
username = ''
password = ''
expected_response = {"msg": "username or password error"}
actual_response = login(username, password)
self.assertTrue(expected_response == actual_response)
def test_demo(self):
pass
def test_demo_1(self):
pass