Pytest-rich - Pytest + rich integration (proof of concept)

Related tags

Testing pytest-rich
Overview

pytest-rich

Leverage rich for richer test session output.

This plugin is not published to PyPI yet.

PyPI version Python versions

IMPORTANT: Proof-of-concept

This plugin is mostly a prove of concept and is looking for a maintainer which wants to adopt it.

The plugin currently outputs this:

assets/screenshot.png

There's definitely room for improvement, and the new maintainers are free to improve on that or even change it completely.

I intend to initially add people as maintainers to this repository, and after a while eventually transfer it to another account.

The reason is that I played a bit with it and see promise in a full pytest + rich integration, but I don't have the bandwidth to maintain yet another pytest plugin, so I'm opening the code to the community in the hope that someone picks it up and gives it the treatment it deserves.

If you are interested, feel free to open an issue.

License

Distributed under the terms of the MIT license, "pytest-rich" is free and open source software


This pytest plugin was generated with Cookiecutter along with @hackebrot's cookiecutter-pytest-plugin template.

Comments
  • Add `RichExceptionChainRepr` for richer exception highlighting

    Add `RichExceptionChainRepr` for richer exception highlighting

    Yanked most of __rich_console__ from Rich's Traceback class and adapted for pytest's ExceptionChainRepr.

    I ignored locals for the time being, which I assume I can grab from reprlocals on each ReprEntry.

    There's no testing other than the eye test and the code could stand to be cleaned up a bit as well. But! It's working.

    image

    opened by joshuadavidthomas 15
  • Move project metadata to `setup.cfg`

    Move project metadata to `setup.cfg`

    Current Python packaging docs recommend using setup.cfg unless you need to support dynamic metadata.

    I see nothing in the current setup.py that necessitates a need for dynamic metadata (maybe in the future? but not now). Though, I am not a seasoned Python packager so I am open to the fact I may be wrong about this.

    opened by joshuadavidthomas 4
  • Better exception highlight in tracebacks

    Better exception highlight in tracebacks

    pytest doesn't provide the actual traceback objects during report (this is due to xdist support, because the report objects need to be serialized to be transferred between processes), we currently we only show the text with some simple highlighting.

    See if we can leverage rich's traceback highlighting somehow.

    opened by nicoddemus 4
  • Tweak GHA triggers for `test.yml` workflow

    Tweak GHA triggers for `test.yml` workflow

    Currently when a PR is opened, the Test workflow is run twice for each job in the os/python version matrix, one for the push and one for the PR.

    image

    I wonder if there isn't a way to tweak the triggers to only run once, perhaps by removing the pull_request trigger?

    opened by joshuadavidthomas 3
  • Deploy to PyPI

    Deploy to PyPI

    We should deploy to PyPI via CI.

    We can use pytest-mock's setup as starting point.

    Also I think we should release to PyPI sooner than later, even if the plugin is not ready, so we can reserve the project name.

    opened by nicoddemus 3
  • #4 - Add test summary

    #4 - Add test summary

    Adds #3 and #4

    Add a test summary at the end of the test suite.

    I've attempted this to the best of my knowledge. Any suggestions, comments, improvements are welcomed

    opened by bhavaniravi 2
  • Release 0.1.1

    Release 0.1.1

    I released 0.1.0 just now in order for the PyPI project to be created, so I could create an API token for it (#15).

    Also use setuptools-scm for versioning: this allow us to publish using tags to the repository.

    I plan to release 0.1.1 just to test the workflow works.

    opened by nicoddemus 2
  • Use mypy in pre-commit

    Use mypy in pre-commit

    Since we are using type annotations, I think we should enable mypy in the pre-commit configuration.

    We might also consider configuring mypy to demand type annotations for all parameters and return types in pytest_rich.py, while also enabling full type checking even in non-annotated functions under tests/.

    opened by nicoddemus 2
  • Allow for other plugins to add to report header

    Allow for other plugins to add to report header

    If you use another pytest plugin that adds additional info to the report header, e.g. pytest-django adds a line containing information about the Django app being tested, pytest-rich doesn't display this.

    pytest parity 
    opened by joshuadavidthomas 2
  • Adjust test workflow to not build on tags

    Adjust test workflow to not build on tags

    In #25 I noticed pushing a tag would run the entire 'test' workflow again, which is a waste because 'publish' also runs the tests.

    Also renamed the 'publish' workflow to match the same style used in 'test'.

    opened by nicoddemus 1
  • Fixed typo

    Fixed typo

    Hi !

    I'm not sure I'm good enough to help but I'm interested on this plugin as I find pytest and most of testing tools ugly in the Python ecosystem.

    Dunno how I can help, in all cases I will use this plugin for my next Python project ๐Ÿ˜

    opened by mickaelandrieu 1
  • Captured stdout/stderr not shown for test failures

    Captured stdout/stderr not shown for test failures

    With stock pytest, any captured stdout/stderr output is shown if a test fails, eg:

    -------------------------------------------------- Captured stderr call ---------------------------------------------------
    INFO:     Started server process [21684]
    INFO:     Waiting for application startup.
    ...
    ERROR:    Application startup failed. Exiting.
    

    With pytest-rich (latest; aea02fbe1e8dc85d7216e343ec52d06244ddc8c9) and pytest 7.2.0 on Python 3.11, this isn't shown in the output.

    feature pytest parity 
    opened by edmorley 1
  • Failures during test collection aren't shown

    Failures during test collection aren't shown

    If I make a Python syntax error in a test, or one of the project files imported by one of the tests, with stock pytest, I get an error like:

    $ pytest
    ====================================== test session starts =======================================
    platform darwin -- Python 3.11.0, pytest-7.2.0, pluggy-1.0.0
    rootdir: /Users/<snip>, configfile: pyproject.toml, testpaths: tests
    plugins: anyio-3.6.2
    collected 0 items / 2 errors                                                                     
    
    ============================================= ERRORS =============================================
    _______________________________ ERROR collecting tests/test_cli.py _______________________________
    ImportError while importing test module '<snip>/tests/test_cli.py'.
    Hint: make sure your test modules/packages have valid Python names.
    Traceback:
    <snip>
    =====================================
    ERROR tests/test_cli.py
    !!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ======================================= 2 errors in 0.14s ========================================
    

    However with pytest-rich installed and using pytest run using --rich, these errors are hidden:

    $ pytest --rich
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ pytest session starts โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
    โ”‚ platform darwin pytest 7.2.0 python 3.11.0                                                                      โ”‚
    โ”‚ root /Users/<snip>                                                                                              โ”‚
    โ”‚ plugins rich-0.1.2.dev26+gaea02fb, anyio-3.6.2                                                                  โ”‚
    โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
    Collected 0 items
    
    
    โ•ญโ”€โ”€โ”€โ”€ Summary โ”€โ”€โ”€โ”€โ”€โ•ฎ
    โ”‚  0  Total        โ”‚
    โ”‚     Tests        โ”‚
    โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ FAILED in 0.00 seconds โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    

    This was using the latest development version of pytest-rich (currently aea02fbe1e8dc85d7216e343ec52d06244ddc8c9).

    bug pytest parity 
    opened by edmorley 1
  • pytest-rich doesn't play well with pytest_runtest_makereport

    pytest-rich doesn't play well with pytest_runtest_makereport

    It looks like that the pytest-rich doesn't pay well with a custom pytest_runtest_makereport. I've the following example to reproduce the issue:

    # conftest.py
    import pytest
    from _pytest.reports import TestReport
    
    
    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(item, call):
        outcome = yield
        if item.config.getvalue("verbose") > 0:
            report = outcome.get_result()
    
            test_fn = item.obj
            docstring: str = getattr(test_fn, '__doc__')
            test_name = report.nodeid.split("::")[0]
            if docstring:
                report.nodeid = f"{docstring.strip()} <- {test_name}"
        else:
            when = call.when
            duration = call.stop - call.start
            keywords = dict([(x, 1) for x in item.keywords])
            sections = []
            default_test_report = TestReport(
                item.nodeid,
                item.location,
                keywords,
                outcome,
                None,
                when,
                sections,
                duration,
            )
            return default_test_report
    
    # test.py
    def test_one_plus_one_equals_2():
        """
        This is a test with a documentation that should show up on the pytest report
        """
        assert 1 == 1
    

    If I ran the test with pytest test.py --verbose --rich this is what I get:

    โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ pytest session starts โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎโ”‚ platform linux pytest 7.2.0 python 3.10.7                                                                                                                                                                                                                                                                                                                                                                                    โ”‚โ”‚ root /home/mazulo/dev/random_code/tests                                                                                                                                                                                                                                                                                                                                                                                      โ”‚โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏCollected 1 items
    โ ‹ [  0%] test.py
    โ ‹ Progress       INTERNALERROR> Traceback (most recent call last):
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/main.py", line 270, in wrap_session
    INTERNALERROR>     session.exitstatus = doit(config, session) or 0
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/main.py", line 324, in _main
    INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/main.py", line 349, in pytest_runtestloop
    INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/runner.py", line 112, in pytest_runtest_protocol
    INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/runner.py", line 125, in runtestprotocol
    INTERNALERROR>     rep = call_and_report(item, "setup", log)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/runner.py", line 224, in call_and_report
    INTERNALERROR>     hook.pytest_runtest_logreport(report=report)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pytest_rich.py", line 225, in pytest_runtest_logreport
    INTERNALERROR>     self._update_task(report.nodeid)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pytest_rich.py", line 194, in _update_task
    INTERNALERROR>     task = self.runtest_tasks_per_file[fn]
    โ ‹ [  0%] test.py
    โ ‹ Progress
    

    However if I remove the --rich from there, it works just fine:

    dev/random_code/tests via ๐Ÿ v3.10.7 (tests) 
    โฏ pytest test.py --verbose
    ===================================================================================================================================================================================================== test session starts ======================================================================================================================================================================================================platform linux -- Python 3.10.7, pytest-7.2.0, pluggy-1.0.0 -- /home/mazulo/.virtualenvs/tests/bin/python
    cachedir: .pytest_cache
    rootdir: /home/mazulo/dev/random_code/tests
    plugins: spec-3.2.0, rich-0.1.1
    collected 1 item                                                                                                                                                                                                                                                                                                                                                                                                                
    
    test.py::test_one_plus_one_equals_2
    This is a test with a documentation that should show up on the pytest report <- test.py PASSED                                                                                                                                                                                                                                                                                                                           [100%] 
    
    ====================================================================================================================================================================================================== 1 passed in 0.00s =======================================================================================================================================================================================================
    

    Something more weird happens when I use the approach outlined here: https://stackoverflow.com/a/61002385/3716354

    # conftest.py
    
    import inspect
    import pytest
    
    
    @pytest.hookimpl(trylast=True)
    def pytest_configure(config):
        terminal_reporter = config.pluginmanager.getplugin("terminalreporter")
        config.pluginmanager.register(
            TestReportDocstringPlugin(terminal_reporter), "testreportdocstring"
        )
    
    class TestReportDocstringPlugin:
        def __init__(self, terminal_reporter):
            self.terminal_reporter = terminal_reporter
            self.docstring = None
    
        @pytest.hookimpl(tryfirst=True, hookwrapper=True)
        def pytest_runtest_setup(self, item):
            self.docstring = inspect.getdoc(item.obj)
            yield
    
        @pytest.hookimpl(hookwrapper=True, tryfirst=True)
        def pytest_runtest_logfinish(self, nodeid: str, location):
            if self.terminal_reporter.verbosity == 0:
                yield
            else:
                if self.docstring:
                    test_name = nodeid.split("::")[0]
                    docstring = self.docstring.strip()
                    self.terminal_reporter.write(f"\n{docstring} <- {test_name}")
                yield
    

    This is the result of running pytest test.py -vvv --rich (actually this same error happens when running without the -vvv flag):

    dev/random_code/tests via ๐Ÿ v3.10.7 (tests) 
    โฏ pytest test.py -vvv --rich
    โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ pytest session starts โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎโ”‚ platform linux pytest 7.2.0 python 3.10.7                                                                                                                                                                                                                                                                                                                                                                                    โ”‚โ”‚ root /home/mazulo/dev/random_code/tests                                                                                                                                                                                                                                                                                                                                                                                      โ”‚โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏCollected 1 items
      [100%] test.py โœ”
    โ ‹ Progress        INTERNALERROR> Traceback (most recent call last):
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/main.py", line 270, in wrap_session
    INTERNALERROR>     session.exitstatus = doit(config, session) or 0
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/main.py", line 324, in _main
    INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/main.py", line 349, in pytest_runtestloop
    INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
    INTERNALERROR>     res = hook_impl.function(*args)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/_pytest/runner.py", line 113, in pytest_runtest_protocol
    INTERNALERROR>     ihook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
    INTERNALERROR>     return outcome.get_result()
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    INTERNALERROR>     raise ex[1].with_traceback(ex[2])
    INTERNALERROR>   File "/home/mazulo/.virtualenvs/tests/lib/python3.10/site-packages/pluggy/_callers.py", line 34, in _multicall
    INTERNALERROR>     next(gen)  # first yield
    INTERNALERROR>   File "/home/mazulo/dev/random_code/tests/conftest.py", line 24, in pytest_runtest_logfinish
    INTERNALERROR>     if self.terminal_reporter.verbosity == 0:
      [100%] test.py โœ”
    โ ‹ Progress
    

    For some reason it seems to get stuck at if self.terminal_reporter.verbosity == 0 what shouldn't happen since we're passing the -vvv flag. So it seems that for some reason this flag is being ignored.

    bug pytest parity 
    opened by mazulo 4
Owner
Bruno Oliveira
Software developer, OS enthusiast, pytest core maintainer, and author of various pytest plugins. Contributing to @pytest-dev and @conda-forge. Works at @ESSS.
Bruno Oliveira
frwk_51pwn is an open-sourced remote vulnerability testing and proof-of-concept development framework

frwk_51pwn Legal Disclaimer Usage of frwk_51pwn for attacking targets without prior mutual consent is illegal. frwk_51pwn is for security testing purp

51pwn 4 Apr 24, 2022
ApiPy was created for api testing with Python pytest framework which has also requests, assertpy and pytest-html-reporter libraries.

ApiPy was created for api testing with Python pytest framework which has also requests, assertpy and pytest-html-reporter libraries. With this f

Mustafa 1 Jul 11, 2022
Playwright Python tool practice pytest pytest-bdd screen-play page-object allure cucumber-report

pytest-ui-automatic Playwright Python tool practice pytest pytest-bdd screen-play page-object allure cucumber-report How to run Run tests execute_test

moyu6027 11 Nov 8, 2022
pytest plugin providing a function to check if pytest is running.

pytest-is-running pytest plugin providing a function to check if pytest is running. Installation Install with: python -m pip install pytest-is-running

Adam Johnson 21 Nov 1, 2022
Pytest-typechecker - Pytest plugin to test how type checkers respond to code

pytest-typechecker this is a plugin for pytest that allows you to create tests t

vivax 2 Aug 20, 2022
A pytest plugin to run an ansible collection's unit tests with pytest.

pytest-ansible-units An experimental pytest plugin to run an ansible collection's unit tests with pytest. Description pytest-ansible-units is a pytest

Community managed Ansible repositories 9 Dec 9, 2022
pytest splinter and selenium integration for anyone interested in browser interaction in tests

Splinter plugin for the pytest runner Install pytest-splinter pip install pytest-splinter Features The plugin provides a set of fixtures to use splin

pytest-dev 238 Nov 14, 2022
A rewrite of Python's builtin doctest module (with pytest plugin integration) but without all the weirdness

The xdoctest package is a re-write of Python's builtin doctest module. It replaces the old regex-based parser with a new abstract-syntax-tree based pa

Jon Crall 174 Dec 16, 2022
A Django plugin for pytest.

Welcome to pytest-django! pytest-django allows you to test your Django project/applications with the pytest testing tool. Quick start / tutorial Chang

pytest-dev 1.1k Dec 31, 2022
A set of pytest fixtures to test Flask applications

pytest-flask An extension of pytest test runner which provides a set of useful tools to simplify testing and development of the Flask extensions and a

pytest-dev 433 Dec 23, 2022
A command-line tool and Python library and Pytest plugin for automated testing of RESTful APIs, with a simple, concise and flexible YAML-based syntax

1.0 Release See here for details about breaking changes with the upcoming 1.0 release: https://github.com/taverntesting/tavern/issues/495 Easier API t

null 909 Dec 15, 2022
The pytest framework makes it easy to write small tests, yet scales to support complex functional testing

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. An example o

pytest-dev 9.6k Jan 2, 2023
Coverage plugin for pytest.

Overview docs tests package This plugin produces coverage reports. Compared to just using coverage run this plugin does some extras: Subprocess suppor

pytest-dev 1.4k Dec 29, 2022
Thin-wrapper around the mock package for easier use with pytest

pytest-mock This plugin provides a mocker fixture which is a thin-wrapper around the patching API provided by the mock package: import os class UnixF

pytest-dev 1.5k Jan 5, 2023
pytest plugin for distributed testing and loop-on-failures testing modes.

xdist: pytest distributed testing plugin The pytest-xdist plugin extends pytest with some unique test execution modes: test run parallelization: if yo

pytest-dev 1.1k Dec 30, 2022
Plugin for generating HTML reports for pytest results

pytest-html pytest-html is a plugin for pytest that generates a HTML report for test results. Resources Documentation Release Notes Issue Tracker Code

pytest-dev 548 Dec 28, 2022
Pytest support for asyncio.

pytest-asyncio: pytest support for asyncio pytest-asyncio is an Apache2 licensed library, written in Python, for testing asyncio code with pytest. asy

pytest-dev 1.1k Jan 2, 2023
Mypy static type checker plugin for Pytest

pytest-mypy Mypy static type checker plugin for pytest Features Runs the mypy static type checker on your source files as part of your pytest test run

Dan Bader 218 Jan 3, 2023
:game_die: Pytest plugin to randomly order tests and control random.seed

pytest-randomly Pytest plugin to randomly order tests and control random.seed. Features All of these features are on by default but can be disabled wi

pytest-dev 471 Dec 30, 2022