Python Forum
Pytest-html hook help - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Web Scraping & Web Development (https://python-forum.io/forum-13.html)
+--- Thread: Pytest-html hook help (/thread-7623.html)



Pytest-html hook help - flashnet1 - Jan-18-2018

Hi there,

I discovered pytest-html and using it as is, and it seems very nice and helpful.

I need to add a sorted column to it's report, and I just can't figure out the hook explanation given.
Here the link to the pytest-html package.

It has a section of "Modifying the results table", but doesn't say exactly where to put the code, and how do I refer to these fields from the tests.
I have test class that run methods (parameterized) and each has data that should be added as an additional column.
On each test I have server name info that I want to add a a column.

Any help or insight is welcomed :)
Thank you


RE: Pytest-html hook help - buran - Jan-18-2018

I didn't use it, but it looks like the code from the example should go at the top of your script where the tests are.
looking at the example
you need to do something like this
@pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
    cells.append(html.th('Server Name'))

@pytest.mark.optionalhook
def pytest_html_results_table_row(report, cells):
    cells.append(html.td(report.server_name))

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
    outcome = yield
    report = outcome.get_result()
    report.server_name = str(item.function.locals()['server_name'])
on the last line, RHS of the =, you need to make adjustments in order to pass whatever value you want to pass to report.server_name


RE: Pytest-html hook help - buran - Jan-18-2018

OK, I was wrong.
The code should go in conftest.py in the same folder as tests.

from py.xml import html
import pytest

@pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
    cells.append(html.th('Server Name'))

@pytest.mark.optionalhook
def pytest_html_results_table_row(report, cells):
    cells.append(html.td(report.server_name))

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
    outcome = yield
    report = outcome.get_result()
    report.server_name = item.function.__doc__
I haven't discovered yet how to access custom variables from test function. One should look more into pytest module docs. In the above example it will print the docstring of the test function.

[attachment=352]

Also, you may use extras example to add different info in Links section - URL, plain text, images, etc.


RE: Pytest-html hook help - flashnet1 - Jan-18-2018

Thank U for the reply, it was really helpful.

In the first two methods I did some changes to enable sortable new field (server name - I used the 'insert' method)

@pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
    cells.insert(1, html.th('Server Name', class_='sortable server-name', col='server-name'))


@pytest.mark.optionalhook
def pytest_html_results_table_row(report, cells):
    cells.insert(1, html.td(report.server_name, class_='col-server-name'))
As you said, now I only need to figure out how to populate this column
... Maybe pytest-metadata, but not sure

Thanks again... will update


RE: Pytest-html hook help - flashnet1 - Jan-19-2018

OK, so as mentioned by buran you should place the conftest.py in the folder of the tests.
The function on the that file "pytest_runtest_makereport" is called after each test method so if one wants to put test specific data on the report, he should should set the value to one of the method's global collections (__dict__ or __doc__) from with each method and retrieve it on the "pytest_runtest_makereport" function (as seen on its last line)

Thanks again for your help


RE: Pytest-html hook help - buran - Jan-19-2018

One should NOT change __doc__ for this purpose, it is the docstring of the function
__dict__ contains function attributes, i.e. the information you want to pass, should be supplied as argument
you can use mark decorator to mark your tests
something like

import pytest

@pytest.mark.servername(server='my_server_name')
def test_function():
    # do your test
then in conftest.py (only makereport hook)
@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
    outcome = yield
    report = outcome.get_result()
    report.server_name = item.keywords['servername'].kwargs['server']