129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
""" basic test session implementation. 
 | 
						|
 | 
						|
* drives collection of tests 
 | 
						|
* triggers executions of tests   
 | 
						|
* produces events used by reporting 
 | 
						|
"""
 | 
						|
 | 
						|
import py
 | 
						|
 | 
						|
# exitcodes for the command line
 | 
						|
EXIT_OK = 0
 | 
						|
EXIT_TESTSFAILED = 1
 | 
						|
EXIT_INTERRUPTED = 2
 | 
						|
EXIT_INTERNALERROR = 3
 | 
						|
EXIT_NOHOSTS = 4
 | 
						|
 | 
						|
# imports used for genitems()
 | 
						|
Item = py.test.collect.Item
 | 
						|
Collector = py.test.collect.Collector
 | 
						|
 | 
						|
class Session(object): 
 | 
						|
    nodeid = ""
 | 
						|
    def __init__(self, config):
 | 
						|
        self.config = config
 | 
						|
        self.pluginmanager = config.pluginmanager # shortcut 
 | 
						|
        self.pluginmanager.register(self)
 | 
						|
        self._testsfailed = False
 | 
						|
        self._nomatch = False
 | 
						|
        self.shouldstop = False
 | 
						|
 | 
						|
    def genitems(self, colitems, keywordexpr=None):
 | 
						|
        """ yield Items from iterating over the given colitems. """
 | 
						|
        if colitems:
 | 
						|
            colitems = list(colitems)
 | 
						|
        while colitems: 
 | 
						|
            next = colitems.pop(0)
 | 
						|
            if isinstance(next, (tuple, list)):
 | 
						|
                colitems[:] = list(next) + colitems 
 | 
						|
                continue
 | 
						|
            assert self.pluginmanager is next.config.pluginmanager
 | 
						|
            if isinstance(next, Item):
 | 
						|
                remaining = self.filteritems([next])
 | 
						|
                if remaining:
 | 
						|
                    self.config.hook.pytest_itemstart(item=next)
 | 
						|
                    yield next 
 | 
						|
            else:
 | 
						|
                assert isinstance(next, Collector)
 | 
						|
                self.config.hook.pytest_collectstart(collector=next)
 | 
						|
                rep = self.config.hook.pytest_make_collect_report(collector=next)
 | 
						|
                if rep.passed:
 | 
						|
                    for x in self.genitems(rep.result, keywordexpr):
 | 
						|
                        yield x 
 | 
						|
                self.config.hook.pytest_collectreport(report=rep)
 | 
						|
            if self.shouldstop:
 | 
						|
                break
 | 
						|
 | 
						|
    def filteritems(self, colitems):
 | 
						|
        """ return items to process (some may be deselected)"""
 | 
						|
        keywordexpr = self.config.option.keyword 
 | 
						|
        if not keywordexpr or self._nomatch:
 | 
						|
            return colitems
 | 
						|
        if keywordexpr[-1] == ":": 
 | 
						|
            keywordexpr = keywordexpr[:-1]
 | 
						|
        remaining = []
 | 
						|
        deselected = []
 | 
						|
        for colitem in colitems:
 | 
						|
            if isinstance(colitem, Item):
 | 
						|
                if colitem._skipbykeyword(keywordexpr):
 | 
						|
                    deselected.append(colitem)
 | 
						|
                    continue
 | 
						|
            remaining.append(colitem)
 | 
						|
        if deselected: 
 | 
						|
            self.config.hook.pytest_deselected(items=deselected)
 | 
						|
            if self.config.option.keyword.endswith(":"):
 | 
						|
                self._nomatch = True
 | 
						|
        return remaining 
 | 
						|
 | 
						|
    def collect(self, colitems): 
 | 
						|
        keyword = self.config.option.keyword
 | 
						|
        for x in self.genitems(colitems, keyword):
 | 
						|
            yield x
 | 
						|
 | 
						|
    def sessionstarts(self):
 | 
						|
        """ setup any neccessary resources ahead of the test run. """
 | 
						|
        self.config.hook.pytest_sessionstart(session=self)
 | 
						|
        
 | 
						|
    def pytest_runtest_logreport(self, report):
 | 
						|
        if report.failed:
 | 
						|
            self._testsfailed = True
 | 
						|
            if self.config.option.exitfirst:
 | 
						|
                self.shouldstop = True
 | 
						|
    pytest_collectreport = pytest_runtest_logreport
 | 
						|
 | 
						|
    def sessionfinishes(self, exitstatus):
 | 
						|
        """ teardown any resources after a test run. """ 
 | 
						|
        self.config.hook.pytest_sessionfinish(
 | 
						|
            session=self, 
 | 
						|
            exitstatus=exitstatus, 
 | 
						|
        )
 | 
						|
 | 
						|
    def main(self, colitems):
 | 
						|
        """ main loop for running tests. """
 | 
						|
        self.shouldstop = False 
 | 
						|
        self.sessionstarts()
 | 
						|
        exitstatus = EXIT_OK
 | 
						|
        try:
 | 
						|
            self._mainloop(colitems)
 | 
						|
            if self._testsfailed:
 | 
						|
                exitstatus = EXIT_TESTSFAILED
 | 
						|
            self.sessionfinishes(exitstatus=exitstatus)
 | 
						|
        except KeyboardInterrupt:
 | 
						|
            excinfo = py.code.ExceptionInfo()
 | 
						|
            self.config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
 | 
						|
            exitstatus = EXIT_INTERRUPTED
 | 
						|
        except:
 | 
						|
            excinfo = py.code.ExceptionInfo()
 | 
						|
            self.config.pluginmanager.notify_exception(excinfo)
 | 
						|
            exitstatus = EXIT_INTERNALERROR
 | 
						|
        if exitstatus in (EXIT_INTERNALERROR, EXIT_INTERRUPTED):
 | 
						|
            self.sessionfinishes(exitstatus=exitstatus)
 | 
						|
        return exitstatus
 | 
						|
 | 
						|
    def _mainloop(self, colitems):
 | 
						|
        for item in self.collect(colitems): 
 | 
						|
            if self.shouldstop: 
 | 
						|
                break 
 | 
						|
            if not self.config.option.collectonly: 
 | 
						|
                item.config.hook.pytest_runtest_protocol(item=item)
 |