快速入门
准备

- 安装
推荐安装anaconda,默认带pytest
# pip3 install pytest
...
$ pytest -h # 查看帮助
...
第一个实例(通过)
def test_passing():
assert (1, 2, 3) == (1, 2, 3)
函数test_passing()为测试函数,因为它以test_开头,并且在名字以test_开头的文件中。assert 语句决定测试是通过还是失败。assert 是 Python 内置的关键字,如果 assert 后面的表达式是假的将引发 AssertionError 异常。在测试中引发的任何未捕获的异常都会导致测试失败。尽管任何类型的未捕获的异常都会导致测试失败,但传统上我们坚持用assert的AssertionError来决定测试的通过/失败。
- 执行
$ pytest test_pass.py
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collected 1 item
test_pass.py . [100%]
============================== 1 passed in 0.08s ==============================
pass_test.py后的点表示一个测试运行并通过。 如果你需要更多信息,您可以使用-v或--verbose
$ pytest test_pass.py -v
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0 -- D:\ProgramData\Anaconda3\python.exe
cachedir: .pytest_cache
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collecting ... collected 1 item
test_pass.py::test_passing PASSED [100%]
============================== 1 passed in 0.08s ==============================
在彩色终端,PASSED和底线是绿色的。

第二个实例(失败)
def test_failing():
assert (1, 2, 3) == (3, 2, 1)
- 执行
$ pytest test_fail.py
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collected 1 item
test_fail.py F [100%]
================================== FAILURES ===================================
________________________________ test_failing _________________________________
def test_failing():
> assert (1, 2, 3) == (3, 2, 1)
E assert (1, 2, 3) == (3, 2, 1)
E At index 0 diff: 1 != 3
E Use -v to get more diff
test_fail.py:2: AssertionError
=========================== short test summary info ===========================
FAILED test_fail.py::test_failing - assert (1, 2, 3) == (3, 2, 1)
============================== 1 failed in 0.14s ==============================
pytest准确地告诉我们失败:At index 0 diff: 1 != 3。如果你有一个彩色终端,大部分内容会以红色显示。这个额外的部分显示了测试失败的确切位置和相关代码,被称为回溯。

同样-v可以获取更多信息
$ pytest test_fail.py -v
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0 -- D:\ProgramData\Anaconda3\python.exe
cachedir: .pytest_cache
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collecting ... collected 1 item
test_fail.py::test_failing FAILED [100%]
================================== FAILURES ===================================
________________________________ test_failing _________________________________
def test_failing():
> assert (1, 2, 3) == (3, 2, 1)
E assert (1, 2, 3) == (3, 2, 1)
E At index 0 diff: 1 != 3
E Full diff:
E - (3, 2, 1)
E ? ^ ^
E + (1, 2, 3)
E ? ^ ^
test_fail.py:2: AssertionError
=========================== short test summary info ===========================
FAILED test_fail.py::test_failing - assert (1, 2, 3) == (3, 2, 1)
============================== 1 failed in 0.15s ==============================
更多运行方式
要运行pytest,你可以选择指定文件和目录。如果你不指定任何文件或目录,pytest将在当前工作目录和子目录中寻找测试。它寻找以test_开头或以_test结尾的.py文件。在ch1目录下,如果运行没有命令的pytest,你将运行两个文件的测试。
$ pytest --tb=no
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collected 2 items
test_fail.py F [ 50%]
test_pass.py . [100%]
=========================== short test summary info ===========================
FAILED test_fail.py::test_failing - assert (1, 2, 3) == (3, 2, 1)
========================= 1 failed, 1 passed in 0.08s =========================
我还使用了 --tb=no 标志来关闭回溯,因为我们现在并不真正需要完整的输出。
我们也可以通过指定测试或列出目录名称来获得相同的测试集来运行。
$ pytest --tb=no test_pass.py test_fail.py
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collected 2 items
test_pass.py . [ 50%]
test_fail.py F [100%]
=========================== short test summary info ===========================
FAILED test_fail.py::test_failing - assert (1, 2, 3) == (3, 2, 1)
========================= 1 failed, 1 passed in 0.09s =========================
我们也可以通过在文件名中加入::test_name来指定在测试文件中运行的测试函数。
$ pytest -v ch1/test_pass.py::test_passing
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0 -- D:\ProgramData\Anaconda3\python.exe
cachedir: .pytest_cache
rootdir: D:\code\pytest_quick, configfile: pytest.ini
plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
collecting ... collected 1 item
ch1/test_pass.py::test_passing PASSED [100%]
============================== 1 passed in 0.08s ==============================
测试发现
pytest执行的部分,即pytest去寻找要运行的测试,被称为测试发现。pytest能够找到所有我们希望它运行的测试,因为我们根据pytest的命名规则给它们命名。
在没有参数的情况下,pytest会在你的当前目录和所有子目录中寻找测试文件,并运行它找到的测试代码。如果你给pytest文件名、目录名或列表,它就会在那里寻找,而不是在当前目录。在命令行中列出的每个目录都会被检查出测试代码,以及任何子目录。
下面是对命名规则的简要概述
- 测试文件应该被命名为test_<something>.py或<something>_test.py。
- 测试方法和函数应该被命名为test_<something>。
- 测试类应该被命名为Test<something>。
如果你的测试以不同方式命名,有办法改变这些发现规则。我将在第8章,配置文件中介绍如何做到这一点。
测试结果
到目前为止,我们已经看到一个通过的测试和一个失败的测试。然而,通过和失败并不是唯一可能的结果。
下面是可能结果:
- PASSED (.):测试成功。
- FAILED (F):测试失败。
- SKIPPED (s): 测试被跳过。 你可以使用@pytest.mark.skip()或 pytest.mark.skipif()修饰器告诉pytest跳过测试。
- XFAIL (x):预期测试失败。@pytest.mark.xfail()
- XPASS (X):测试被标记为xfail,但它运行并通过了。
- ERROR (E):异常发生在夹具或钩子函数的执行过程中,而不是测试函数的执行过程中。
网友评论