1亩码、安裝和入門

pytest是一個能夠簡化測試系統(tǒng)構(gòu)建季率、方便測試規(guī)模擴展的框架,它讓測試變得更具表現(xiàn)力和可讀性--模版代碼不再是必需的描沟。

只需要幾分鐘的時間飒泻,就可以對你的應(yīng)用開始一個簡單的單元測試或者復(fù)雜的功能測試。

安裝

  • 命令行執(zhí)行如下命令:pipenv install pytest==5.1.3

  • 查看安裝的版本信息:pipenv run pytest --version

創(chuàng)建你的第一個測試用例

它只有四行代碼:

# src/chapter-1/test_sample.py

def func(x):
    return x + 1


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

通過以下命令執(zhí)行測試:

λ pipenv run pytest src/chapter-1/test_sample.py
============================= test session starts ============================== 
platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0
rootdir: D:\Personal Files\Projects\pytest-chinese-doc
collected 1 item

src\chapter-1\test_sample.py F                                            [100%]

=================================== FAILURES =================================== 
_________________________________ test_sample __________________________________

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

src\chapter-1\test_sample.py:28: AssertionError
============================== 1 failed in 0.05s ===============================

pytest返回一個失敗的測試報告吏廉,因為func(3)不等于5泞遗。

執(zhí)行多個測試用例

執(zhí)行pipenv run pytest命令,它會執(zhí)行當(dāng)前及其子文件夾中席覆,所有命名符合test_*.py或者*_test.py規(guī)則的文件史辙;

觸發(fā)一個指定異常的斷言

使用raises可以檢查代碼是否拋出一個指定的異常:

# src/chapter-1/test_sysexit.py

import pytest


def f():
    # 解釋器請求退出
    raise SystemExit(1)


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

執(zhí)行這個測試用例時,加上-q選項可以查看精簡版的測試報告:

λ pipenv run pytest -q src/chapter-1/test_sysexit.py
.                                                                         [100%] 
1 passed in 0.01s

在一個類中組織多個測試用例

pytest可以讓你很容易的通過創(chuàng)建一個測試類來包含多個測試用例:

# src/chapter-1/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')

現(xiàn)在我們來執(zhí)行這個測試用例:

λ pipenv run pytest -q src/chapter-1/test_class.py
.F                                                                        [100%] 
=================================== FAILURES =================================== 
______________________________ TestClass.test_two ______________________________

self = <test_class.TestClass object at 0x000001D364778E48>

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

src\chapter-1\test_class.py:30: AssertionError
1 failed, 1 passed in 0.05s

從輸出的報告中我們可以看到:

  • test_one測試通過佩伤,用.表示聊倔;test_two測試失敗,用F表示生巡;
  • 清除的看到耙蔑,test_two失敗的原因是:False = hasattr('hello', 'check')

注意:

測試類要符合特定的規(guī)則孤荣,pytest才能發(fā)現(xiàn)它:

  • 測試類的命令要符合Test*規(guī)則甸陌;
  • 測試類中不能有__init__()方法;

申請一個唯一的臨時目錄

pytest提供一些內(nèi)置的fixtures盐股,可以用來請求一些系統(tǒng)的資源钱豁。例如,一個唯一的臨時性目錄:

# src/chapter-1/test_tmpdir.py

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

在測試用例中遂庄,以形參的方式使用內(nèi)置的tempdir fixture寥院,pytest會事先創(chuàng)建一個目錄,并將一個py.path.local對象作為實參傳入涛目;

現(xiàn)在秸谢,我們來執(zhí)行這個測試用例:

λ pipenv run pytest -q src/chapter-1/test_tmpdir.py
F                                                                         [100%] 
=================================== FAILURES =================================== 
_______________________________ test_needsfiles ________________________________

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

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

src\chapter-1\test_tmpdir.py:25: AssertionError
----------------------------- Captured stdout call ----------------------------- C:\Users\luyao\AppData\Local\Temp\pytest-of-luyao\pytest-1\test_needsfiles0
1 failed in 0.05s

可以使用如下命令查看所有可用的fixtures,如果想同時查看以_開頭的fixtures霹肝,需要添加-v選項:

λ pipenv run pytest -q -v --fixtures
============================= test session starts ============================== 
platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0
rootdir: D:\Personal Files\Projects\pytest-chinese-doc
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 =============================
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末估蹄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沫换,更是在濱河造成了極大的恐慌臭蚁,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讯赏,死亡現(xiàn)場離奇詭異垮兑,居然都是意外死亡,警方通過查閱死者的電腦和手機漱挎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門系枪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人磕谅,你說我怎么就攤上這事私爷。” “怎么了膊夹?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵衬浑,是天一觀的道長。 經(jīng)常有香客問我放刨,道長工秩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任进统,我火速辦了婚禮拓诸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘麻昼。我一直安慰自己奠支,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布抚芦。 她就那樣靜靜地躺著倍谜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叉抡。 梳的紋絲不亂的頭發(fā)上尔崔,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音褥民,去河邊找鬼季春。 笑死,一個胖子當(dāng)著我的面吹牛消返,可吹牛的內(nèi)容都是我干的载弄。 我是一名探鬼主播耘拇,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宇攻!你這毒婦竟也來了惫叛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤逞刷,失蹤者是張志新(化名)和其女友劉穎嘉涌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夸浅,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡仑最,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了帆喇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片警医。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖番枚,靈堂內(nèi)的尸體忽然破棺而出法严,到底是詐尸還是另有隱情,我是刑警寧澤葫笼,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布深啤,位于F島的核電站,受9級特大地震影響路星,放射性物質(zhì)發(fā)生泄漏溯街。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一洋丐、第九天 我趴在偏房一處隱蔽的房頂上張望呈昔。 院中可真熱鬧,春花似錦友绝、人聲如沸堤尾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽郭宝。三九已至,卻和暖如春掷漱,著一層夾襖步出監(jiān)牢的瞬間粘室,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工卜范, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衔统,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像锦爵,于是被迫代替她去往敵國和親舱殿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容