105 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
| """ log machine-parseable test session result information in a plain
 | |
| text file.
 | |
| """
 | |
| 
 | |
| import py
 | |
| import os
 | |
| 
 | |
| def pytest_addoption(parser):
 | |
|     group = parser.getgroup("terminal reporting", "resultlog plugin options")
 | |
|     group.addoption('--resultlog', '--result-log', action="store",
 | |
|         metavar="path", default=None,
 | |
|         help="path for machine-readable result log.")
 | |
| 
 | |
| def pytest_configure(config):
 | |
|     resultlog = config.option.resultlog
 | |
|     # prevent opening resultlog on slave nodes (xdist)
 | |
|     if resultlog and not hasattr(config, 'slaveinput'):
 | |
|         dirname = os.path.dirname(os.path.abspath(resultlog))
 | |
|         if not os.path.isdir(dirname):
 | |
|             os.makedirs(dirname)
 | |
|         logfile = open(resultlog, 'w', 1) # line buffered
 | |
|         config._resultlog = ResultLog(config, logfile)
 | |
|         config.pluginmanager.register(config._resultlog)
 | |
| 
 | |
| def pytest_unconfigure(config):
 | |
|     resultlog = getattr(config, '_resultlog', None)
 | |
|     if resultlog:
 | |
|         resultlog.logfile.close()
 | |
|         del config._resultlog
 | |
|         config.pluginmanager.unregister(resultlog)
 | |
| 
 | |
| def generic_path(item):
 | |
|     chain = item.listchain()
 | |
|     gpath = [chain[0].name]
 | |
|     fspath = chain[0].fspath
 | |
|     fspart = False
 | |
|     for node in chain[1:]:
 | |
|         newfspath = node.fspath
 | |
|         if newfspath == fspath:
 | |
|             if fspart:
 | |
|                 gpath.append(':')
 | |
|                 fspart = False
 | |
|             else:
 | |
|                 gpath.append('.')
 | |
|         else:
 | |
|             gpath.append('/')
 | |
|             fspart = True
 | |
|         name = node.name
 | |
|         if name[0] in '([':
 | |
|             gpath.pop()
 | |
|         gpath.append(name)
 | |
|         fspath = newfspath
 | |
|     return ''.join(gpath)
 | |
| 
 | |
| class ResultLog(object):
 | |
|     def __init__(self, config, logfile):
 | |
|         self.config = config
 | |
|         self.logfile = logfile # preferably line buffered
 | |
| 
 | |
|     def write_log_entry(self, testpath, lettercode, longrepr):
 | |
|         py.builtin.print_("%s %s" % (lettercode, testpath), file=self.logfile)
 | |
|         for line in longrepr.splitlines():
 | |
|             py.builtin.print_(" %s" % line, file=self.logfile)
 | |
| 
 | |
|     def log_outcome(self, report, lettercode, longrepr):
 | |
|         testpath = getattr(report, 'nodeid', None)
 | |
|         if testpath is None:
 | |
|             testpath = report.fspath
 | |
|         self.write_log_entry(testpath, lettercode, longrepr)
 | |
| 
 | |
|     def pytest_runtest_logreport(self, report):
 | |
|         if report.when != "call" and report.passed:
 | |
|             return
 | |
|         res = self.config.hook.pytest_report_teststatus(report=report)
 | |
|         code = res[1]
 | |
|         if code == 'x':
 | |
|             longrepr = str(report.longrepr)
 | |
|         elif code == 'X':
 | |
|             longrepr = ''
 | |
|         elif report.passed:
 | |
|             longrepr = ""
 | |
|         elif report.failed:
 | |
|             longrepr = str(report.longrepr)
 | |
|         elif report.skipped:
 | |
|             longrepr = str(report.longrepr[2])
 | |
|         self.log_outcome(report, code, longrepr)
 | |
| 
 | |
|     def pytest_collectreport(self, report):
 | |
|         if not report.passed:
 | |
|             if report.failed:
 | |
|                 code = "F"
 | |
|                 longrepr = str(report.longrepr)
 | |
|             else:
 | |
|                 assert report.skipped
 | |
|                 code = "S"
 | |
|                 longrepr = "%s:%d: %s" % report.longrepr
 | |
|             self.log_outcome(report, code, longrepr)
 | |
| 
 | |
|     def pytest_internalerror(self, excrepr):
 | |
|         reprcrash = getattr(excrepr, 'reprcrash', None)
 | |
|         path = getattr(reprcrash, "path", None)
 | |
|         if path is None:
 | |
|             path = "cwd:%s" % py.path.local()
 | |
|         self.write_log_entry(path, '!', str(excrepr))
 |