pytest-xdist icon indicating copy to clipboard operation
pytest-xdist copied to clipboard

Pytest-xdist doen't recognise custom plugin that is executed as pytest.main(sys.argv[1:], CustomPlugin())

Open The69Boi opened this issue 4 years ago • 4 comments

I have the following module which acts as a script to execute pytest.

class CustomPlugin:

    def pytest_configure(self,config):

        config.addinivalue_line(
            "python_files", "*.py"
        )
        config.addinivalue_line(
            "markers", "ignore_stdout: mark test to ignore stdout as failed task"
        )
        config.addinivalue_line(
            "markers", "ignore_stderr: mark test to ignore stderr as failed task"
        )
        config.addinivalue_line(
            "markers", "big: mark test as big and only running it certain times"
        )

    def is_setup_py(self,path):
        if path.basename != "setup.py":
            return False
        contents = path.read_binary()
        return b"setuptools" in contents or b"distutils" in contents
        
    def pytest_addoption(self,parser):
        parser.addoption("--big", dest="exclude_big",default=True, action='store_false', help='run big test')
        parser.addoption("--no-big", dest="exclude_big", action='store_true', help='miss big test [ default ]' )

    def pytest_collection_modifyitems(self,config, items):
        exclude_big = config.getoption("exclude_big")
        deselect_tests, selected = [],[]
        for item in items:
            if exclude_big and "big" in item.keywords or item.name == "test_ignore_this":
                deselect_tests.append(item)
            else:
                selected.append(item)
        items[:] = selected
        config.hook.pytest_deselected(items=deselect_tests)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(self, item,call):
        report = (yield).get_result()

        markers = [mark.name for mark in item.own_markers if mark.name in ['xfail','ignore_stdout','ignore_stderr']]
        
        if report.when == 'call' \
            and len(item._report_sections)>0 \
                and len(item._report_sections[0])==3 \
                    and 'ignore_stdout' not in markers \
                        and 'ignore_stderr' not in markers:
            if len(markers) > 0:
                report.outcome = "skipped"
            else:    
                report.outcome = "failed"


if __name__=='__main__':
    pytest.main(sys.argv[1:], plugins=[CustomPlugin()])

The script works as expected when I run it normally without pytest-xdist.

But when I use pytest-xdist it is not able to recognise the custom-plugin based markers and collection_modifications.

Attached the outputs while running normally as well as while using xdist

Output while executing normally

Output while executing using xdist

How to make pytest-xdist run the custom-plugin while executing the tests parallely?

The69Boi avatar Jun 10 '21 17:06 The69Boi

@nicoddemus any chance to get this looked at? 🙏

I've tested pretty much the same code and disabled xdist with -n 0 and it works

if __name__=='__main__':
    args = sys.argv[1:].extend(["-n", "0"])
    pytest.main(args, plugins=[CustomPlugin()])

Diaoul avatar Nov 22 '23 19:11 Diaoul

Support for this currently is not implemented

RonnyPfannschmidt avatar Nov 22 '23 22:11 RonnyPfannschmidt

What would it take to implement it? Maybe with some pointers I can attempt to give it a shot.

Diaoul avatar Nov 23 '23 08:11 Diaoul

Currently there's no mechanism to inject plugin instances into workers, so one needs to have a autoloaded plugin load them via worker input

There's no plans to support it directly as of now

RonnyPfannschmidt avatar Nov 23 '23 08:11 RonnyPfannschmidt