目录
[导入unittest模块 以及要测试的函数 get_formatted_name](#导入unittest模块 以及要测试的函数 get_formatted_name)
[python 运行这个文件中的测试](#python 运行这个文件中的测试)
名词解释
单元测试:用于核实函数的某个方面没有问题;
测试用例:是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。
全覆盖式试:用例包含一整套单元测试,涵盖了各种可能的函数使用方式
单元测试与测试用例
为函数编写测试用例的步骤
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()