pytest中文文档--安装和入门

目录

安装和入门

  • Python版本:Python 3.5, 3.6, 3.7, PyPy3
  • 平台: Linux或者Windows
  • PyPI包:pytest

pytest是一个测试框架,它能够简化测试系统的构建,和规模化测试的组织。测试系统将会变得更具有表现力和可读性———不再需要通过阅读模版代码来了解系统。只需要几分钟的时间,就可以开始对你的应用做一个简单的单元测试或者复杂的功能测试。

安装pytest

  1. 在你的命令行中执行如下命令:

     pip install -U pytest
  2. 检查pytest的版本信息:

     $ pytest --version
     This is pytest version 5.1.2, imported from $PYTHON_PREFIX/lib/python3.7/site-packages/pytest.py

创建你的第一个测试用例

创建一个简单的测试用例,它只有四行代码:

# test_sample.py

def func(x):
    return x + 1


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

现在你可以执行这个测试用例:

/d/Personal Files/Python/pytest-chinese-doc/src (5.1.2)
λ pytest test_sample.py
================================================= test session starts =================================================
platform win32 -- Python 3.7.3, pytest-5.1.2, py-1.8.0, pluggy-0.12.0
rootdir: D:\Personal Files\Python\pytest-chinese-doc\src
collected 1 item

test_sample.py F                                                                                                 [100%]

====================================================== FAILURES =======================================================
_____________________________________________________ test_sample _____________________________________________________

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

test_sample.py:28: AssertionError
================================================== 1 failed in 0.07s ==================================================

pytest返回一个失败的测试报告,因为func(3)不等于5

执行多个测试用例

在当前文件夹和子文件夹中,pytest会执行所有符合test_*.py*_test.py命名规则的文件。一般来说,其遵循标准的测试发现规则

检查代码是否触发一个指定的异常

使用raises可以检查代码是否抛出一个指定的异常:

# test_sysexit.py

import pytest


def f():
    # 解释器请求退出
    raise SystemExit(1)


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

执行这个测试用例,加上-q选项可以减少不必要的日志输出:

/d/Personal Files/Python/pytest-chinese-doc/src (5.1.2)
λ pytest -q test_sysexit.py
.                                                                                                                                                                [100%] 1 passed in 0.01s

在一个类中组织多个测试用例

当你需要新建多个相似的测试用例时,pytest可以让你很容易的通过创建一个测试类来包含所有的测试用例:

测试类的命名也有确定的规则,通常需要以Test开头或结尾;

# 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可以发现测试类中所有以test_开头的实例函数,查找过程遵循Python发现测试的约定,你只需要通过传入具体的文件名来执行这些测试:

/d/Personal Files/Python/pytest-chinese-doc/src (5.1.2)
λ pytest test_class.py
================================================= test session starts =================================================
platform win32 -- Python 3.7.3, pytest-5.1.2, py-1.8.0, pluggy-0.12.0
rootdir: D:\Personal Files\Python\pytest-chinese-doc\src
collected 2 items

test_class.py .F                                                                                                 [100%]

====================================================== FAILURES ======================================================= _________________________________________________ TestClass.test_two __________________________________________________

self = <test_class.TestClass object at 0x00000200EFA83550>

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

test_class.py:30: AssertionError
============================================= 1 failed, 1 passed in 0.05s =============================================

第一个用例测试通过,第二个用例测试失败。并且,你可以很清楚的看到失败断言处判断的依据。

申请一个唯一的临时目录用于功能测试

pytest提供一些内置的fixture,以参数的形式来请求任意资源,例如请求一个唯一的临时性目录:

# test_tmpdir.py

def test_needsfiles(tmpdir):
    print(type(tmpdir))
    print(tmpdir)
    assert 0

在测试用例执行前,pytest会查找并调用工厂函数tmpdir来创建一个的临时性目录,并返回其路径对象:

/d/Personal Files/Python/pytest-chinese-doc/src (5.1.2)
λ pytest -q test_tmpdir.py
F                                                                                                                [100%] ====================================================== FAILURES ======================================================= ___________________________________________________ test_needsfiles ___________________________________________________

tmpdir = local('C:\\Users\\luyao\\AppData\\Local\\Temp\\pytest-of-luyao\\pytest-0\\test_needsfiles0')

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

test_tmpdir.py:25: AssertionError
------------------------------------------------ Captured stdout call ------------------------------------------------- 
<class 'py._path.local.LocalPath'>
C:\Users\luyao\AppData\Local\Temp\pytest-of-luyao\pytest-0\test_needsfiles0
1 failed in 0.05s

查找有哪些可用的fixture

