matt3o
matt3o

Reputation: 653

Is there a custom way to collect pytest results?

I want to see the results of the tests that just run such that I can pipe the information e.g. into a custom file. This will be used later on to automatically parse the pytest results.

Upvotes: 1

Views: 1174

Answers (2)

Jared Jesionek
Jared Jesionek

Reputation: 31

I have found pytest-json-report to be super useful for generating pytest reports.

To install: pip install pytest-json-report

To use: pytest --json-report

View Output at file: .report.json

Post to Webhook: curl -X POST -H "Content-Type: application/json" -d @.report.json https://webhooks.fivetran.com/webhooks/asdf-s09byus-skihboih-slkjhd

I used fivetran to collect and load it into a data warehouse but you can post to any webhook you want

I wrote a medium article on how to build a pipline using pytest-json-report, snowflake & an engineering friendly BI tool called Visivo.io.

Article: https://medium.com/@jared_86317/visualizing-pytest-results-with-the-modern-data-stack-29daeab99b66

Getting a full blown dashboard & it's pipeline running is pretty easy. Once you get the initial dash configured you can also set up email alerts, additional reporting ect.

Note- I helped write Visivo ;)

Upvotes: 2

matt3o
matt3o

Reputation: 653

Yes there is a way by creating / using the conftest.py. In the example a dict with the results will be created and after all tests have run the results will printed.

from collections import OrderedDict
test_results = OrderedDict()

def get_current_test():
    """Just a helper function to extract the current test"""
    full_name = os.environ.get('PYTEST_CURRENT_TEST').split(' ')[0]
    test_file = full_name.split("::")[0].split('/')[-1].split('.py')[0]
    test_name = full_name.split("::")[1]
    return full_name, test_file, test_name


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """The actual wrapper that gets called before and after every test"""
    global test_results
    outcome = yield
    rep = outcome.get_result()

    # only check the result of the test
    if rep.when == "call":
        full_name, test_file, test_name = get_current_test()
        test_name_msg = f"{test_name}_msg"
        if rep.failed:
            test_results[test_name] = "Failure"
            # return the last error msg either by pytest.fail or from any exception raised
            test_results[test_name_msg] = f"{call.excinfo.typename} - {call.excinfo.value}"
        else:
            test_results[test_name] = "Success"
            test_results[test_name_msg] = ''

def pytest_unconfigure(config):
    """Called when pytest is about to end. Can be used to print the result dict or 
    to pipe the data into a file"""
    print(test_results)

Upvotes: 1

Related Questions