def get_func_source_code(func): if isinstance(func, types.MethodType): if sys.version_info[0] == 3: src_code = inspect.getsource(func.__self__.__class__) else: im_class = get_method_defined_class(func) src_code = inspect.getsource(im_class) else: src_code = inspect.getsource(func) indent = inspect.indentsize(src_code) if indent > 0: lines = src_code.split("\n") src_code = "" for line in lines: src_code += line[indent:] + "\n" return src_code
def _get_extra_fail_record_safe(self, timeout=300): '''使用线程调用测试用例的get_extra_fail_record ''' def _run(outputs, errors): try: outputs.append( context.current_testcase().get_extra_fail_record()) except: errors.append(traceback.format_exc()) errors = [] outputs = [] t = threading.Thread(target=_run, args=(outputs, errors)) t.daemon = True t.start() t.join(timeout) extra_record, extra_attachments = {}, {} with self.__lock: if t.is_alive(): stack = get_thread_traceback(t) self.handle_log_record(EnumLogLevel.ERROR, '测试失败时获取其他额外错误信息超过了指定时间:%ds' % timeout, {'traceback': stack}, {}) else: if errors: self.handle_log_record(EnumLogLevel.ERROR, '测试失败时获取其他额外错误信息失败', {'traceback': errors[0]}, {}) else: record_info = outputs[0] if isinstance(record_info, (tuple, list)) and len(record_info) == 2: extra_record, extra_attachments = record_info else: cls = get_method_defined_class( self.testcase.get_extra_fail_record) if cls.__module__ == '__main__': class_path = cls.__name__ else: class_path = "%s.%s" % (cls.__module__, cls.__name__) raise RuntimeError( "%s.get_extra_fail_record must return a 2 elements tuple" % class_path) return extra_record, extra_attachments