使用docstrings列出py.test中的测试

Mat*_*rth 19 python unit-testing pytest

这是一个简单的测试文件:

# test_single.py
def test_addition():
    "Two plus two is still four"
    assert 2 + 2 == 4

def test_addition2():
    "One plus one is still two"
    assert 1 + 1 == 2
Run Code Online (Sandbox Code Playgroud)

py.test中的默认输出就像

$ py.test test_single.py -v
[...]
test_single.py::test_addition PASSED
test_single.py::test_addition2 PASSED
Run Code Online (Sandbox Code Playgroud)

我想拥有

Two plus two is still four PASSED
One plus one is still two PASSED
Run Code Online (Sandbox Code Playgroud)

即使用docstrings作为测试的描述.

我试图在conftest.py文件中使用自定义:

import pytest

@pytest.mark.tryfirst
def pytest_runtest_makereport(item, call, __multicall__):
    # execute all other hooks to obtain the report object
    rep = __multicall__.execute()
    if rep.when == "call":
        extra = item._obj.__doc__.strip()
        rep.nodeid =  extra
    return rep
Run Code Online (Sandbox Code Playgroud)

这是接近的,但它在每一行重复文件名:

$ py.test test_single.py
======================================================================================== test session starts =========================================================================================
platform darwin -- Python 2.7.7 -- py-1.4.26 -- pytest-2.6.4
plugins: greendots, osxnotify, pycharm
collected 2 items

test_single.py
And two plus two is still four .
test_single.py
And one plus one is still two .

====================================================================================== 2 passed in 0.11 seconds ======================================================================================
Run Code Online (Sandbox Code Playgroud)

如何避免test_single.py输出中的线条,或者只打印一次?

查看py.test的来源及其一些插件没有帮助.

我知道pytest-spec插件,但它使用函数的名称作为描述.我不想写def test_two_plus_two_is_four().

Mis*_*dze 19

为了扩大我对迈克尔@婉的回答评论:才达到类似的东西来specplugin投入conftest.py:

def pytest_itemcollected(item):
    par = item.parent.obj
    node = item.obj
    pref = par.__doc__.strip() if par.__doc__ else par.__class__.__name__
    suf = node.__doc__.strip() if node.__doc__ else node.__name__
    if pref or suf:
        item._nodeid = ' '.join((pref, suf))
Run Code Online (Sandbox Code Playgroud)

和的pytest输出

class TestSomething:
"""Something"""

def test_ok(self):
    """should be ok"""
    pass
Run Code Online (Sandbox Code Playgroud)

会是这样的

py.test屏幕抓取

如果省略docstrings将使用class/func名称.


Sym*_*ric 5

对于(我认为)开箱即用的插件,请查看pytest-testdox

它提供了每个测试函数名称的友好格式化列表,其中test_删除了下划线,并将下划线替换为空格,以便测试名称可读。它还按测试文件分解各个部分。

输出如下所示:

在此输入图像描述


7H3*_*D3R 5

我缺少rspec in rubypython。因此,基于该插件pytest-testdox.,我编写了类似的文档,该文档将doc字符串作为报告消息。您可以检查出pytest-pspec在此处输入图片说明


Mic*_*Wan 2

@Matthias Berth,你可以尝试使用 pytest_itemcollected

def pytest_itemcollected(item):
""" we just collected a test item. """
    item.setNodeid('' if item._obj.__doc__ is None else item._obj.__doc__.strip() )
Run Code Online (Sandbox Code Playgroud)

并修改 pydir/Lib/site-packages/pytest-2.9.1-py2.7.egg/_pytest/unittest.py 将以下函数添加到 TestCaseFunction 类

def setNodeid(self, value):
    self._nodeid = value
Run Code Online (Sandbox Code Playgroud)

结果将是:

platform win32 -- Python 2.7.10, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- D:\Python27\python.exe
cachedir: .cache
rootdir: E:\workspace\satp2\atest\testcase\Search\grp_sp, inifile:
plugins: html-1.8.0, pep8-1.0.6
collecting 0 itemsNone
collected 2 items
Two plus two is still four <- sut_amap3.py PASSED
One plus one is still two <- sut_amap3.py PASSED
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 顺便说一句,当您使用 pytest-html 时,您可以使用您创建的 pytest_runtest_makereport 函数,它将生成具有您自定义名称的报告。希望这可以帮助。