def __init__(self, stream=sys.stdout, *args, **kwargs): TestResult.__init__(self) for arg, value in kwargs.items(): setattr(self, arg, value) self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) self.messages.testMatrixEntered() self.current_suite = None
def __init__(self, stream=sys.stdout, *args, **kwargs): TestResult.__init__(self) for arg, value in kwargs.items(): setattr(self, arg, value) self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) if not "_jb_do_not_call_enter_matrix" in os.environ: self.messages.testMatrixEntered() self.current_failed = False self.current_suite = None self.subtest_suite = None
def run_tests(test_labels, verbosity=1, interactive=False, extra_tests=[], **kwargs): """ Run the unit tests for all the test labels in the provided list. Labels must be of the form: - app.TestClass.test_method Run a single specific test method - app.TestClass Run all the test methods in a given class - app Search for doctests and unittests in the named application. When looking for tests, the test runner will look in the models and tests modules for the application. A list of 'extra' tests may also be provided; these tests will be added to the test suite. Returns the number of tests that failed. """ options = { 'verbosity': verbosity, 'interactive': interactive } options.update(kwargs) TeamcityServiceMessages(sys.stdout).testMatrixEntered() if VERSION[1] > 1: return DjangoTeamcityTestRunner(**options).run_tests(test_labels, extra_tests=extra_tests, **options) return run_the_old_way(extra_tests, options, test_labels, verbosity)
def __init__(self, stream=sys.stderr, descriptions=None, verbosity=1, config=None, errorClasses=None): super(TeamcityPlugin, self).__init__() if errorClasses is None: errorClasses = {} self.errorClasses = errorClasses if config is None: config = Config() self.config = config self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) self.messages.testMatrixEntered() self.current_suite = None TextTestResult.__init__(self, stream, descriptions, verbosity, config, errorClasses) TeamcityTestResult.__init__(self, stream)
"pytest_teamcity", dir_to_run ] + command[1:] class _Nose(object): def fix(self, command, dir_to_run, bin): if command[0] != "nosetests": return None return [bin, os.path.join(helpers_dir, "noserunner.py"), dir_to_run ] + command[1:] _RUNNERS = [_Unit2(), _PyTest(), _Nose()] teamcity = TeamcityServiceMessages() class _Reporter(Reporter): def logaction_start(self, action): super(_Reporter, self).logaction_start(action) if action.activity == "getenv": teamcity.output.write("\n") teamcity.testSuiteStarted(action.id, location="tox_env://" + str(action.id)) self.current_suite = action.id def logaction_finish(self, action): super(_Reporter, self).logaction_finish(action) if action.activity == "runtests": teamcity.testSuiteFinished(action.id)
class TeamcityTestResult(TestResult): """ Set ``_jb_do_not_call_enter_matrix`` to prevent it from runnig "enter matrix" """ def __init__(self, stream=sys.stdout, *args, **kwargs): TestResult.__init__(self) for arg, value in kwargs.items(): setattr(self, arg, value) self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) if not "_jb_do_not_call_enter_matrix" in os.environ: self.messages.testMatrixEntered() self.current_failed = False self.current_suite = None self.subtest_suite = None def find_first(self, val): quot = val[0] count = 1 quote_ind = val[count:].find(quot) while quote_ind != -1 and val[count + quote_ind - 1] == "\\": count = count + quote_ind + 1 quote_ind = val[count:].find(quot) return val[0 : quote_ind + count + 1] def find_second(self, val): val_index = val.find("!=") if val_index != -1: count = 1 val = val[val_index + 2 :].strip() quot = val[0] quote_ind = val[count:].find(quot) while quote_ind != -1 and val[count + quote_ind - 1] == "\\": count = count + quote_ind + 1 quote_ind = val[count:].find(quot) return val[0 : quote_ind + count + 1] else: quot = val[-1] quote_ind = val[: len(val) - 1].rfind(quot) while quote_ind != -1 and val[quote_ind - 1] == "\\": quote_ind = val[: quote_ind - 1].rfind(quot) return val[quote_ind:] def formatErr(self, err): exctype, value, tb = err return "".join(traceback.format_exception(exctype, value, tb)) def getTestName(self, test, is_subtest=False): if is_subtest: test_name = self.getTestName(test.test_case) return "{} {}".format(test_name, test._subDescription()) if hasattr(test, "_testMethodName"): if test._testMethodName == "runTest": return str(test) return test._testMethodName else: test_name = str(test) whitespace_index = test_name.index(" ") if whitespace_index != -1: test_name = test_name[:whitespace_index] return test_name def getTestId(self, test): return test.id def addSuccess(self, test): TestResult.addSuccess(self, test) def addError(self, test, err): location = self.init_suite(test) self.current_failed = True TestResult.addError(self, test, err) err = self._exc_info_to_string(err, test) self.messages.testStarted(self.getTestName(test), location=location) self.messages.testError(self.getTestName(test), message="Error", details=err, duration=self.__getDuration(test)) def find_error_value(self, err): error_value = traceback.extract_tb(err) error_value = error_value[-1][-1] return error_value.split("assert")[-1].strip() def addFailure(self, test, err): location = self.init_suite(test) self.current_failed = True TestResult.addFailure(self, test, err) error_value = smart_str(err[1]) if not len(error_value): # means it's test function and we have to extract value from traceback error_value = self.find_error_value(err[2]) self_find_first = self.find_first(error_value) self_find_second = self.find_second(error_value) quotes = ["'", '"'] if ( self_find_first[0] == self_find_first[-1] and self_find_first[0] in quotes and self_find_second[0] == self_find_second[-1] and self_find_second[0] in quotes ): # let's unescape strings to show sexy multiline diff in PyCharm. # By default all caret return chars are escaped by testing framework first = self._unescape(self_find_first) second = self._unescape(self_find_second) else: first = second = "" err = self._exc_info_to_string(err, test) self.messages.testStarted(self.getTestName(test), location=location) duration = self.__getDuration(test) self.messages.testFailed( self.getTestName(test), message="Failure", details=err, expected=first, actual=second, duration=duration ) def addSkip(self, test, reason): self.init_suite(test) self.current_failed = True self.messages.testIgnored(self.getTestName(test), message=reason) def _getSuite(self, test): try: suite = strclass(test.suite) suite_location = test.suite.location location = test.suite.abs_location if hasattr(test, "lineno"): location = location + ":" + str(test.lineno) else: location = location + ":" + str(test.test.lineno) except AttributeError: import inspect try: source_file = inspect.getsourcefile(test.__class__) if source_file: source_dir_splitted = source_file.split("/")[:-1] source_dir = "/".join(source_dir_splitted) + "/" else: source_dir = "" except TypeError: source_dir = "" suite = strclass(test.__class__) suite_location = "python_uttestid://" + source_dir + suite location = "python_uttestid://" + source_dir + str(test.id()) return (suite, location, suite_location) def startTest(self, test): self.current_failed = False setattr(test, "startTime", datetime.datetime.now()) def init_suite(self, test): suite, location, suite_location = self._getSuite(test) if suite != self.current_suite: if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = suite self.messages.testSuiteStarted(self.current_suite, location=suite_location) return location def stopTest(self, test): duration = self.__getDuration(test) if not self.subtest_suite: if not self.current_failed: location = self.init_suite(test) self.messages.testStarted(self.getTestName(test), location=location) self.messages.testFinished(self.getTestName(test), duration=int(duration)) else: self.messages.testSuiteFinished(self.subtest_suite) self.subtest_suite = None def __getDuration(self, test): start = getattr(test, "startTime", datetime.datetime.now()) assert isinstance( start, datetime.datetime ), "You testcase has property named 'startTime' (value {0}). Please, rename it".format(start) d = datetime.datetime.now() - start duration = d.microseconds / 1000 + d.seconds * 1000 + d.days * 86400000 return duration def addSubTest(self, test, subtest, err): location = self.init_suite(test) suite_name = self.getTestName(test) # + " (subTests)" if not self.subtest_suite: self.subtest_suite = suite_name self.messages.testSuiteStarted(self.subtest_suite, location=location) else: if suite_name != self.subtest_suite: self.messages.testSuiteFinished(self.subtest_suite) self.subtest_suite = suite_name self.messages.testSuiteStarted(self.subtest_suite, location=location) name = self.getTestName(subtest, True) if err is not None: error = self._exc_info_to_string(err, test) self.messages.testStarted(name) self.messages.testFailed(name, message="Failure", details=error, duration=None) else: self.messages.testStarted(name) self.messages.testFinished(name) def endLastSuite(self): if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = None def _unescape(self, text): # do not use text.decode('string_escape'), it leads to problems with different string encodings given return text.replace("\\n", "\n")
class TeamcityTestResult(TestResult): def __init__(self, stream=sys.stdout, *args, **kwargs): TestResult.__init__(self) for arg, value in kwargs.items(): setattr(self, arg, value) self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) self.messages.testMatrixEntered() self.current_failed = False self.current_suite = None self.subtest_suite = None def find_first(self, val): quot = val[0] count = 1 quote_ind = val[count:].find(quot) while quote_ind != -1 and val[count + quote_ind - 1] == "\\": count = count + quote_ind + 1 quote_ind = val[count:].find(quot) return val[0:quote_ind + count + 1] def find_second(self, val): val_index = val.find("!=") if val_index != -1: count = 1 val = val[val_index + 2:].strip() quot = val[0] quote_ind = val[count:].find(quot) while quote_ind != -1 and val[count + quote_ind - 1] == "\\": count = count + quote_ind + 1 quote_ind = val[count:].find(quot) return val[0:quote_ind + count + 1] else: quot = val[-1] quote_ind = val[:len(val) - 1].rfind(quot) while quote_ind != -1 and val[quote_ind - 1] == "\\": quote_ind = val[:quote_ind - 1].rfind(quot) return val[quote_ind:] def formatErr(self, err): exctype, value, tb = err return ''.join(traceback.format_exception(exctype, value, tb)) def getTestName(self, test, is_subtest=False): if is_subtest: test_name = self.getTestName(test.test_case) return "{} {}".format(test_name, test._subDescription()) if hasattr(test, '_testMethodName'): if test._testMethodName == "runTest": return str(test) return test._testMethodName else: test_name = str(test) whitespace_index = test_name.index(" ") if whitespace_index != -1: test_name = test_name[:whitespace_index] return test_name def getTestId(self, test): return test.id def addSuccess(self, test): TestResult.addSuccess(self, test) def addError(self, test, err): self.init_suite(test) self.current_failed = True TestResult.addError(self, test, err) err = self._exc_info_to_string(err, test) self.messages.testStarted(self.getTestName(test)) self.messages.testError(self.getTestName(test), message='Error', details=err) def find_error_value(self, err): error_value = traceback.extract_tb(err) error_value = error_value[-1][-1] return error_value.split('assert')[-1].strip() def addFailure(self, test, err): self.init_suite(test) self.current_failed = True TestResult.addFailure(self, test, err) error_value = smart_str(err[1]) if not len(error_value): # means it's test function and we have to extract value from traceback error_value = self.find_error_value(err[2]) self_find_first = self.find_first(error_value) self_find_second = self.find_second(error_value) quotes = ["'", '"'] if (self_find_first[0] == self_find_first[-1] and self_find_first[0] in quotes and self_find_second[0] == self_find_second[-1] and self_find_second[0] in quotes): # let's unescape strings to show sexy multiline diff in PyCharm. # By default all caret return chars are escaped by testing framework first = self._unescape(self_find_first) second = self._unescape(self_find_second) else: first = second = "" err = self._exc_info_to_string(err, test) self.messages.testStarted(self.getTestName(test)) self.messages.testFailed(self.getTestName(test), message='Failure', details=err, expected=first, actual=second) def addSkip(self, test, reason): self.init_suite(test) self.current_failed = True self.messages.testIgnored(self.getTestName(test), message=reason) def __getSuite(self, test): if hasattr(test, "suite"): suite = strclass(test.suite) suite_location = test.suite.location location = test.suite.abs_location if hasattr(test, "lineno"): location = location + ":" + str(test.lineno) else: location = location + ":" + str(test.test.lineno) else: import inspect try: source_file = inspect.getsourcefile(test.__class__) if source_file: source_dir_splitted = source_file.split("/")[:-1] source_dir = "/".join(source_dir_splitted) + "/" else: source_dir = "" except TypeError: source_dir = "" suite = strclass(test.__class__) suite_location = "python_uttestid://" + source_dir + suite location = "python_uttestid://" + source_dir + str(test.id()) return (suite, location, suite_location) def startTest(self, test): self.current_failed = False setattr(test, "startTime", datetime.datetime.now()) def init_suite(self, test): suite, location, suite_location = self.__getSuite(test) if suite != self.current_suite: if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = suite self.messages.testSuiteStarted(self.current_suite, location=suite_location) return location def stopTest(self, test): start = getattr(test, "startTime", datetime.datetime.now()) d = datetime.datetime.now() - start duration = d.microseconds / 1000 + d.seconds * 1000 + d.days * 86400000 if not self.subtest_suite: if not self.current_failed: location = self.init_suite(test) self.messages.testStarted(self.getTestName(test), location=location) self.messages.testFinished(self.getTestName(test), duration=int(duration)) else: self.messages.testSuiteFinished(self.subtest_suite) self.subtest_suite = None def addSubTest(self, test, subtest, err): suite_name = self.getTestName(test) # + " (subTests)" if not self.subtest_suite: self.subtest_suite = suite_name self.messages.testSuiteStarted(self.subtest_suite) else: if suite_name != self.subtest_suite: self.messages.testSuiteFinished(self.subtest_suite) self.subtest_suite = suite_name self.messages.testSuiteStarted(self.subtest_suite) name = self.getTestName(subtest, True) if err is not None: error = self._exc_info_to_string(err, test) self.messages.testStarted(name) self.messages.testFailed(name, message='Failure', details=error) else: self.messages.testStarted(name) self.messages.testFinished(name) def endLastSuite(self): if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = None def _unescape(self, text): # do not use text.decode('string_escape'), it leads to problems with different string encodings given return text.replace("\\n", "\n")
class TeamcityTestResult(TestResult): def __init__(self, stream=sys.stdout, *args, **kwargs): TestResult.__init__(self) for arg, value in kwargs.items(): setattr(self, arg, value) self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) self.messages.testMatrixEntered() self.current_suite = None def find_first(self, val): quot = val[0] count = 1 quote_ind = val[count:].find(quot) while val[count+quote_ind-1] == "\\" and quote_ind != -1: count = count + quote_ind + 1 quote_ind = val[count:].find(quot) return val[0:quote_ind+count+1] def find_second(self, val): val_index = val.find("!=") if val_index != -1: count = 1 val = val[val_index+2:].strip() quot = val[0] quote_ind = val[count:].find(quot) while val[count+quote_ind-1] == "\\" and quote_ind != -1: count = count + quote_ind + 1 quote_ind = val[count:].find(quot) return val[0:quote_ind+count+1] else: quot = val[-1] count = 0 quote_ind = val[:len(val)-count-1].rfind(quot) while val[quote_ind-1] == "\\": quote_ind = val[:quote_ind-1].rfind(quot) return val[quote_ind:] def formatErr(self, err): exctype, value, tb = err return ''.join(traceback.format_exception(exctype, value, tb)) def getTestName(self, test): if hasattr(test, '_testMethodName'): if test._testMethodName == "runTest": return str(test) return test._testMethodName else: test_name = str(test) whitespace_index = test_name.index(" ") if whitespace_index != -1: test_name = test_name[:whitespace_index] return test_name def getTestId(self, test): return test.id def addSuccess(self, test): TestResult.addSuccess(self, test) def addError(self, test, err): TestResult.addError(self, test, err) err = self._exc_info_to_string(err, test) self.messages.testError(self.getTestName(test), message='Error', details=err) def find_error_value(self, err): error_value = traceback.extract_tb(err) error_value = error_value[-1][-1] return error_value.split('assert')[-1].strip() def addFailure(self, test, err): TestResult.addFailure(self, test, err) error_value = smart_str(err[1]) if not len(error_value): # means it's test function and we have to extract value from traceback error_value = self.find_error_value(err[2]) self_find_first = self.find_first(error_value) self_find_second = self.find_second(error_value) quotes = ["'", '"'] if (self_find_first[0] == self_find_first[-1] and self_find_first[0] in quotes and self_find_second[0] == self_find_second[-1] and self_find_second[0] in quotes): # let's unescape strings to show sexy multiline diff in PyCharm. # By default all caret return chars are escaped by testing framework first = self._unescape(self_find_first) second = self._unescape(self_find_second) else: first = second = "" err = self._exc_info_to_string(err, test) self.messages.testFailed(self.getTestName(test), message='Failure', details=err, expected=first, actual=second) def addSkip(self, test, reason): self.messages.testIgnored(self.getTestName(test), message=reason) def __getSuite(self, test): if hasattr(test, "suite"): suite = strclass(test.suite) suite_location = test.suite.location location = test.suite.abs_location if hasattr(test, "lineno"): location = location + ":" + str(test.lineno) else: location = location + ":" + str(test.test.lineno) else: import inspect try: source_dir_splitted = inspect.getsourcefile(test.__class__).split("/")[:-1] source_dir = "/".join(source_dir_splitted) + "/" except TypeError: source_dir = "" suite = strclass(test.__class__) suite_location = "python_uttestid://" + source_dir + suite location = "python_uttestid://" + source_dir + str(test.id()) return (suite, location, suite_location) def startTest(self, test): suite, location, suite_location = self.__getSuite(test) if suite != self.current_suite: if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = suite self.messages.testSuiteStarted(self.current_suite, location=suite_location) setattr(test, "startTime", datetime.datetime.now()) self.messages.testStarted(self.getTestName(test), location=location) def stopTest(self, test): start = getattr(test, "startTime", datetime.datetime.now()) d = datetime.datetime.now() - start duration=d.microseconds / 1000 + d.seconds * 1000 + d.days * 86400000 self.messages.testFinished(self.getTestName(test), duration=int(duration)) def endLastSuite(self): if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = None def _unescape(self, text): # do not use text.decode('string_escape'), it leads to problems with different string encodings given return text.replace("\\n", "\n")
adjust_sys_path(False) # Directory where test script exist CURRENT_DIR_NAME = "" if sys.argv: last_arg = sys.argv[-1] if os.path.isfile(last_arg): CURRENT_DIR_NAME = os.path.dirname(last_arg) else: CURRENT_DIR_NAME = last_arg if not str(last_arg).endswith(os.sep): CURRENT_DIR_NAME = last_arg + os.sep messages = TeamcityServiceMessages(prepend_linebreak=True) if not "_jb_do_not_call_enter_matrix" in os.environ: messages.testMatrixEntered() try: import pytest PYVERSION = [int(x) for x in pytest.__version__.split(".")] except: import py PYVERSION = [int(x) for x in py.__version__.split(".")] def get_name(nodeid): return nodeid.split("::")[-1] def fspath_to_url(fspath): return "file:///" + str(fspath).replace("\\", "/")
if hasattr(module, a[2]): testcase = getattr(module, a[2]) tests = finder.find(testcase, getattr(testcase, "__name__", None)) runner.addTests(tests) else: raise NameError('Module "%s" has no method "%s"' % (a[0], a[2])) else: debug("/ from method " + a[2] + " in class " + a[1] + " in " + a[0]) if hasattr(module, a[1]): testCaseClass = getattr(module, a[1]) if hasattr(testCaseClass, a[2]): testcase = getattr(testCaseClass, a[2]) name = getattr(testcase, "__name__", None) if not name: name = testCaseClass.__name__ tests = finder.find(testcase, name) runner.addTests(tests) else: raise NameError('Class "%s" has no function "%s"' % (testCaseClass, a[2])) else: raise NameError('Module "%s" has no class "%s"' % (module, a[1])) debug("/ Loaded " + str(runner.countTests()) + " tests") TeamcityServiceMessages(sys.stdout).testCount(runner.countTests()) runner.start()
from tcmessages import TeamcityServiceMessages import os from pycharm_run_utils import adjust_sys_path adjust_sys_path(False) messages = TeamcityServiceMessages(prepend_linebreak=True) messages.testMatrixEntered() try: import pytest PYVERSION = [int(x) for x in pytest.__version__.split(".")] except: import py PYVERSION = [int(x) for x in py.__version__.split(".")] def get_name(nodeid): return nodeid.split("::")[-1] def fspath_to_url(fspath): return "file:///" + str(fspath).replace("\\", "/") if PYVERSION > [1, 4, 0]: items = {} current_suite = None current_file = None current_file_suite = None def pytest_runtest_logstart(nodeid, location): path = "file://" + os.path.realpath(location[0]) if location[1]:
class TeamcityPlugin(ErrorClassPlugin, TextTestResult, TeamcityTestResult): """ TeamcityTest plugin for nose tests """ name = "TeamcityPlugin" enabled = True def __init__(self, stream=sys.stderr, descriptions=None, verbosity=1, config=None, errorClasses=None): super(TeamcityPlugin, self).__init__() if errorClasses is None: errorClasses = {} self.errorClasses = errorClasses if config is None: config = Config() self.config = config self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) self.messages.testMatrixEntered() self.current_suite = None TextTestResult.__init__(self, stream, descriptions, verbosity, config, errorClasses) TeamcityTestResult.__init__(self, stream) def configure(self, options, conf): if not self.can_configure: return self.conf = conf def _is_failure(self, test): try: return isinstance(test.test, Failure) except AttributeError: return False def addError(self, test, err): exctype, value, tb = err err = self.formatErr(err) if self._is_failure(test): self.messages.testError(_ERROR_TEST_NAME, message='Error', details=err, duration=self.__getDuration(test)) return if exctype == SkipTest: self.messages.testIgnored(self.getTestName(test), message='Skip') else: self.messages.testError(self.getTestName(test), message='Error', details=err, duration=self.__getDuration(test)) def formatErr(self, err): exctype, value, tb = err if isinstance(value, str): try: value = exctype(value) except TypeError: pass return ''.join(traceback.format_exception(exctype, value, tb)) def is_gen(self, test): if hasattr(test, "test") and hasattr(test.test, "descriptor"): if test.test.descriptor is not None: return True return False def getTestName(self, test): if hasattr(test, "error_context"): return test.error_context test_name_full = str(test) if self.is_gen(test): return test_name_full ind_1 = test_name_full.rfind('(') if ind_1 != -1: return test_name_full[:ind_1] return test_name_full def addFailure(self, test, err): err = self.formatErr(err) self.messages.testFailed(self.getTestName(test), message='Failure', details=err) def addSkip(self, test, reason): self.messages.testIgnored(self.getTestName(test), message=reason) def _getSuite(self, test): if hasattr(test, "suite"): suite = strclass(test.suite) suite_location = test.suite.location location = test.suite.abs_location if hasattr(test, "lineno"): location = location + ":" + str(test.lineno) else: location = location + ":" + str(test.test.lineno) else: suite = strclass(test.__class__) suite_location = "python_nosetestid://" + suite try: from nose.util import func_lineno if hasattr(test.test, "descriptor") and test.test.descriptor: suite_location = "file://" + self.test_address( test.test.descriptor) location = suite_location + ":" + str( func_lineno(test.test.descriptor)) else: suite_location = "file://" + self.test_address( test.test.test) location = "file://" + self.test_address( test.test.test) + ":" + str(func_lineno( test.test.test)) except: test_id = test.id() suite_id = test_id[:test_id.rfind(".")] suite_location = "python_nosetestid://" + str(suite_id) location = "python_nosetestid://" + str(test_id) return (location, suite_location) def test_address(self, test): if hasattr(test, "address"): return test.address()[0] t = type(test) file = None import types, os if (t == types.FunctionType or issubclass(t, type) or t == type or isclass(test)): module = getattr(test, '__module__', None) if module is not None: m = sys.modules[module] file = getattr(m, '__file__', None) if file is not None: file = os.path.abspath(file) if file.endswith("pyc"): file = file[:-1] return file raise TypeError("I don't know what %s is (%s)" % (test, t)) def getSuiteName(self, test): test_name_full = str(test) ind_1 = test_name_full.rfind('(') if self.is_gen(test) and ind_1 != -1: ind = test_name_full[:ind_1].rfind('.') if ind != -1: return test_name_full[:ind] if ind_1 != -1: return test_name_full[ind_1 + 1:-1] ind = test_name_full.rfind('.') if ind != -1: return test_name_full[:test_name_full.rfind(".")] return test_name_full def startTest(self, test): location, suite_location = self._getSuite(test) if self._is_failure(test): self.messages.testStarted(_ERROR_TEST_NAME, location=suite_location) return suite = self.getSuiteName(test) if suite != self.current_suite: if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = suite self.messages.testSuiteStarted(self.current_suite, location=suite_location) setattr(test, "startTime", datetime.datetime.now()) self.messages.testStarted(self.getTestName(test), location=location) def stopTest(self, test): duration = self.__getDuration(test) if self._is_failure(test): return # Finish reported by testError self.messages.testFinished(self.getTestName(test), duration=int(duration)) def __getDuration(self, test): start = getattr(test, "startTime", datetime.datetime.now()) d = datetime.datetime.now() - start duration = d.microseconds / 1000 + d.seconds * 1000 + d.days * 86400000 return duration def finalize(self, result): if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = None
if command[0] != "py.test": return None return [bin, os.path.join(helpers_dir, "pytestrunner.py"), "-p", "pytest_teamcity", dir_to_run] + command[1:] class _Nose(object): def fix(self, command, dir_to_run, bin): if command[0] != "nosetests": return None return [bin, os.path.join(helpers_dir, "noserunner.py"), dir_to_run] + command[1:] _RUNNERS = [_Unit2(), _PyTest(), _Nose()] teamcity = TeamcityServiceMessages() class _Reporter(Reporter): def logaction_start(self, action): super(_Reporter, self).logaction_start(action) if action.activity == "getenv": teamcity.testSuiteStarted(action.id, location="tox_env://" + str(action.id)) self.current_suite = action.id def logaction_finish(self, action): super(_Reporter, self).logaction_finish(action) if action.activity == "runtests": teamcity.testSuiteFinished(action.id) def error(self, msg):
class TeamcityPlugin(ErrorClassPlugin, TextTestResult, TeamcityTestResult): """ TeamcityTest plugin for nose tests """ name = "TeamcityPlugin" enabled = True def __init__(self, stream=sys.stderr, descriptions=None, verbosity=1, config=None, errorClasses=None): super(TeamcityPlugin, self).__init__() if errorClasses is None: errorClasses = {} self.errorClasses = errorClasses if config is None: config = Config() self.config = config self.output = stream self.messages = TeamcityServiceMessages(self.output, prepend_linebreak=True) self.messages.testMatrixEntered() self.current_suite = None TextTestResult.__init__(self, stream, descriptions, verbosity, config, errorClasses) TeamcityTestResult.__init__(self, stream) def configure(self, options, conf): if not self.can_configure: return self.conf = conf def addError(self, test, err): exctype, value, tb = err err = self.formatErr(err) if exctype == SkipTest: self.messages.testIgnored(self.getTestName(test), message='Skip') else: self.messages.testError(self.getTestName(test), message='Error', details=err, duration=self.__getDuration(test)) def formatErr(self, err): exctype, value, tb = err if isinstance(value, str): try: value = exctype(value) except TypeError: pass return ''.join(traceback.format_exception(exctype, value, tb)) def is_gen(self, test): if hasattr(test, "test") and hasattr(test.test, "descriptor"): if test.test.descriptor is not None: return True return False def getTestName(self, test): if hasattr(test, "error_context"): return test.error_context test_name_full = str(test) if self.is_gen(test): return test_name_full ind_1 = test_name_full.rfind('(') if ind_1 != -1: return test_name_full[:ind_1] return test_name_full def addFailure(self, test, err): err = self.formatErr(err) self.messages.testFailed(self.getTestName(test), message='Failure', details=err) def addSkip(self, test, reason): self.messages.testIgnored(self.getTestName(test), message=reason) def _getSuite(self, test): if hasattr(test, "suite"): suite = strclass(test.suite) suite_location = test.suite.location location = test.suite.abs_location if hasattr(test, "lineno"): location = location + ":" + str(test.lineno) else: location = location + ":" + str(test.test.lineno) else: suite = strclass(test.__class__) suite_location = "python_nosetestid://" + suite try: from nose.util import func_lineno if hasattr(test.test, "descriptor") and test.test.descriptor: suite_location = "file://" + self.test_address( test.test.descriptor) location = suite_location + ":" + str( func_lineno(test.test.descriptor)) else: suite_location = "file://" + self.test_address( test.test.test) location = "file://" + self.test_address( test.test.test) + ":" + str(func_lineno(test.test.test)) except: test_id = test.id() suite_id = test_id[:test_id.rfind(".")] suite_location = "python_nosetestid://" + str(suite_id) location = "python_nosetestid://" + str(test_id) return (location, suite_location) def test_address(self, test): if hasattr(test, "address"): return test.address()[0] t = type(test) file = None import types, os if (t == types.FunctionType or issubclass(t, type) or t == type or isclass(test)): module = getattr(test, '__module__', None) if module is not None: m = sys.modules[module] file = getattr(m, '__file__', None) if file is not None: file = os.path.abspath(file) if file.endswith("pyc"): file = file[:-1] return file raise TypeError("I don't know what %s is (%s)" % (test, t)) def getSuiteName(self, test): test_name_full = str(test) ind_1 = test_name_full.rfind('(') if self.is_gen(test) and ind_1 != -1: ind = test_name_full[:ind_1].rfind('.') if ind != -1: return test_name_full[:ind] if ind_1 != -1: return test_name_full[ind_1 + 1: -1] ind = test_name_full.rfind('.') if ind != -1: return test_name_full[:test_name_full.rfind(".")] return test_name_full def startTest(self, test): location, suite_location = self._getSuite(test) suite = self.getSuiteName(test) if suite != self.current_suite: if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = suite self.messages.testSuiteStarted(self.current_suite, location=suite_location) setattr(test, "startTime", datetime.datetime.now()) self.messages.testStarted(self.getTestName(test), location=location) def stopTest(self, test): duration = self.__getDuration(test) self.messages.testFinished(self.getTestName(test), duration=int(duration)) def __getDuration(self, test): start = getattr(test, "startTime", datetime.datetime.now()) d = datetime.datetime.now() - start duration = d.microseconds / 1000 + d.seconds * 1000 + d.days * 86400000 return duration def finalize(self, result): if self.current_suite: self.messages.testSuiteFinished(self.current_suite) self.current_suite = None
def __init__(self): self.messages = TeamcityServiceMessages(prepend_linebreak=True)
class TeamcityTestListener(TestListener): def __init__(self): self.messages = TeamcityServiceMessages(prepend_linebreak=True) def on_test_suite_start(self, test_suite): self.messages.testMatrixEntered() self.messages.testCount(len(test_suite.test_cases)) def on_test_suite_finish(self, test_suite): pass def on_test_class_start(self, test_class): self.messages.testSuiteStarted(suiteName=test_class.full_name) def on_test_class_finish(self, test_class): self.messages.testSuiteFinished(suiteName=test_class.full_name) def on_test_group_start(self, test_group): if not hasattr(test_group.test_class, "is_group_feature_used") or test_group.test_class.is_group_feature_used: self.messages.testSuiteStarted(suiteName=test_group.name) def on_test_group_finish(self, test_group): if not hasattr(test_group.test_class, "is_group_feature_used") or test_group.test_class.is_group_feature_used: self.messages.testSuiteFinished(suiteName=test_group.name) def on_test_case_start(self, test_case): self.messages.testStarted(testName=test_case.name, location=test_case.location) def on_test_case_finish(self, test_case): if test_case.status == TestCaseStatus.FAILED: self.messages.testFailed(testName=test_case.name) elif test_case.status == TestCaseStatus.SKIPPED: self.messages.testIgnored(testName=test_case.name) self.messages.testFinished(testName=test_case.name, duration=int(test_case.elapsed_time * 1000.0))
# coding=utf-8 """ Runs tox from current directory. It supports any runner, but well-known runners (py.test and unittest) are switched to our internal runners to provide better support """ import os import pluggy from tox import config as tox_config from tox.session import Session from tcmessages import TeamcityServiceMessages from tox import exception teamcity = TeamcityServiceMessages() hookimpl = pluggy.HookimplMarker("tox") helpers_dir = str(os.path.split(__file__)[0]) class JbToxHook(object): """ Hook to report test start and test end. """ def __init__(self, config): self.offsets = dict() self.current_env = None self.config = config @hookimpl def tox_runtest_pre(self, venv):