Use docstrings para listar pruebas en py.test

Aquí hay un simple archivo de prueba:

# 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 

La salida por defecto en py.test es como

 $ py.test test_single.py -v [...] test_single.py::test_addition PASSED test_single.py::test_addition2 PASSED 

me gustaría tener

 Two plus two is still four PASSED One plus one is still two PASSED 

es decir, utilizar las cadenas de documentación como descripciones para las pruebas.

Intenté usar una personalización en un archivo 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 

eso está cerca, pero repite el nombre de archivo en cada línea:

 $ 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 ====================================================================================== 

¿Cómo puedo evitar las líneas con test_single.py en la salida, o tal vez imprimirlo solo una vez?

Mirando en la fuente de py.test y algunos de sus complementos no ayudaron.

Soy consciente del complemento pytest-spec , pero que utiliza el nombre de la función como una descripción. No quiero escribir def test_two_plus_two_is_four() .

Para ampliar mi comentario a la respuesta de @ michael-wan: lograr algo similar a specplugin puesto en 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)) 

y la salida pytest de

 class TestSomething: """Something""" def test_ok(self): """should be ok""" pass 

se vera como

captura de pantalla de py.test

Si omite docstrings, se utilizarán los nombres de clase / función.

Me faltaba rspec in ruby para python. Entonces, basado en el plugin pytest-testdox. , He escrito uno similar que toma cadenas de documentos como mensaje de informe. Puedes comprobarlo en pytest-pspec . introduzca la descripción de la imagen aquí

Para un plugin que (creo) hace lo que quieres fuera de la caja, echa un vistazo a pytest-testdox .

Proporciona una lista fácil de usar con formato de cada nombre de función de prueba, con test_ stripped, y los guiones bajos reemplazados por espacios, de modo que los nombres de prueba sean legibles. También rompe las secciones por archivo de prueba.

Así es como se ve la salida:

introduzca la descripción de la imagen aquí

@Matthias Berth, puedes intentar usar 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() ) 

y modifique pydir / Lib / site-packages / pytest-2.9.1-py2.7.egg / _pytest / unittest.py agregue la siguiente función a la clase TestCaseFunction

 def setNodeid(self, value): self._nodeid = value 

y el resultado será:

 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 

introduzca la descripción de la imagen aquí a propósito, cuando esté usando pytest-html, puede usar la función pytest_runtest_makereport que creará y generará el informe con el nombre que ha personalizado. espero que esto ayude.