Python -- 单元测试 unittest

目录

名词解释

单元测试与测试用例

为函数编写测试用例的步骤

[导入unittest模块 以及要测试的函数 get_formatted_name](#导入unittest模块 以及要测试的函数 get_formatted_name)

创建继承unittest.TestCase的类

编写一系列方法对函数行为的不同方面进行测试

[python 运行这个文件中的测试](#python 运行这个文件中的测试)

断言方法总结

测试结果解释

示例1

可选入参的处理

示例2

setUp()方法


名词解释

单元测试:用于核实函数的某个方面没有问题;

测试用例:是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。

全覆盖式试:用例包含一整套单元测试,涵盖了各种可能的函数使用方式

单元测试与测试用例

为函数编写测试用例的步骤

1、先导入模块unittest以及要测试的函数

2、再创建一个继承unittest.TestCase的类

3、在创建的类中编写一系列方法对函数行为的不同方面进行测试

导入unittest模块 以及要测试的函数 get_formatted_name

import unittest

from name_function import get_formatted_name

创建继承unittest.TestCase的类

class NameTestCase(unittest.TestCase) :

编写一系列方法对函数行为的不同方面进行测试

方法名以test_打头 在运行该.py时会自动运行这个方法,代码中无需去调用

self.assertEqual() 使用了unittest类最有用的功能之一:一个断言方法。

断言方法用来核实得到的结果是否与期望的结果一致。

def test_first_last_name(self) :

formatted_name = get_formatted_name("janis", "joplin")

self.assertEqual(formatted_name, "Janis Joplin")

python 运行这个文件中的测试

unittest.main()

断言方法总结

Python在unittest.TestCase类中提供了很多断言方法。如下列表:

| 方法 | 用途 |
| assertEqual(a, b) | 核实a == b |
| assertNotEqual(a, b) | 核实a != b |
| assertTrue(x) | 核实x为True |
| assertFalse(x) | 核实x为False |
| assertIn(item, list) | 核实item在list中 |

assertNotIn(item, list) 核实item不在list中

测试结果解释

测试通过 时打印一个句点"."

测试引发错误 时打印一个E

测试导致断言失败 时打印一个F

可以在下面实例中对照一下

示例1

定义一个模块name_funciton.py,里面包含一个合并姓名的函数

python 复制代码
# 合并姓名

def get_formatted_name(first, last) :
	"""Generate a neatly formatted full name."""
	full_name = first + " " + last
	# title() 首字母大写
	return full_name.title()

test_name_function.py

python 复制代码
# 1、导入 unittest 模块
import unittest

# 2、导入要测试的函数(name_function模块中的get_formatted_name函数)
from name_function import get_formatted_name

# 3、创建一个继承unittest.TestCase的类
class NameTestCase(unittest.TestCase) :
	"""测试 name_function.py"""
	
    # 4、 编写一系列方法对函数行为的不同方面进行测试
	# 方法名以test_打头 在运行该.py时会自动运行
	def test_first_last_name(self) :
		formatted_name = get_formatted_name("janis", "joplin")
		# unittest类最有用的功能之一:一个断言方法。
		# 断言方法用来核实得到的结果是否与期望的结果一致
		# assertEqual() 断言是否相等,相等则通过测试,否则抛出错误
		self.assertEqual(formatted_name, "Janis Joplin")

    # 测试包含是三个函数的情况
	def test_first_middle_last_name(self) :
		formatted_name = get_formatted_name("janis", "joplin", "simith")
		self.assertEqual(formatted_name, "Janis Joplin Simith")


# 让Python运行这个文件中的测试
unittest.main()

上方代码的运行结果如图:一个成功一个失败时

两个测试用例都失败的情况下运行结果:

def test_first_last_name(self):

formatted_name = get_formatted_name("janis", "joplinn")

调用get_formatted_name时第二个参数多加一个 "n",会断言不相等

如果有需求需要中间名可选,应该怎么做?

可选入参的处理

需要修改name_function.py,入参中给middle 一个默认值 -- 空,代码中通过if-else判断middle是否为空,来根据需求做相应处理。

python 复制代码
def get_formatted_name(first, last, middle=''):
	"""生成整洁的姓名"""
	if middle:
		full_name = first + ' ' + middle + ' ' + last
	else:
		full_name = first + ' ' + last
	return full_name.title()

修改后运行结果:

示例2

定义一个测试类survey.py (又称为survey模块),用于帮助管理匿名调查

python 复制代码
class AnonymousSurvey() :
	""" 收集你匿名调查问卷的答案 """

	# 定义构造器
	def __init__(self, question) :
		""" 存储一个问题,并为存储答案做准备 """
		# 初始化问题
		self.question = question
		# 创建空列表,用于存储答案
		self.responses = []

	# 打印问题
	def show_question(self) :
		""" 显示调查问卷 """
		print(question)

	# 存储答案
	def store_response(self, new_response) :
		""" 存储单份调查答卷 """
		# 追加答案到列表中
		self.responses.append(new_response)

	# 打印所有答案
	def show_result(self) :
		""" 显示收集到的所有答卷 """
		print("Survey results: ")
		for response in responses :
			print("- " + response)

针对上面的类进行测试

编写测试类 test_survey.py

python 复制代码
# 回忆一下进行单元测是的步骤
# 1 导入 unittest模块和需要测试的类
# 2 创建一个继承自 unittest.TestCase的类
# 3 在创建的类中编写一些列测试方法

import unittest
from survey import AnonymousSurvey 

class TestAnonymousSurvey(unittest.TestCase) :
	""" 针对AnonymousSurvey类的测试 """

	def test_store_single_response(self) :
		""" 测试单个答案会被妥善存储 """
		# 定义问题
		question = "What language did you first learn to speak?"
		# 创建AnonymousSurvey实例
		my_survey = AnonymousSurvey(question)
		# 调用实例中的store_response 方法存储答案
		my_survey.store_response('Chinese')

		# 断言答案是否被妥善存储
		self.assertIn('Chinese', my_survey.responses)


	def test_store_multi_response(self) :
		""" 测试多个答案会被妥善存储 """
		# 定义问题
		question = "What language did you first learn to speak?"
		# 创建AnonymousSurvey实例
		my_survey = AnonymousSurvey(question)
		# 调用实例中存储答案的方法
		responses = ["Chinese", "English", "Mandarin"]

		# for 循环存储答案
		for response in responses :
			my_survey.store_response(response)

		# for循环断言每个答案都被妥善存储
		for response in responses :
			self.assertIn(response, my_survey.responses)

unittest.main()

从上面的代码可以看出,test_survey.py中每个测试方法中都创建了AnonymousSurvey实例,问题,也都创建了答案,如图

存在冗余代码,如何仅写一次,然后在每个方法中使用呢?可以使用unittest.TestCase类中的方法setUp()

setUp()方法

def setUp(self) :

""" 创建一个调查对象和一组答案,供测试方法使用 """

question = "What language did you first learn to speak?"

self.my_survey = AnonymousSurvey(question)

self.responses = "English", "Spanish","Mandarin"

test_survey.py 修改后的代码

python 复制代码
# 回忆一下进行单元测是的步骤
# 1 导入 unittest模块和需要测试的类
# 2 创建一个继承自 unittest.TestCase的类
# 3 在创建的类中编写一些列测试方法

import unittest
from survey import AnonymousSurvey 

class TestAnonymousSurvey(unittest.TestCase) :
	""" 针对AnonymousSurvey类的测试 """

	def setUp(self) :
		"""
		创建一个调查对象和一组答案,供测试方法使用
		"""
		question = "What language did you first learn to speak?"
		# 创建一个调查对象
		self.my_survey = AnonymousSurvey(question)
		# 创建一个答案列表
		self.responses = ["English", "Spanish","Mandarin"]

	def test_store_single_response(self) :
		""" 测试单个答案会被妥善存储 """
		self.my_survey.store_response(self.responses[0])
		self.assertIn(self.responses[0], self.my_survey.responses)

	def test_store_multi_response(self) :
		""" 测试多个答案被妥善存储 """
		for response in self.responses :
			self.my_survey.store_response(response)

		for response in self.responses :
			self.assertIn(response, self.my_survey.responses)

unittest.main()
相关推荐
千天夜13 分钟前
深入剖析 `Path(path).parent.mkdir(parents=True, exist_ok=True)` —— 优雅处理目录创建的终极方案
python
简~76834 分钟前
python for in循环不能遍历整数怎么解决
python·大学生
aiqianji1 小时前
垂直专业的AI短篇小说写作软件有哪些特点?
人工智能·python
aqi001 小时前
15天学会AI应用开发(十三)上下文与RAG的阶段性总结
人工智能·python·大模型·ai编程·ai应用
程序员杰哥1 小时前
接口测试知识总结
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
大海变好AI1 小时前
专业的智能体算力架构高性价比品牌公司
python
江华森2 小时前
深入理解 Flask 实现原理
后端·python·flask
FriendshipT2 小时前
Ultralytics:解读SPPF模块
人工智能·pytorch·python·深度学习·目标检测
AOwhisky2 小时前
Python 基础语法(上篇 + 下篇)——综合自测题
linux·windows·python