目录
pip安装pytest
pytest库是一组工具,不仅能帮助你快速而轻松地编写测试,而且能持续支持随项目增大而变得复杂的测试。Python默认不包含pytest,因此你将学习如何安装外部库。
Python提供了一款名为pip的工具,可用来安装第三方包。因为pip帮我们安装来自外部的包,所以更新频繁,以消除潜在的安全问题。
pip安装更新
方式如下(win系统):在终端输入一下代码
python3 -m pip install --upgrade pip
如果还不明白,其实上网搜索一下就有很详细的教程。这一步不难。下面附上参考更新网址:
安装pytest
在终端输入以下命令:
pip install pytest
验证安装是否成功可以输入以下命令:
pytest --version
测试函数
测试准备工作
先写一个简单函数:name_function.py
def get_formatted_name(first, last):
"""生成格式规范的姓名"""
full_name = f"{first} {last}"
return full_name.title()
我们再来一个程序names.py从name_function.py中导入get_formatted_name():
from name_function import get_formatted_name
print("Enter 'q' at any time to quit.")
while True:
first = input("\nPlease give me a first name: ")
if first == 'q':
break
last = input("Please give me a last name: ")
if last == 'q':
break
formatted_name = get_formatted_name(first, last)
print(f"\tNeatly formatted name: {formatted_name}.")
可以跑names.py来验证程序可行。那么接下来我们就开始来测试这个函数!
这个针对get_formatted_name()函数的测试如下:test_name_function.py
from name_function import get_formatted_name
def test_first_last_name():
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formatted_name('janis', 'joplin')
assert formatted_name == 'Janis Joplin'
其中断言(assertion)就是声称满足特定的条件:这里声称formatted_name的值为'Janis Joplin'。
到目前为止,我们只介绍了一种断言:声称一个字符串变量取预期的值。在编写测试时,可做出任何可表示为条件语句的断言。下图列出了可在测试中包含的一些有用的断言,这里列出的只是九牛一毛,测试能包含任意可用条件语句表示的断言。
注意📢:
第一,测试函数必须以test_打头。在测试过程中,pytest将找出并运行所有以test_打头的函数。
第二,测试函数的名称应该比典型的函数名更长,更具描述性。
运行测试
如果直接运行文件test_name_function.py,将不会有任何输出,因为我们没有调用这个测试函数。相反,应该让pytest替我们运行这个测试文件。
测试方法一:
打开一个终端窗口,并切换到这个测试文件所在的文件夹。测试成功如下:
(在macOS系统中运行该测试的,因此你看到的输出可能与这里显示的不同。)
$ pytest
========================= test session starts =========================
platform darwin -- Python 3.x.x, pytest-7.x.x, pluggy-1.x.x
rootdir: /.../python_work/chapter_11
collected 1 item
test_name_function.py . [100%]
========================== 1 passed in 0.00s ==========================
测试方法二:VS Code,可打开测试文件所在的文件夹,并使用该编辑器内嵌的终端。在内置终端输入pytest 如果测试成功,会得到以下:
测试类
测试准备工作
先写一个要测试的类:survey.py
class AnonymousSurvey:
"""收集匿名调查问卷的答案"""
def __init__(self, question):
"""存储一个问题,并为存储答案做准备"""
self.question = question
self.responses = []
def show_question(self):
"""显示调查问卷"""
print(self.question)
def store_response(self, new_response):
"""存储单份调查答卷"""
self.responses.append(new_response)
def show_results(self):
"""显示收集到的所有答卷"""
print("Survey results:")
for response in self.responses:
print(f"- {response}")
这个类首先存储一个调查问题,并创建了一个空列表,用于存储答案。这个类包含打印调查问题的方法,在答案列表中添加新答案的方法,以及将存储在列表中的答案打印出来的方法。要创建这个类的实例,只需提供一个问题即可。有了表示调查的实例,就可以使用show_question()来显示其中的问题,使用store_response()来存储答案,并使用show_results()来显示调查结果了。
为了证明AnonymousSurvey类能够正确地工作,编写一个使用它的程序:language_survey.py
from survey import AnonymousSurvey
#定义一个问题,并创建一个表示调查的AnonymousSurvey对象
question = "What language did you first learn to speak?"
language_survey = AnonymousSurvey(question)
#显示问题并存储答案
language_survey.show_question()
print("Enter 'q' at any time to quit.\n")
while True:
response = input("Language: ")
if response == 'q':
break
language_survey.store_response(response)
#显示调查结果
print("\nThank you to everyone who participated in the survey!")
language_survey.show_results()
运行测试
下面来编写一个测试,对AnonymousSurvey类的行为的一个方面进行验证。我们要验证的是,如果用户在面对调查问题时只提供一个答案和提供三个答案时,答案都能被妥善地存储:
test_survey.py
from survey import AnonymousSurvey
def test_store_single_response():
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
language_survey = AnonymousSurvey(question)
language_survey.store_response('English')
assert 'English' in language_survey.responses
def test_store_three_responses():
"""测试三个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
language_survey = AnonymousSurvey(question)
responses = ['English', 'Spanish', 'Mandarin']
for response in responses:
language_survey.store_response(response)
for response in responses:
assert response in language_survey.responses
本人在VSCode内嵌终端输入pytest,运行成功如下图:
测试未通过时
应修复导致测试不能通过的代码:检查刚刚对函数所做的修改,找出这些修改是如何导致函数行为不符合预期的。
测试是很多初学者并不熟悉的主题。作为初学者,你并非必须为自己尝试的所有项目编写测试。但是,在参与工作量较大的项目时,应该对自己编写的函数和类的重要行为进行测试。这样就能够确信,自己所做的工作不会破坏项目的其他部分,让你能够随心所欲地改进既有的代码。