0
votes

It seems that the teardown portion/trigger of hook function pytest_report_teststatus gets executed after any session scoped fixtures that have yield statements. How can I change that? For example, here is my hook function:

def pytest_report_teststatus(report,): 
    """
    Using the pytest hook pytest_report_teststatus.  This will give us
    the test result of each test function.
    Note, this hook can get called up to 3 times for one test funtion.
    Test Setup, Call, and Teardown.  Call is the actual test function.

    This hook function will write out test results for each
    test to the summary.log file.

    """
    sum_log = dnet_generic.get_logger()
    if report.when == 'setup' and report.outcome == 'failed':
        sum_log.info("\n    --------------------------------------")
        sum_log.info("    ---- Test Setup Stage FAILED!")
        sum_log.info(f'    ---- Test: {report.nodeid}' )
        sum_log.info("    --------------------------------------\n")
    elif report.when == 'call':
        now = datetime.datetime.now()
        end_time = now.strftime('%a %b %d %H:%M:%S %Z %Y')
        sum_log.info("\n    --------------------------------------")
        sum_log.info('    ---- Test Function completed at: %s' % (end_time) )
        sum_log.info(f'    ---- Test: {report.nodeid}' )
        sum_log.info(f'    ---- Result: {report.outcome.upper()}' )
        sum_log.info("    --------------------------------------\n")
    elif report.when == 'teardown' and report.outcome == 'failed':
        sum_log.info("\n    --------------------------------------")
        sum_log.info("    ---- Test Teardown Stage FAILED!")
        sum_log.info(f'    ---- Test: {report.nodeid}' )
        sum_log.info("    --------------------------------------\n")

and here is the session scoped fixture with the yield statement:

@pytest.fixture(scope="session")
def logger(testinfo):

    sum_log = dnet_generic.get_logger(initialize=True)

    ############################################################
    # Don't like to do this but I'm going to add a new key
    # to testinfo which defines the summary.log logger
    # Since dictionaries are mutable this should work fine....
    ############################################################
    testinfo.update({"sum_log" : sum_log })

    start_time = testinfo['start_time'].strftime('%a %b %d %H:%M:%S %Z %Y')
    script_name = sys.argv[0]
    script_args = sys.argv[1:] # all remaining arguments other than script name
    script_basename = os.path.basename(script_name)

    sum_log.info("\n\n----------------------------------------------------------")
    sum_log.info("----------------------------------------------------------")
    sum_log.info('-----Pytest Session Started' )
    sum_log.info('-----Start Time:: %s' % (start_time) )
    sum_log.info('-----Results for script_name %s' % (script_basename))
    sum_log.info('-----Script Arguments %s' % ' '.join(map(str,script_args)))
    sum_log.info("----------------------------------------------------------")
    sum_log.info("----------------------------------------------------------")

    yield sum_log

    now = datetime.datetime.now()
    end_time = now.strftime('%a %b %d %H:%M:%S %Z %Y')
    script_basename = os.path.basename(script_name)

    sum_log.info("+++++++++++++++++++++++++++++++++++++++++++++")
    sum_log.info("+++++++++++++++++++++++++++++++++++++++++++++")
    sum_log.info('-----Pytest Session Ended' )
    sum_log.info('-----End Time: %s' % (end_time) )
    sum_log.info("+++++++++++++++++++++++++++++++++++++++++++++")
    sum_log.info("+++++++++++++++++++++++++++++++++++++++++++++")

I'm only having the problem with the teardown. If I have 5 separate test functions in a module, this hook gets called 5 times and writes out the appropriate message to the log file and then the Session scoped fixture writes to log file last.

Here is what the output of the log file looked like when another "function scoped" fixture failed after a yield statement (I need the Teardown Message to come before the "Pytest Session Ended" message :

+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++
-----Pytest Session Ended
-----End Time: Wed Apr 08 02:48:31  2020
+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++

    --------------------------------------
    ---- Test Teardown Stage FAILED!
    ---- Test: lag/test_preconfig_setup.py::test_lag_load_balance[au22-bundle-28130-4-80-128-True-60-lag_setup_test.yml]
    --------------------------------------

Thank you asilver

1

1 Answers

0
votes

Transfer session logs from fixture "logger" into test session related hooks.
Example - "pytest_sessionstart" and "pytest_sessionfinish"
(https://docs.pytest.org/en/stable/_modules/_pytest/hookspec.html#pytest_sessionfinish)
My simple check -

@pytest.hookspec(firstresult=True)
def pytest_sessionstart(session):

    print("\n+++++++++++++++++++++++++++++++++++++++++++++")
    print('\n-----Pytest Session Started')
    print("\n+++++++++++++++++++++++++++++++++++++++++++++")


@pytest.hookspec(firstresult=True)
def pytest_sessionfinish(session, exitstatus):

    print("\n+++++++++++++++++++++++++++++++++++++++++++++")
    print('\n-----Pytest Session Ended')
    print("\n+++++++++++++++++++++++++++++++++++++++++++++")
  • work with your "pytest_report_teststatus", when fixture failed after yield