菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
pytest教程

pytest教程

阅读(15) 赞(0) 收藏 分享

 手册简介


pytest 是一个成熟的全功能 Python 测试工具,可以帮助你编写更好的程序。

 手册说明


该pytest框架使编写小型可读测试变得容易,并且可以扩展以支持应用程序和库的复杂功能测试。

pytest 开始使用

pytest需要你已掌握Python。

安装pytest

pytest需要:Python 3.7+ 或 PyPy3。
1、在命令行中运行以下命令:

pip install -U pytest

2、检查您是否安装了正确的版本:

$ pytest --version
pytest 7.1.0

创建你的第一个测试

创建一个名为 的新文件​test_sample.py​,其中包含一个函数和一个测试:

# content of test_sample.py
def func(x):
    return x + 1


def test_answer():
    assert func(3) == 5

测试结果

$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item

test_sample.py F                                                     [100%]

================================= FAILURES =================================
_______________________________ test_answer ________________________________

    def test_answer():
>       assert func(3) == 5
E       assert 4 == 5
E        +  where 4 = func(3)

test_sample.py:6: AssertionError
========================= short test summary info ==========================
FAILED test_sample.py::test_answer - assert 4 == 5
============================ 1 failed in 0.12s =============================

[100%] 是指运行所有测试用例的整体进度。 完成后,pytest 会显示失败报告,因为 func(3) 不返回 5。

运行多个测试

pytest将在当前目录及其子目录中运行 ​test_.py​ 或 ​_test.py​ 形式的所有文件。

断言引发了某个异常

使用 ​raises ​断言某些代码引发了异常:

# content of test_sysexit.py
import pytest


def f():
    raise SystemExit(1)


def test_mytest():
    with pytest.raises(SystemExit):
        f()

以“安静”报告模式执行测试功能:

$ pytest -q test_sysexit.py
.                                                                    [100%]
1 passed in 0.12s

将多个测试分组到一个类中

一旦您开发了多个测试,您可能希望将它们分组到一个类中。 pytest 可以很容易地创建一个包含多个测试的类:

# content of test_class.py
class TestClass:
    def test_one(self):
        x = "this"
        assert "h" in x

    def test_two(self):
        x = "hello"
        assert hasattr(x, "check")

pytest 按照其 Python 测试约定发现所有测试,因此它会找到两个以 ​test_ ​为前缀的函数。 不需要对任何东西进行子类化,但请确保在您的类前面加上 ​Test ​,否则该类将被跳过。 我们可以通过传递文件名来简单地运行模块:

$ pytest -q test_class.py
.F                                                                   [100%]
================================= FAILURES =================================
____________________________ TestClass.test_two ____________________________

self = <test_class.TestClass object at 0xdeadbeef0001>

    def test_two(self):
        x = "hello"
>       assert hasattr(x, "check")
E       AssertionError: assert False
E        +  where False = hasattr('hello', 'check')

test_class.py:8: AssertionError
========================= short test summary info ==========================
FAILED test_class.py::TestClass::test_two - AssertionError: assert False
1 failed, 1 passed in 0.12s

第一次测试通过,第二次失败。 您可以很容易地看到断言中的中间值,以帮助您了解失败的原因。

将测试分组在类中可能是有益的,原因如下:

  • 测试配置
  • 仅在该特定类中共享用于测试的固定装置
  • 在类级别应用标记,并将它们隐式应用于所有测试

在类中对测试进行分组时需要注意的是,每个测试都有一个唯一的类实例。 让每个测试共享相同的类实例对测试隔离非常不利,并且会促进不良的测试实践。 例如:

# content of test_class_demo.py
class TestClassDemoInstance:
    value = 0

    def test_one(self):
        self.value = 1
        assert self.value == 1

    def test_two(self):
        assert self.value == 1
$ pytest -k TestClassDemoInstance -q
.F                                                                   [100%]
================================= FAILURES =================================
______________________ TestClassDemoInstance.test_two ______________________

self = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002>

    def test_two(self):
>       assert self.value == 1
E       assert 0 == 1
E        +  where 0 = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002>.value

test_class_demo.py:9: AssertionError
========================= short test summary info ==========================
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0 == 1
1 failed, 1 passed in 0.12s

请注意,在类级别添加的属性是类属性,因此它们将在测试之间共享。

为功能测试请求一个唯一的临时目录

pytest提供内置​fixture /function​参数来请求任意资源,比如一个唯一的临时目录:

# content of test_tmp_path.py
def test_needsfiles(tmp_path):
    print(tmp_path)
    assert 0

在测试函数签名中列出名称​tmp_path​, pytest将在执行测试函数调用之前查找并调用一个​fixture​工厂来创建资源。在运行测试之前,pytest会创建一个每个测试调用唯一的临时目录:

$ pytest -q test_tmp_path.py
F                                                                    [100%]
================================= FAILURES =================================
_____________________________ test_needsfiles ______________________________

tmp_path = PosixPath('PYTEST_TMPDIR/test_needsfiles0')

    def test_needsfiles(tmp_path):
        print(tmp_path)
>       assert 0
E       assert 0

test_tmp_path.py:3: AssertionError
--------------------------- Captured stdout call ---------------------------
PYTEST_TMPDIR/test_needsfiles0
========================= short test summary info ==========================
FAILED test_tmp_path.py::test_needsfiles - assert 0
1 failed in 0.12s

通过下面的命令来了解内置pytest fixture的类型:

pytest --fixtures   # shows builtin and custom fixtures

注意,除非添加了​-v​选项,否则该命令会省略带有​_​前导的fixture。

 更多记录

    返回 学习猿地 官网主页