Search code examples
pythonpytestpytest-html

pytest html - pass images to the hook in conftest.py from a test file


I have a test that produce a HTML output via pytest-html.

I get the report, but I would like to add a reference to the failure and to the expected image; I save those in my main test.py file, and I added the hook to conftest.py.

Now, I have no idea how to pass those images to the function; the hook is called after the test is performed; and currently I am hardcoding the output files and they are attached; but I would like to pass the path to the image from the test instead, especially because I need to write more tests that may be saved somewhere else from my usual folder, and may have different names.

This is the hook I have in conftest.py

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):

    timestamp = datetime.now().strftime('%H-%M-%S')

    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, 'extra', [])
    if report.when == 'call':
        # Attach failure image, hardcoded...how do I pass this from the test?
        extra.append(pytest_html.extras.image('/tmp/image1.png'))

        # test report html
        extra.append(pytest_html.extras.url('http://www.theoutput.com/'))
        xfail = hasattr(report, 'wasxfail')
        if (report.skipped and xfail) or (report.failed and not xfail):
            # only add additional data on failure
            # Same as above, hardcoded but I want to pass the reference image from the test
            extra.append(pytest_html.extras.image('/tmp/image2.png'))
            extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
        report.extra = extra

How can I pass to the hook, a variable containing the path of the image(s) to attach, from my pytest test files?


Solution

  • I found a workaround, although it is not pretty.

    Adding a variable at module level in my test file, allow me to use item.module.varname, so if I set varname in my module test, and then assign it in the test; I can access it in pytest_runtest_makereport

    in testfile.py

    import pytest
    
    myvar1 = None
    myvar2 = None
    
    class VariousTests(unittest.TestCase):
    
        def test_attachimages():
    
            global myvar1
            global myvar2
    
            myvar1 = "/tmp/img1.png"
            myvar2 = "/tmp/img2.png"
    

    in conftest.py

    @pytest.mark.hookwrapper
    def pytest_runtest_makereport(item, call):
    
        timestamp = datetime.now().strftime('%H-%M-%S')
    
        pytest_html = item.config.pluginmanager.getplugin('html')
        outcome = yield
        report = outcome.get_result()
        extra = getattr(report, 'extra', [])
        if report.when == 'call':
            # Attach failure image
            img1 = item.module.myvar1
            img2 = item.module.myvar2
            extra.append(pytest_html.extras.png(img1))
            # test report html
            extra.append(pytest_html.extras.url('http://www.theoutput.com/'))
            xfail = hasattr(report, 'wasxfail')
            if (report.skipped and xfail) or (report.failed and not xfail):
                # only add additional data on failure
                # Same as above, hardcoded but I want to pass the reference image from the test
                extra.append(pytest_html.extras.png(img2))
                extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
            report.extra = extra