Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" log machine-parseable test session result information in a plain 

2text file. 

3""" 

4import os 

5 

6import py 

7 

8 

9def pytest_addoption(parser): 

10 group = parser.getgroup("terminal reporting", "resultlog plugin options") 

11 group.addoption( 

12 "--resultlog", 

13 "--result-log", 

14 action="store", 

15 metavar="path", 

16 default=None, 

17 help="DEPRECATED path for machine-readable result log.", 

18 ) 

19 

20 

21def pytest_configure(config): 

22 resultlog = config.option.resultlog 

23 # prevent opening resultlog on slave nodes (xdist) 

24 if resultlog and not hasattr(config, "slaveinput"): 

25 dirname = os.path.dirname(os.path.abspath(resultlog)) 

26 if not os.path.isdir(dirname): 

27 os.makedirs(dirname) 

28 logfile = open(resultlog, "w", 1) # line buffered 

29 config._resultlog = ResultLog(config, logfile) 

30 config.pluginmanager.register(config._resultlog) 

31 

32 from _pytest.deprecated import RESULT_LOG 

33 from _pytest.warnings import _issue_warning_captured 

34 

35 _issue_warning_captured(RESULT_LOG, config.hook, stacklevel=2) 

36 

37 

38def pytest_unconfigure(config): 

39 resultlog = getattr(config, "_resultlog", None) 

40 if resultlog: 

41 resultlog.logfile.close() 

42 del config._resultlog 

43 config.pluginmanager.unregister(resultlog) 

44 

45 

46class ResultLog: 

47 def __init__(self, config, logfile): 

48 self.config = config 

49 self.logfile = logfile # preferably line buffered 

50 

51 def write_log_entry(self, testpath, lettercode, longrepr): 

52 print("{} {}".format(lettercode, testpath), file=self.logfile) 

53 for line in longrepr.splitlines(): 

54 print(" %s" % line, file=self.logfile) 

55 

56 def log_outcome(self, report, lettercode, longrepr): 

57 testpath = getattr(report, "nodeid", None) 

58 if testpath is None: 

59 testpath = report.fspath 

60 self.write_log_entry(testpath, lettercode, longrepr) 

61 

62 def pytest_runtest_logreport(self, report): 

63 if report.when != "call" and report.passed: 

64 return 

65 res = self.config.hook.pytest_report_teststatus( 

66 report=report, config=self.config 

67 ) 

68 code = res[1] 

69 if code == "x": 

70 longrepr = str(report.longrepr) 

71 elif code == "X": 

72 longrepr = "" 

73 elif report.passed: 

74 longrepr = "" 

75 elif report.failed: 

76 longrepr = str(report.longrepr) 

77 elif report.skipped: 

78 longrepr = str(report.longrepr[2]) 

79 self.log_outcome(report, code, longrepr) 

80 

81 def pytest_collectreport(self, report): 

82 if not report.passed: 

83 if report.failed: 

84 code = "F" 

85 longrepr = str(report.longrepr) 

86 else: 

87 assert report.skipped 

88 code = "S" 

89 longrepr = "%s:%d: %s" % report.longrepr 

90 self.log_outcome(report, code, longrepr) 

91 

92 def pytest_internalerror(self, excrepr): 

93 reprcrash = getattr(excrepr, "reprcrash", None) 

94 path = getattr(reprcrash, "path", None) 

95 if path is None: 

96 path = "cwd:%s" % py.path.local() 

97 self.write_log_entry(path, "!", str(excrepr))