2014-06-20 5 views
8

Pytest ermöglicht es Ihnen, für jeden Test in die Teardown Phase hook durch eine Funktion namens pytest_runtest_teardown in einem Plugin Implementierung:Wie kann ich feststellen, ob ein Test bestanden oder fehlgeschlagen ist, indem ich das Item-Objekt untersucht habe, das an pytest_runtest_teardown übergeben wurde?

def pytest_runtest_teardown(item, nextitem): 
    pass 

Gibt es ein Attribut oder eine Methode auf item, die ich, ob der Test, dass verwenden können, um festzustellen, nur Fertig läuft bestanden oder nicht bestanden? Ich konnte keine Dokumentation für pytest.Item finden und die Jagd durch den Quellcode und herumspielen in ipdb ergab nichts offensichtliches.

Antwort

4

können Sie auch call.excinfo in pytest_runtest_makereport betrachten:

def pytest_runtest_makereport(item, call): 
    if call.when == 'setup': 
     print('Called after setup for test case is executed.') 
    if call.when == 'call': 
     print('Called after test case is executed.') 
     print('-->{}<--'.format(call.excinfo)) 
    if call.when == 'teardown': 
     print('Called after teardown for test case is executed.') 

Das Anruf-Objekt enthält eine ganze Reihe von zusätzlichen Informationen (Teststartzeit, Stoppzeit, etc.) .

Siehe: http://doc.pytest.org/en/latest/_modules/_pytest/runner.html

def pytest_runtest_makereport(item, call): 
    when = call.when 
    duration = call.stop-call.start 
    keywords = dict([(x,1) for x in item.keywords]) 
    excinfo = call.excinfo 
    sections = [] 
    if not call.excinfo: 
     outcome = "passed" 
     longrepr = None 
    else: 
     if not isinstance(excinfo, ExceptionInfo): 
      outcome = "failed" 
      longrepr = excinfo 
     elif excinfo.errisinstance(pytest.skip.Exception): 
      outcome = "skipped" 
      r = excinfo._getreprcrash() 
      longrepr = (str(r.path), r.lineno, r.message) 
     else: 
      outcome = "failed" 
      if call.when == "call": 
       longrepr = item.repr_failure(excinfo) 
      else: # exception in setup or teardown 
       longrepr = item._repr_failure_py(excinfo, 
              style=item.config.option.tbstyle) 
    for rwhen, key, content in item._report_sections: 
     sections.append(("Captured %s %s" %(key, rwhen), content)) 
    return TestReport(item.nodeid, item.location, 
         keywords, outcome, longrepr, when, 
         sections, duration) 
1

Die Node class haben keine Informationen über den Status des letzten Tests, jedoch haben wir den Status der Gesamtzahl der fehlgeschlagenen Tests haben (in item.session.testsfailed), und wir können es verwenden:

  1. Wir können dem Objekt item.session ein neues Mitglied hinzufügen (nicht so nett, aber du musst Python lieben!). Dieses Mitglied speichert den Status der letzten testsfailed - item.session.last_testsfailed_status.
  2. Wenn testsfailed>last_testsfailed_status - der letzte Test der Lauf gerade fehlgeschlagen.

import pytest 
import logging 

logging.basicConfig(
    level='INFO', 
    handlers=(
     logging.StreamHandler(), 
     logging.FileHandler('log.txt') 
    ) 
) 

@pytest.mark.hookwrapper 
def pytest_runtest_teardown(item, nextitem): 
    outcome = yield 

    if not hasattr(item.session, 'last_testsfailed_status'): 
     item.session.last_testsfailed_status = 0 

    if item.session.testsfailed and item.session.testsfailed > item.session.last_testsfailed_status: 
     logging.info('Last test failed') 

    item.session.last_testsfailed_status = item.session.testsfailed 
Verwandte Themen