编译整理|TesterHome社区
作者|Stanley Ulili
1.引言
pip install pytest
如果你想安装特定版本的 pytest,可以在命令中指定版本号,例如:
pip install pytest==5.4.3
3. 第一个 pytest 测试用例
让我们从一个简单的例子开始,了解 pytest 是如何工作的。创建一个名为test_example.py的文件,内容如下:
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
在这个例子中,我们定义了一个add函数,然后编写了一个名为test_add的测试用例。测试用例使用assert语句来验证add函数的输出是否符合预期。要运行这个测试用例,在命令行中进入包含test_example.py文件的目录,然后运行:
pytest
如果一切正常,你将看到类似以下的输出:
============================= test session starts =============================
platform linux -- Python 3.6.9, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
root@5605836111362047397950633459331456893668-ubuntu
collecting... done
collected 1 item
test_example.py.
============================== 1 passed in 0.01s ==============================
这里的.表示测试通过。如果测试失败,将会显示详细的错误信息。
4. pytest 的基本概念
4.1 测试函数
pytest 通过识别以test_开头的函数名来确定测试函数。在上面的例子中,test_add就是一个测试函数。你可以在一个文件中定义多个测试函数,它们将按照顺序依次被测试。
4.2 断言
断言是测试用例中最重要的部分之一。它用于验证代码的输出是否符合预期。在 pytest 中,通常使用assert语句来进行断言。例如:
def test_something():
value = some_function()
assert value == expected_value
如果value不等于expected_value,测试将失败,并显示详细的错误信息。
4.3 夹具(Fixtures)
夹具是 pytest 中一个非常重要的概念。它用于为测试用例提供一些前置条件和后置条件。例如,你可能需要在测试用例中使用一个数据库连接,夹具可以在测试开始前创建这个连接,并在测试结束后关闭它。夹具可以通过@pytest.fixture装饰器来定义,如下所示:
def database_connection():
connection = create_database_connection()
yield connection
connection.close()
在这个例子中,database_connection是一个夹具,它创建了一个数据库连接,并在测试结束后关闭它。在测试用例中,可以使用这个夹具,如下所示:
def test_database_operation(database_connection):
result = do_satabase_operation(database_connection)
assert result == expected_result
夹具可以有不同的作用域,例如函数级、类级、模块级和会话级。不同的作用域决定了夹具在测试过程中的重复使用方式。
4.4 测试模块和测试套件
一个测试模块是一个包含测试函数和夹具的 Python 文件。多个测试模块可以组成一个测试套件。你可以使用pytest命令来运行一个测试套件,它将自动收集所有的测试模块并进行测试。
4.5 标记(Markers)
标记是 pytest 中用于分类和筛选测试用例的一种手段。你可以使用@pytest.mark装饰器来给测试用例加上标记,例如:
def test_slow_function():
# 执行一个耗时的操作
pass
在这个例子中,test_slow_function被标记为slow。你可以使用pytest -m slow命令来只运行被标记为slow的测试用例。
5. 编写更复杂的测试用例
5.1 参数化测试
参数化测试是一种将测试用例中的某些参数进行变化的方法,从而可以用一个测试函数测试多个情况。例如,我们可以对上面的add函数进行参数化测试,如下所示:
import pytest
@pytest.mark.parametrize("a,b,expected", [(1, 2, 3), (2, 3, 5), (3, 4, 7)])
def test_add(a, b, expected):
assert add(a, b) == expected
在这个例子中,我们使用@pytest.mark.parametrize装饰器对test_add函数进行了参数化。参数化的参数为a、b和expected,分别对应add函数的两个输入参数和预期输出。通过这种方式,我们可以用一个测试函数测试add的多个输入输出组合。
5.2 处理异常
有时候我们需要测试代码在出现异常时的行为。在 pytest 中,可以通过@pytest.mark.raises装饰器来测试异常,如下所示:
import pytest
def test_division():
with open('non-existent-file.txt', 'r') as f:
content = f.read()
在这个例子中,test_division被标记为raises,并且期望在执行代码时出现Exception类型的异常。如果没有出现异常或者出现的异常类型不正确,测试将失败。
5.3 结合夹具和参数化测试
我们可以将夹具和参数化测试结合起来,以创建更复杂的测试用例。例如,假设我们有一个夹具database_connection和一个参数化测试函数test_database_operation,我们可以这样结合它们:
def test_database_operation(database_connection, a, b, expected):
result = do_database_operation(database_connection, a, b)
assert result == expected
在这个例子中,test_database_operation既使用了夹具database_connection,又使用了参数化测试的参数a、b和expected。通过这种方式,我们可以创建出更复杂的测试用例。
6. 测试文件和测试目录结构
在实际项目中,我们需要合理地安排测试文件和测试目录结构。一般来说,我们可以按照以下原则进行安排:
对于一个 Python 项目,通常在项目根目录下创建一个tests目录。
在tests目录下,可以根据项目的模块结构进一步细分测试目录。例如,如果项目有module1和module2两个模块,那么可以在tests目录下创建test_module1和test_module2两个子目录。
在每个测试子目录中,放置与该子目录对应的模块的测试文件。例如,在test_module1目录中放置test_module1.py文件。
通过这种结构,我们可以更方便地组织和管理测试文件,并且在运行测试时,pytest也更容易找到所有的测试文件。
7. 常见问题解答
7.1 如何知道我的测试是否有效?
如果测试通过,在运行测试时你会看到一个.表示通过。如果测试失败,会显示详细的错误信息,你可以根据这些信息来判断测试是否有效以及找出问题所在。
7.2 如何处理测试中的数据?
你可以使用夹具来处理测试中的数据。夹具可以创建模拟数据,也可以获取真实数据。例如,你可以定义一个夹具来创建一个数据库连接,然后通过这个连接获取真实数据,或者定义一个夹具来创建模拟数据,如上面提到的database_connection和fake_data夹具。
7.3 如何筛选特定的测试用例?
你可以使用标记来筛选特定的测试用例。例如,你可以使用pytest -m slow命令来只运行被标记为slow的测试用例。你也可以使用@pytest.mark装饰器给测试用例加上其他标记,然后根据这些标记来筛选测试用例。
7.4 如何在测试中使用真实数据?
你可以使用夹具来获取真实数据。例如,你可以定义一个夹具来创建一个数据库连接,然后通过这个连接获取真实数据。在测试用例中使用这个夹具,就可以使用真实数据进行测试。
7.5 如何加快测试速度?
可以通过以下几种方式加快测试速度:
减少不必要的测试用例。如果某些测试用例对项目质量影响不大,可以考虑删除它们。
优化测试数据。如果测试数据过多或者过于复杂,可以考虑简化它。
优化测试代码。如果测试代码存在冗余或者效率低下的问题,可以考虑优化它。
并行测试。如果你的计算机有多个核心,可以考虑使用并行测试技术,如pytest-xdist插件,可以同时运行多个测试用例,提高测试效率。
8. 结论
pytest 是一个功能强大、简洁易用的 Python 测试框架。通过本指南,你应该对 pytest 有了一个基本的了解,包括它的安装、基本概念、如何编写复杂的测试用例以及如何组织测试文件和测试目录结构。在实际项目中,熟练掌握 pytest 将有助于提高代码质量和项目的可维护性。希望本指南对你有所帮助,让你在测试 Python 代码时更加得心应手。(原文链接:https://betterstack.com/community/guides/testing/pytest-guide/)
1.自动化测试框架|我们为什么抛弃Selenium选择Playwright
3.已开源!一款支持HarmonyOS NEXT系统的UI自动化框架hmdriver2发布