【Pytest官方文档翻译及学习】1.1 安装和入门

目录

1.1 安装和入门

1.1.1 安装pytest

1.1.2 创建第一个测试

1.1.3 运行多个测试

1.1.4 断言引发了某个异常

1.1.5 将多个测试分组在一个类中

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

1.1.7 继续阅读


Pytest是一个成熟的全功能的Python测试框架,它可以满足大多数Python测试需求。以下是一些Pytest的主要特点:

  1. 简洁的语法:Pytest使用简洁的语法,使你的测试代码更加清晰易读。
  2. 丰富的内建功能:Pytest内建支持单元测试、功能测试、集成测试和回归测试。
  3. 灵活的fixture机制:Pytest提供了fixture机制,能够方便的在测试函数之间共享测试数据或测试状态。
  4. 参数化测试:Pytest支持参数化测试,可以用一组输入数据针对同一测试用例执行多次测试。
  5. 插件支持:Pytest有大量的插件,如用于测试覆盖率的pytest-cov,用于并行测试的pytest-xdist等。
  6. 兼容unittest框架:Pytest兼容Python标准库中的unittest测试框架,所以你可以在Pytest中运行unittest的测试用例。
  7. 详细的错误报告:当测试失败时,Pytest可以提供详细的错误报告,包括测试期间的输入数据、执行路径和异常堆栈。

在创建测试用例时,你不需要继承任何特定的类,只需要定义一个函数,并在函数名前加上test_前缀即可。Pytest会自动发现并运行这些测试用例。

安装pytest非常简单,只需在命令行中运行pip install pytest即可。

1.1 安装和入门

1.1.1 安装pytest

1、在命令行中运行以下命令:

pip install -U pytest

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

$ pytest --version
pytest 6.2.1

1.1.2 创建第一个测试

创建一个名为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-6.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
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 .

注:

您可以使用assert语句来验证测试期望值。pytest的高级断言内省(Advanced assertion introspection)将智能地报告断言表达式的中间值,这样您就可以避免使用多个名称JUnit遗留方法(of JUnit legacy methods)。

1.1.3 运行多个测试

pytest将运行当前目录及其子目录中test_*.py或*_test.py格式的所有文件。更一般地说,它遵循标准的测试发现规则(standard test discovery rules)。

1.1.4 断言引发了某个异常

使用 raises 助手来断言某些代码引发异常:

#content of test_sysexit.py

import pytest

def f():
    raise SystemExit(1)

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

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

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

注:

在本例和以下示例中,-q/--quiet标志使输出保持简短。

1.1.5 将多个测试分组在一个类中

一旦开发了多个测试,您可能需要将它们分组到一个类中。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测试发现的约定来发现所有测试( Conventions for Python test discovery),因此它可以找到两个带有test_前缀的函数。没有必要对任何东西进行子类化,但请确保在类前面加上Test,否则该类将被跳过。我们可以简单地通过传递其文件名来运行模块:

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

self = <test_class.TestClass object at 0xdeadbeef>

    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

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

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

pytest提供了 Builtin fixtures/function arguments参数来请求任意资源,比如一个唯一的临时目录:

# 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

有关临时目录处理的更多信息,请访问 Temporary directories and files

通过以下命令了解存在哪种内置pytest固定装置 pytest fixtures

pytest --fixtures   # shows builtin and custom fixtures

注意,这个命令省略了前导的fixtures _ 除非 -v 选项已添加。

1.1.7 继续阅读

查看其他Pytest资源以帮助您为独特的工作流自定义测试:

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值