Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytest_runtest_makereport of custom conftest doesn't get called when running with xdist with -n option #79

Closed
ssrikanta-scea opened this issue Aug 6, 2016 · 21 comments

Comments

@ssrikanta-scea
Copy link

I have noticed registering new plugin having the method (item, call)pytest_runtest_makereport doesn't get call back. However it works without -n option.

@ssrikanta-scea
Copy link
Author

Here is my sample conftest.

def pytest_configure(config):
    config._foo = FooBar()
    config.pluginmanager.register(config._foo)


def pytest_unconfigure(config):
    foo = getattr(config, '_foo', None)
    if foo:
        del config._foo
        config.pluginmanager.unregister(foo)



class FooBar(object):


    def pytest_runtest_makereport(self, item, call):

        print "pytest_runtest_makereport"


@ssrikanta-scea
Copy link
Author

Sample test file

class Test_Foo_Bar(object):


  def test_foo_bar_01(self):
    """
    test_foo_bar_01
    """
    assert 2 == 2

  @pytest.mark.xfail(reason="passed Simply")  
  def test_foo_bar_02(self):
    """
    test_foo_bar_02
    """
    assert 3 == 3

@ssrikanta-scea
Copy link
Author

Can some one look into this issue please.

@nicoddemus
Copy link
Member

Unfortunately printing on the slaves does not work because stdout is used for communication by execnet in the current implementation.

I changed your example slightly to write to a file instead:

# conftest.py
import os

def pytest_configure(config):
    config._foo = FooBar()
    config.pluginmanager.register(config._foo)
    if os.path.isfile('report'):
        os.remove('report')


def pytest_unconfigure(config):
    foo = getattr(config, '_foo', None)
    if foo:
        del config._foo
        config.pluginmanager.unregister(foo)

class FooBar(object):

    def pytest_runtest_makereport(self, item, call):
        with open('report', 'a+') as f:
            f.write(call.when + '\n')       

# test_foo.py
class Test_Foo_Bar(object):


  def test_foo_bar_01(self):
    """
    test_foo_bar_01
    """
    assert 2 == 2
$ py.test test_foo.py -n2 -q
gw0 [1] / gw1 [1]
scheduling tests via LoadScheduling
.
1 passed in 2.56 seconds
$
$ cat report
setup
call
teardown

@RonnyPfannschmidt
Copy link
Member

closing this one as missunderstanding on the op side, please notify if there is something missing

@nicoddemus
Copy link
Member

We should document this though, as it is a common catch: #82.

@ssrikanta
Copy link

@RonnyPfannschmidt If i prevent running on slave node i get the issue which i reported.
Actutally pytest_runtest_logreport in this case but not pytest_runtest_makereport.
I have made some tweaks and here is my sample code.

# conftest.py
import os

def pytest_configure(config):
    if not hasattr(config, 'slaveinput'):
        config._foo = FooBar()
        config.pluginmanager.register(config._foo)
        if os.path.isfile('report'):
            os.remove('report')


def pytest_unconfigure(config):
    foo = getattr(config, '_foo', None)
    if foo:
        del config._foo
        config.pluginmanager.unregister(foo)


class FooBar(object):

    def pytest_runtest_makereport(self, item, call):
        with open('report', 'a+') as f:
            f.write(call.when + '\n')


    def  pytest_runtest_logreport(self, report):
        with open('pytest_runtest_logreport', 'a+') as f:
            f.write(report.when + '\n')

@ssrikanta
Copy link

@nicoddemus @RonnyPfannschmidt My aim is to get access to both item and report even using xdist plugin.

@RonnyPfannschmidt
Copy link
Member

@ssrikanta by design the makereport happens only on the slave - item is never ever transfered to the master

@RonnyPfannschmidt
Copy link
Member

so by intended design the plugin you posted can not work

@ssrikanta
Copy link

@RonnyPfannschmidt Is there any alternative where can i access both item and report

@ssrikanta
Copy link

Also i have observed pytest_sessionfinish gets called multiple times when using xdist, IS there way to make it call only once after complete finish of session

@RonnyPfannschmidt
Copy link
Member

@ssrikanta its by design impossible to access item on the master - what do you want to use it for?

@RonnyPfannschmidt
Copy link
Member

@ssrikanta the session finish hook happens on every node also by design, you can figure if you are on the master by taking alook at session.config

@ssrikanta
Copy link

ssrikanta commented Aug 18, 2016

I need an reporter with test status and also i need to capture the doc string available with each test.
I can capture the doc string with item object

@RonnyPfannschmidt
Copy link
Member

so put the docstring into the report as a section

@ssrikanta
Copy link

But to do that i need a place where i can access both report and item rite, so which can run with xdist as well

@RonnyPfannschmidt
Copy link
Member

you put the section into the report in a hookwrapper for the makereport hook, then you can access it in the logreport hook

@ssrikanta
Copy link

Currently i am getting the results and test doc string in makereport hook and writing it to a file in session_finish hook, but the problem here is, if i wont restrict to run on slave nodes, session_finish will get called more than once.

@RonnyPfannschmidt
Copy link
Member

all nodes (masters and slaves) run session_finish

@jgzzzz
Copy link

jgzzzz commented Apr 7, 2023

I have a somehow similar question, when I call:
pytest.main([ -c pytest.ini path\testsuite1.py::test1 path\testsuite2.py::test2])
my tests are run and create and html report with pytest-html. When conftest.py is on the tests folder then the pytest_runtest_makereport (that I have written) gets called and the html report works with no problem.
When I call:
pytest.main([ path\conftest.py -c path\pytest.ini tests\testsuite1.py::test1 tests\testsuite2.py::test2])
The conftest is on a custom location and not on the tests folder then the pytest_runtest_makereport doesnt get called, the other hooks from the conftest work.
I am debugging and have notices that on the session.item.ihook there are hooks when conftest.py is on the tests folder. When the conftest.py is on the custom location outside the tests folder session.items.ihook contains a module of the conftest I passed:
report: TestReport = hook.pytest_runtest_makereport(item=item, call=call)
Do you know how can I make the tweak for the hook to work?
I will continue to debug but I want to see if I can get some support. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants