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()
相关推荐
柒昀2 小时前
python环境配置
人工智能·python·深度学习
粉嘟小飞妹儿2 小时前
php怎么使用Ice RPC通信_php如何实现跨语言微服务远程调用
jvm·数据库·python
m0_377618232 小时前
C#怎么实现批量邮件发送 C#如何用MailKit批量发送个性化邮件和HTML格式邮件【网络】
jvm·数据库·python
m0_640309302 小时前
宝塔面板如何配置多版本PHP共存_针对不同站点指定环境
jvm·数据库·python
慕涯AI2 小时前
Agent 30 课程开发指南 - 第14课
人工智能·python
weixin_586061462 小时前
Go 中实现无侵入式方法级执行时间监控的完整实践指南
jvm·数据库·python
Ares-Wang2 小时前
flask 路由 add_url_rule 、@app.route app.test_request_context() 类视图
后端·python·flask
NotFound4862 小时前
golang如何实现时间格式化_golang时间格式化方法详解
jvm·数据库·python
DaqunChen2 小时前
PHP怎么合并数组_array_merge函数指南【指南】
jvm·数据库·python