pytest 单元测试

pytest简介

pytestpython的一种单元测试框架,它非常的简洁、清晰。

pytest 安装

pip install -U pytest

查看pytest版本

pytest --version

入门

创建、运行第一个 test

test_first.py

def inc(x):
    return x + 1


def test_inc():
    assert inc(10) == 20

运行 pytest

an@hosta:~/PycharmProjects/testproject/pytest_study$ pytest     # 运行命令
========================================================== test session starts ==========================================================
platform linux -- Python 3.5.2, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/an/PycharmProjects/testproject/pytest_study, inifile: pytest.ini
plugins: xdist-1.22.0  
collected 1 item      # 搜集到的测试用例数量                                                                                                                

test_cont.py F   # F 代表测试出错,                                                                                                                 [100%]  # 测试完成率

=============================================================== FAILURES ================================================================
_______________________________________________________________ test_inc ____________________ # 测试模块名     _______________________________________

    def test_inc():
>       assert inc(10) == 20   # 报错的位置
E       assert 11 == 20   # 报错原因
E        +  where 11 = inc(10)   # 错误的来源
 
test_cont.py:6: AssertionError
======================================================= 1 failed in 0.04 seconds =============# 测试结果  =======================================

pytest 测试代码中抛出的异常

cont_test.py
import pytest


def inc(x):
    return x + 1


def test_inc():
    assert inc(10) == 11


def f():
    raise SyntaxError()

def test_f():
    with pytest.raises(SyntaxError):
        f()

运行pytest

an@hosta:~/PycharmProjects/testproject/pytest_study$ pytest
========================================================== test session starts ==========================================================
platform linux -- Python 3.5.2, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/an/PycharmProjects/testproject/pytest_study, inifile: pytest.ini
plugins: xdist-1.22.0
collected 2 items   # 两个测试用例                                                                                                                      

cont_test.py ..        # 两个 . 表示都测试成功了       F 表示失败                                                                                                    [100%]

======================================================= 2 passed in 0.01 seconds ========= #测试结果  =======================================

另一种方式运行多个测试。构造一个 测试类 里面包含多个测试用例

cont_test.py
import pytest
class TestClass:
    def test_one(self):
        x = "this"
        assert x != "that"

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

    def test_three(self):
        with pytest.raises(IndexError):
            raise IndexError

运行 pytest

运行pytest的退出码

Exit code 0:	All tests were collected and passed successfully
Exit code 1:	Tests were collected and run but some of the tests failed
Exit code 2:	Test execution was interrupted by the user
Exit code 3:	Internal error happened while executing tests
Exit code 4:	pytest command line usage error
Exit code 5:	No tests were collected
指定测试用例失败次数失败之后,就停止测试

pytest -x 在第一次失败之后,就停止运行剩余的测试
pytest --maxfail=2 两次失败之后,就停止运行剩余测试

指定运行测试用例

目录结构
|---pytest_test
        |
        |---cont_test.py

# 模块内容
cont_test.py

import pytest


def inc(x):
    return x + 1


def test_inc():
    assert inc(10) == 11


def f():
    raise SyntaxError()


@pytest.mark.slow
def test_f():
    with pytest.raises(SyntaxError):
        f()


class TestClass:
    def test_one(self):
        x = "t"
        assert x == "that"

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

    def test_three(self):
        with pytest.raises(IndexError):
            raise IndexError
  • 指定运行目录
    pytest pytest_test

  • 自动搜索运行本目录内的测试模块(以test开头或结尾)
    pytest_test$ pytest

  • 指定运行模块
    pytest_test$ pytest cont_test.py

  • 指定测试函数
    pytest_test$ pytest cont_test.py::test_inc

  • 指定测试类
    pytest_test$ pytest cont_test.py::TestClass

  • 指定测试方法
    pytest_test$ pytest cont_test.py::TestClass::test_one

  • 指定被mark的测试
    pytest_test$ pytest -m slow

将结果输出到 XML 文件
pytest --junitxml=/tmp/zz.xml

禁用pytest的扩展
pytest -p no:doctest -p no:django

方法二:
创建一个 pytest.ini 文件
pytest.ini
[pytest]
addopts = -p no:django -p no:forked -p no:xdist-1.22.0 -p no:celery
;禁用扩展

异常

捕获程序中故意引发的异常
def f():
    raise SyntaxError()

def test_f():
    with pytest.raises(SyntaxError):
        f()
指定测试失败的信息

def test_f():
    with pytest.raises(SyntaxError, message='this is i expected error'):
        pass

——————————————————————————————

------------------------------------------------ generated xml file: /home/an/haha.xml -------------------------------------------------
=============================================================== FAILURES ================================================================
________________________________________________________________ test_f _________________________________________________________________

    def test_f():
        with pytest.raises(SyntaxError, message='this is i expected error'):
>           pass
E           Failed: this is i expected error  # 正是我们所希望失败

cont_test.py:17: Failed
================================================== 1 failed, 3 passed in 0.06 seconds =====
进一步限定我们所期望的异常,match使用的 python 中 re.search 方法进行匹配
def test_f():
    with pytest.raises(ValueError, match=r'.?1'):
        raise ValueError("a1")
# 正常

def test_f():
    with pytest.raises(ValueError, match=r'.?1'):
        raise ValueError("z3")
_____________________________________________

============================================================== FAILURES ================================================================
________________________________________________________________ test_f _________________________________________________________________

    def test_f():
        with pytest.raises(ValueError, match=r'.?1'):
>           raise ValueError("z3")
E           ValueError: z3

cont_test.py:17: ValueError

During handling of the above exception, another exception occurred:

    def test_f():
        with pytest.raises(ValueError, match=r'.?1'):
>           raise ValueError("z3")
E           AssertionError: Pattern '.?1' not found in 'z3'    # 匹配失败

cont_test.py:17: AssertionError
================================================== 1 failed, 3 passed in 0.10 seconds ============
原文地址:https://www.cnblogs.com/jijizhazha/p/8522815.html