λ pytest --fixtures # 内置的和自定义的
================================================= test session starts =================================================
platform win32 -- Python 3.7.3, pytest-5.1.2, py-1.8.0, pluggy-0.12.0
rootdir: D:\Personal Files\Python\pytest-chinese-doc\src
collected 5 items
cache
    Return a cache object that can persist state between testing sessions.

    cache.get(key, default)
    cache.set(key, value)

    Keys must be a ``/`` separated value, where the first part is usually the
    name of your plugin or application to avoid clashes with other cache users.

    Values can be any object handled by the json stdlib module.

capsys
    Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``.

    The captured output is made available via ``capsys.readouterr()`` method
    calls, which return a ``(out, err)`` namedtuple.
    ``out`` and ``err`` will be ``text`` objects.

capsysbinary
    Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``.

    The captured output is made available via ``capsysbinary.readouterr()``
    method calls, which return a ``(out, err)`` namedtuple.
    ``out`` and ``err`` will be ``bytes`` objects.

capfd
    Enable text capturing of writes to file descriptors ``1`` and ``2``.

    The captured output is made available via ``capfd.readouterr()`` method
    calls, which return a ``(out, err)`` namedtuple.
    ``out`` and ``err`` will be ``text`` objects.

capfdbinary
    Enable bytes capturing of writes to file descriptors ``1`` and ``2``.

    The captured output is made available via ``capfd.readouterr()`` method
    calls, which return a ``(out, err)`` namedtuple.
    ``out`` and ``err`` will be ``byte`` objects.

doctest_namespace [session scope]
    Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests.

pytestconfig [session scope]
    Session-scoped fixture that returns the :class:`_pytest.config.Config` object.

    Example::

        def test_foo(pytestconfig):
            if pytestconfig.getoption("verbose") > 0:
                ...

record_property
    Add an extra properties the calling test.
    User properties become part of the test report and are available to the
    configured reporters, like JUnit XML.
    The fixture is callable with ``(name, value)``, with value being automatically
    xml-encoded.

    Example::

        def test_function(record_property):
            record_property("example_key", 1)

record_xml_attribute
    Add extra xml attributes to the tag for the calling test.
    The fixture is callable with ``(name, value)``, with value being
    automatically xml-encoded

record_testsuite_property [session scope]
    Records a new ``<property>`` tag as child of the root ``<testsuite>``. This is suitable to
    writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family.

    This is a ``session``-scoped fixture which is called with ``(name, value)``. Example:

    .. code-block:: python

        def test_foo(record_testsuite_property):
            record_testsuite_property("ARCH", "PPC")
            record_testsuite_property("STORAGE_TYPE", "CEPH")

    ``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.

caplog
    Access and control log capturing.

    Captured logs are available through the following properties/methods::

    * caplog.text            -> string containing formatted log output
    * caplog.records         -> list of logging.LogRecord instances
    * caplog.record_tuples   -> list of (logger_name, level, message) tuples
    * caplog.clear()         -> clear captured records and formatted log output string

monkeypatch
    The returned ``monkeypatch`` fixture provides these
    helper methods to modify objects, dictionaries or os.environ::

        monkeypatch.setattr(obj, name, value, raising=True)
        monkeypatch.delattr(obj, name, raising=True)
        monkeypatch.setitem(mapping, name, value)
        monkeypatch.delitem(obj, name, raising=True)
        monkeypatch.setenv(name, value, prepend=False)
        monkeypatch.delenv(name, raising=True)
        monkeypatch.syspath_prepend(path)
        monkeypatch.chdir(path)

    All modifications will be undone after the requesting
    test function or fixture has finished. The ``raising``
    parameter determines if a KeyError or AttributeError
    will be raised if the set/deletion operation has no target.

recwarn
    Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.

    See http://docs.python.org/library/warnings.html for information
    on warning categories.

tmpdir_factory [session scope]
    Return a :class:`_pytest.tmpdir.TempdirFactory` instance for the test session.

tmp_path_factory [session scope]
    Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.

tmpdir
    Return a temporary directory path object
    which is unique to each test function invocation,
    created as a sub directory of the base temporary
    directory.  The returned object is a `py.path.local`_
    path object.

    .. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html

tmp_path
    Return a temporary directory path object
    which is unique to each test function invocation,
    created as a sub directory of the base temporary
    directory.  The returned object is a :class:`pathlib.Path`
    object.

    .. note::

        in python < 3.6 this is a pathlib2.Path


================================================ no tests ran in 0.10s ================================================

这个命令会忽略以_开头的fixture,你可以通过添加-v选项来查看它们;

    原文作者:luizyao
    原文地址: https://www.cnblogs.com/luizyao/p/11481565.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