Beispiel #1
0
    def handle_log_record(self, level, msg, record, attachments):
        '''处理一个日志记录
        
        :param level: 日志级别,参考EnumLogLevel
        :type level: string
        :param msg: 日志消息
        :type msg: string
        :param record: 日志记录
        :type record: dict
        :param attachments: 附件
        :type attachments: dict
        '''
        self._write("%s: %s\n" % (levelname[level], msg))

        if level == EnumLogLevel.ASSERT:
            if "actual" in record:
                actual = record["actual"]
                self._write("   实际值:%s%s\n" % (actual.__class__, actual))
            if "expect" in record:
                expect = record["expect"]
                self._write("   期望值:%s%s\n" % (expect.__class__, expect))
            if "code_location" in record:
                self._write(
                    smart_text('  File "%s", line %s, in %s\n' %
                               record["code_location"]))

        if "traceback" in record:
            self._write(smart_text_by_lines("%s\n" % record["traceback"]))

        for name in attachments:
            file_path = smart_text(attachments[name])
            if path_exists(file_path):
                file_path = os.path.abspath(file_path)
            self._write("   %s:%s\n" % (smart_text(name), file_path))
Beispiel #2
0
    def abs_path(self, relative_path):
        """get resource absolute path
:        type relative_path:string
        :param relative_path: ,资源文件相对描述符,相对于setting下的资源目录的路径,支持多级目录
        :return:返回资源文件的绝对路径
        """
        relative_path = self._adjust_path(relative_path)
        if relative_path.startswith(os.sep):
            relative_path = relative_path[1:]

        found_paths = []
        for it in self._resources_dirs:
            file_path = self._adjust_path(os.path.join(it, relative_path))
            file_path = smart_text(file_path)
            file_link = smart_text(file_path + '.link')
            if os.path.exists(file_path):
                found_paths.append(file_path)
            elif os.path.exists(file_link):
                with codecs_open(file_link, encoding="utf-8") as f:
                    remote_path = f.read()
                    file_path = self._resolve_link_file(remote_path, file_path)
                    found_paths.append(file_path)
        if len(found_paths) == 0:
            raise Exception("relative_path=%s not found" % relative_path)
        if len(found_paths) > 1:
            raise Exception("relative_path=%s got multiple results:\n%s" %
                            (relative_path, "\n".join(found_paths)))
        return os.path.abspath(file_path)
Beispiel #3
0
    def handle_test_begin(self, testcase):
        '''处理一个测试用例执行的开始
        
        :param testcase: 测试用例
        :type testcase: TestCase
        '''
        self._xmldoc.appendChild(
            self._xmldoc.createProcessingInstruction(
                "xml-stylesheet", 'type="text/xsl" href="TestResult.xsl"'))
        owner = getattr(testcase, 'owner', None)
        priority = getattr(testcase, 'priority', None)
        timeout = getattr(testcase, 'timeout', None)
        self._testnode = self._xmldoc.createElement('TEST')
        self._testnode.setAttribute(
            "name", smart_text(saxutils.escape(testcase.test_name)))
        self._testnode.setAttribute("owner",
                                    smart_text(saxutils.escape(str(owner))))
        self._testnode.setAttribute("priority", str(priority))
        self._testnode.setAttribute("timeout", str(timeout))
        self._testnode.setAttribute(
            'begintime',
            time.strftime("%Y-%m-%d %H:%M:%S",
                          time.localtime(self.begin_time)))
        self._xmldoc.appendChild(self._testnode)

        self.begin_step('测试用例初始步骤')
Beispiel #4
0
    def get_file(self, relative_path):
        """查找某个文件

        :type relative_path:string
        :param relative_path: ,资源文件相对描述符,相对于setting下的资源目录的路径,支持多级目录
        :return:返回资源文件的绝对路径
        """
        result = []
        relative_path = self._adjust_path(relative_path)
        if relative_path.startswith(os.sep):
            relative_path = relative_path[1:]
        for it in self._resources_dirs:
            file_path = self._adjust_path(os.path.join(it, relative_path))
            file_path = smart_text(file_path)
            file_link = smart_text(file_path + '.link')
            if os.path.isfile(file_path):
                result.append(file_path)
            elif os.path.isfile(file_link):
                with codecs_open(file_link, encoding="utf-8") as f:
                    remote_path = f.read()
                    file_path = self._resolve_link_file(remote_path, file_path)
                    result.append(file_path)
        if len(result) > 1:
            raise Exception("存在多个%s文件" % relative_path)
        elif len(result) < 1:
            raise Exception("%s文件不存在" % relative_path)
        return result[0]
Beispiel #5
0
 def _log_assert_failed(self, message, back_count=2):
     """记录断言失败的信息
     """
     stack = get_last_frame_stack(back_count)
     msg = "检查点不通过\n%s%s\n" % (smart_text(stack), smart_text(message))
     self.__testresult.log_record(EnumLogLevel.ASSERT, msg)
     if not settings.get("QTAF_ASSERT_CONTINUE", True):
         raise RuntimeError("testcase assert failed:%s" % message)
Beispiel #6
0
    def test_class_name(self):
        '''返回测试用例名字(不同测试用例的名字不同)

        :rtype: str
        '''
        cls = type(self)
        if cls.__module__ == '__main__':
            type_name = smart_text(cls.__name__)
        else:
            type_name = smart_text(cls.__module__ + '.' + cls.__name__)
        return type_name
Beispiel #7
0
 def log_filtered_test(self, loader, testcase, reason):
     '''记录一个被过滤的测试用例
     :param loader: 用例加载器
     :type loader: TestLoader
     :param testcase: 测试用例
     :type testcase: TestCase
     :param reason: 过滤原因
     :type reason: str
     '''
     nodestr = """<FilterTest name="%s" reason="%s"></FilterTest>
     """ % (smart_text(saxutils.escape(
         testcase.test_name)), smart_text(saxutils.escape(reason)))
     doc2 = dom.parseString(nodestr)
     filterNode = doc2.childNodes[0]
     self._runrstnode.appendChild(filterNode)
Beispiel #8
0
def _get_translated_in_datadrive(name, dd):
    if isinstance(name, six.string_types):
        name = smart_text(name)
    else:
        name = str(name)
    translated_name = translate_bad_char(name)
    for item in dd:
        if isinstance(item, six.string_types):
            item_string = smart_text(item)
        else:
            item_string = str(item)
        if translated_name == translate_bad_char(item_string):
            return dd[item]
    else:
        raise ValueError("找不到对应名字'%s'的数据驱动用例" % name)
Beispiel #9
0
 def log_test_result(self, testcase, testresult):
     '''记录一个测试结果
     :param testcase: 测试用例
     :type testcase: TestCase
     :param testresult: 测试结果
     :type testresult: XmlResult
     '''
     super(XMLTestReport, self).log_test_result(testcase, testresult)
     casemark = saxutils.escape(testcase.test_doc)
     nodestr = """<TestResult result="%s" log="%s" status="%s">%s</TestResult>
     """ % (testresult.passed, testresult.file_path, testcase.status, casemark)
     doc2 = dom.parseString(smart_binary(nodestr))
     resultNode = doc2.childNodes[0]
     resultNode.setAttribute("name", smart_text(saxutils.escape(testcase.test_name)))
     resultNode.setAttribute("owner", smart_text(saxutils.escape(testcase.owner)))
     self._runrstnode.appendChild(resultNode)
Beispiel #10
0
def translate_bad_char4exclude_keys(data_key):
    if isinstance(data_key, six.string_types):
        data_key = smart_text(data_key)
    else:
        data_key = str(data_key)
    data_key = translate_bad_char(data_key)
    return data_key
Beispiel #11
0
    def __record_assert_failed(self, message, actual, expect):
        '''记录Assert失败信息

        :param message: 提示信息
        :type message: string
        :param actual: 实际值
        :type actual: string
        :param expect: 期望值
        :type expect: string
        '''
        # 得到上一个函数调用帧所在的文件路径,行号,函数名
        stack = get_last_frame_stack(3)
        msg = "检查点不通过\n%s%s\n期望值:%s%s\n实际值:%s%s" % (
            smart_text(stack), smart_text(message), expect.__class__, expect,
            actual.__class__, actual)
        self.__testresult.log_record(EnumLogLevel.ASSERT, msg)
Beispiel #12
0
    def list_dir(self, relative_path):
        """列出某个目录下的文件

        :type relative_path:string
        :param relative_path: ,资源文件目录相对路径,相对于setting下的资源目录的路径,支持多级目录
        :return:返回一个包含资源目录下所有文件或者文件下的绝对路径列表
        """
        result = []
        relative_path = self._adjust_path(relative_path)
        if relative_path.startswith(os.sep):
            relative_path = relative_path[1:]
        for it in self._resources_dirs:
            dir_path = self._adjust_path(os.path.join(it, relative_path))
            dir_path = smart_text(dir_path)
            if os.path.isdir(dir_path):
                result.append(dir_path)
        if len(result) > 1:
            logger.error("找到多个目录:")
            for item in result:
                logger.error("%s" % item)
            raise Exception("存在多个%s目录" % relative_path)
        if len(result) < 1:
            raise Exception("%s目录不存在" % relative_path)
        paths = []
        for path in os.listdir(result[0]):
            paths.append(os.path.join(result[0], path))
        return paths
Beispiel #13
0
def smart_text_by_lines(s):
    '''将任意字符串转换为UTF-8编码
    '''
    lines = []
    for line in s.split('\n'):
        lines.append(smart_text(line))
    return '\n'.join(lines)
Beispiel #14
0
    def _load_from_class(self,
                         cls,
                         data_key=None,
                         exclude_data_key=None,
                         attrs=None):
        '''加载用例类

        :param cls: Python类
        :type cls: Type
        :returns list - 测试用例对象列表
        '''
        if exclude_data_key is None:
            exclude_data_key = []
        exclude_data_key = [smart_text(i) for i in exclude_data_key]

        tests = []
        if datadrive.is_datadrive(cls) or settings.DATA_DRIVE:
            tests = datadrive.load_datadrive_tests(cls, data_key, attrs)
        else:
            tests = [cls(attrs=attrs)]

        if self._filter:
            final_tests = []
            for it in tests:
                filter_reason = self._filter(it)
                if filter_reason:
                    self._filtered_tests[it] = filter_reason
                else:
                    final_tests.append(it)
            tests = final_tests
        return tests
Beispiel #15
0
 def test_xml_report(self):
     test_pairs = [("HelloTest", "断言失败"),
                 ("TimeoutTest", "用例执行超时"),
                 ("CrashTest", "App Crash"),
                 ("QT4iTest", "run_test执行失败"),]
     
     old_cwd = os.getcwd()
     for test_name, reason in test_pairs:
         try:
             test_report = report.report_types["xml"]()
             test_runner = runner.runner_types["basic"](test_report)
             test_name = "test.sampletest.hellotest.%s" % test_name
             working_dir = test_name + "_" + get_time_str()
             os.makedirs(working_dir)
             os.chdir(working_dir)
             self.addCleanup(shutil.rmtree, working_dir, True)
             print("xml report test for test: %s, wokring dir=%s" % (test_name, working_dir))
             test_runner.run(test_name)
             report_path = os.path.join(os.getcwd(), "TestReport.xml")
             xml_report = minidom.parse(report_path)
             test_results = xml_report.getElementsByTagName("TestResult")
             self.assertEqual(len(test_results), 1)
             attrs = test_results[0].attributes
             self.assertEqual(attrs["name"].value, test_name)
             self.assertEqual(attrs["result"].value, "False")
             result_path = os.path.join(os.getcwd(), attrs["log"].value)
             result_xml = minidom.parse(result_path)
             error_nodes = result_xml.getElementsByTagName("ERROR")
             self.assertEqual(len(error_nodes), 1)
             failed_reason = smart_text(error_nodes[0].childNodes[0].nodeValue)
             self.assertRegexpMatches(failed_reason, reason)
         finally:
             os.chdir(old_cwd)
Beispiel #16
0
    def assert_equal(self, message, actual, expect=True):
        '''检查实际值和期望值是否相等,不能则测试用例失败

       :param message: 检查信息
       :param actual: 实际值
       :param expect: 期望值(默认:True)
       :return: True or False
        '''
        if isinstance(actual, six.string_types):
            actual = smart_text(actual)
        if isinstance(expect, six.string_types):
            expect = smart_text(expect)
        if expect != actual:
            self.__record_assert_failed(message, actual, expect)
            return False
        else:
            return True
Beispiel #17
0
    def load(self, testname):
        '''通过名字加载测试用例
        
        :param name: 用例或用例名称
        :type name: string/list
        
        :returns list - 测试用例对象列表
        '''

        if isinstance(testname, list):
            testnames = testname
        else:
            testnames = [testname]

        self._module_errs = {}
        testcases = []

        for testname in testnames:
            testname = smart_text(testname)
            if settings.DATA_DRIVE:
                self._dataset = TestDataLoader().load()
            if '/' in testname:
                testname, datakeyname = testname.split('/', 1)
            else:
                datakeyname = None

            obj = self._load(testname)

            if isinstance(obj, types.ModuleType):
                if hasattr(obj, '__path__'):
                    testcases += self._load_from_package(obj)
                else:
                    testcases += self._load_from_module(obj)
            elif isinstance(obj, type):
                testcases += self._load_from_class(obj)

        #过滤掉重复的用例
        testcase_dict = {}
        for testcase in testcases:
            if datakeyname and smart_text(
                    testcase.casedataname) != datakeyname:
                continue
            testcase_dict[testcase.test_name] = testcase

        return list(testcase_dict.values())
Beispiel #18
0
 def test_json_report(self):
     def _clean_json_report(json_report_file, results=None):
         if results is None:
             with codecs_open(json_report_file, "r", encoding="utf-8") as fd:
                 content = fd.read()
                 results = json.loads(content)["results"]
         json_files = results[:]
         json_files.append(json_report_file)
         for json_file in json_files:
             os.remove(json_file)
            
     test_pairs = [("HelloTest", "断言失败"),
                 ("TimeoutTest", "用例执行超时"),
                 ("CrashTest", "App Crash"),
                 ("QT4iTest", "run_test执行失败"),]
     for test_name, reason in test_pairs:
         time_str = get_time_str()
         test_report_name = "%s_%s.json" % (time_str, test_name)
         with codecs_open(test_report_name, "w", encoding="utf-8") as fd:
             test_report = report.report_types["json"](fd=fd)
             test_runner = runner.runner_types["basic"](test_report)
             test_name = "test.sampletest.hellotest.%s" % test_name
             print("json report test for test: " + test_name)
             test_runner.run(test_name)
         with codecs_open(test_report_name, "r", encoding="utf-8") as fd:
             content = fd.read()
             report_json = json.loads(content)
             self.assertEqual(report_json["loaded_testcases"][0]["name"], test_name)
             test_results = report_json["results"]
             self.addCleanup(_clean_json_report, test_report_name, test_results)
             self.assertEqual(len(test_results), 1)
             with codecs_open(test_results[0], "r", encoding="utf-8") as fd2:
                 content = fd2.read()
                 result_json = json.loads(content)
                 self.assertEqual(result_json["succeed"], False)
                 failed_step = result_json["steps"][-1]
                 self.assertEqual(failed_step["succeed"], False)
                 actual_reson = smart_text(failed_step["logs"][0]["message"])
                 self.assertRegexpMatches(actual_reson, reason)
         
     test_name = "test.sampletest.hellotest.HelloTest test.sampletest.hellotest.TimeoutTest"
     time_str = get_time_str()
     test_report_name = "test_json_report_%s.json" % time_str
     retry_count = 2
     with codecs_open(test_report_name, "w", encoding="utf-8") as fd:
         test_report = report.report_types["json"](fd=fd, title="test_json_report")
         test_runner = runner.runner_types["multithread"](test_report, retries=retry_count)
         test_runner.run(test_name)
     with codecs_open(test_report_name, "r", encoding="utf-8") as fd:
         content = fd.read()
         report_json = json.loads(content)
         summary = report_json["summary"]
         self.assertEqual(summary["testcase_total_run"], (retry_count + 1) * 2)
         self.assertEqual(summary["testcase_total_count"], 2)
         self.assertTrue("hostname" in summary)
         self.assertTrue("os" in summary)
         self.addCleanup(_clean_json_report, test_report_name)
Beispiel #19
0
    def __record_assert_failed(self, message, actual, expect):
        '''记录Assert失败信息

        :param message: 提示信息
        :type message: string
        :param actual: 实际值
        :type actual: string
        :param expect: 期望值
        :type expect: string
        '''
        # 得到上一个函数调用帧所在的文件路径,行号,函数名
        stack = get_last_frame_stack(3)
        msg = "检查点不通过\n%s%s\n期望值:%s%s\n实际值:%s%s" % (
            smart_text(stack), smart_text(message), expect.__class__, expect,
            actual.__class__, actual)
        self.__testresult.log_record(EnumLogLevel.ASSERT, msg)
        if not settings.get("QTAF_ASSERT_CONTINUE", True):
            raise RuntimeError("testcase assert failed:%s" % message)
Beispiel #20
0
def load_datadrive_tests(cls, name=None, exclude_data_key=None, attrs=None):
    '''加载对应数据驱动测试用例类的数据驱动用例
    '''
    if is_datadrive(cls):
        dd = get_datadrive(cls)
    else:
        if not settings.DATA_DRIVE:
            raise RuntimeError("DATA_DRIVE is not set to True")

        from testbase.loader import TestDataLoader
        dd = TestDataLoader().load()

    if name:
        if name in dd:
            drive_data = {name : dd[name]}
        else:
            drive_value = _get_translated_in_datadrive(name, dd)
            drive_data = {name : drive_value}
    else:
        drive_data = dd

    if exclude_data_key is None:
        exclude_data_key = []

    exclude_data_key = [_translate_bad_char4exclude_keys(item) for item in exclude_data_key]

    tests = []
    for item in drive_data:
        # 如果有排除标签
        exclude_item = _translate_bad_char4exclude_keys(item)
        if exclude_data_key is not None and exclude_item in exclude_data_key:
            continue
        testdata = drive_data[item]
        if isinstance(item, six.string_types):
            item = smart_text(item)
        else:
            item = str(item)
        casedata_name = item
        if has_bad_char(item):
            casedata_name = translate_bad_char(item)
            warn_msg = "[WARNING]%r's drive data key should use \"%s\" instead of \"%s\"" % (cls, casedata_name, item)
            logger.warn(warn_msg)

        if isinstance(testdata, dict) and "__attrs__" in testdata:
            new_attrs = testdata.get("__attrs__")
        else:
            new_attrs = None

        if attrs:
            if not new_attrs:
                new_attrs = attrs
            else:
                new_attrs.update(attrs)

        tests.append(cls(testdata, casedata_name, new_attrs))
    return tests
Beispiel #21
0
    def test_name(self):
        '''返回测试用例实例的名字

        :rtype: str
        '''
        if self.casedataname is not None:
            casedataname = smart_text(self.casedataname)
            return '%s/%s' % (self.test_class_name, casedataname)
        else:
            return self.test_class_name
Beispiel #22
0
 def get_debugger(self, url=None, title=None):
     '''获取Web调试器
     '''
     if url is None and title is None:
         raise ValueError('url或title参数不能同时为空')
     page_list = self.get_page_list()
     ws_addr = None
     if len(page_list) == 1: 
         ws_addr = page_list[0]['websocketurl']
     else:
         for page in page_list:
             if (url and smart_text(page['url']) == smart_text(url) ) or (title and smart_text(page['title']) == smart_text(title) ):
                 ws_addr = page['websocketurl']
                 break
         else:
             raise RuntimeError('page %s not found' % (url or title))
     if not ws_addr in self.__class__.inst_dict:
         self.__class__.inst_dict[ws_addr] = WebkitDebugger(ws_addr)
     return self.__class__.inst_dict[ws_addr]
Beispiel #23
0
    def test_get_local_file(self):
        fm = resource.TestResourceManager(
            resource.LocalResourceManagerBackend()).create_session()
        self.assertEqual(self.local_file, fm.get_file(test_file_name))
        self.assertEqual(self.local_file, resource.get_file(test_file_name))

        paths = []
        for it in os.listdir(self.local_dir):
            paths.append(smart_text(os.path.join(self.local_dir, it)))
        self.assertEqual(paths, fm.list_dir(''))
        self.assertEqual(paths, resource.list_dir(''))
Beispiel #24
0
    def assert_match(self, message, actual, expect):
        '''检查actual和expect是否模式匹配,不匹配则记录一个检查失败

        :type message: string
        :param message: 失败时记录的消息
        :type actual: string
        :param actual: 需要匹配的字符串
        :type expect: string
        :param expect: 要匹配的正则表达式
        :return: 匹配成果
        '''
        if isinstance(actual, six.string_types):
            actual = smart_text(actual)
        if isinstance(expect, six.string_types):
            expect = smart_text(expect)
        if re.search(expect, actual):
            return True
        else:
            self.__record_assert_failed(message, actual, expect)
            return False
Beispiel #25
0
    def load(self, testname):
        '''通过名字加载测试用例

        :param name: 用例或用例名称
        :type name: string/list

        :returns list - 测试用例对象列表
        '''

        if isinstance(testname, list):
            testnames = testname
        else:
            testnames = [testname]

        self._module_errs = {}
        testcases = []

        for testname in testnames:
            parameters = {}
            exclude_data_keys = None

            if isinstance(testname, dict):
                parameters = testname.get("parameters", {})
                exclude_data_keys = testname.get("exclude_data_keys")
                testname = testname.get("name")
            testname = smart_text(testname)
            if settings.DATA_DRIVE:
                self._dataset = TestDataLoader().load()
            if '/' in testname:
                testname, data_key = testname.split('/', 1)
            else:
                data_key = None

            obj = self._load(testname)

            if isinstance(obj, types.ModuleType):
                if hasattr(obj, '__path__'):
                    testcases += self._load_from_package(
                        obj, data_key, exclude_data_keys, parameters)
                else:
                    testcases += self._load_from_module(
                        obj, data_key, exclude_data_keys, parameters)
            elif isinstance(obj, type):
                testcases += self._load_from_class(obj, data_key,
                                                   exclude_data_keys,
                                                   parameters)

        # 过滤掉重复的用例
        testcase_dict = {}
        for testcase in testcases:
            testcase_dict[testcase.test_name] = testcase

        return list(testcase_dict.values())
Beispiel #26
0
 def handle_test_end(self, passed):
     '''处理一个测试用例执行的结束
     
     :param passed: 测试用例是否通过
     :type passed: boolean
     '''
     self._testnode.setAttribute('result', str(passed))
     self._testnode.setAttribute('endtime', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.end_time)))
     self._testnode.setAttribute('duration', "%02d:%02d:%02.2f\n" % _convert_timelength(self.end_time - self.begin_time))
     if self._file_path:
         with codecs_open(smart_text(self._file_path), 'wb') as fd:
             fd.write(to_pretty_xml(self._xmldoc))
Beispiel #27
0
 def handle_step_begin(self, msg):
     '''处理一个测试步骤的开始
     
     :param msg: 测试步骤名称
     :type msg: string
     '''
     if not isinstance(msg, six.string_types):
         raise ValueError("msg='%r'必须是string类型" % msg)
     self._stepnode = self._xmldoc.createElement("STEP")
     self._stepnode.setAttribute('title', smart_text(msg))
     self._stepnode.setAttribute('time', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
     self._testnode.appendChild(self._stepnode)
Beispiel #28
0
 def loads(self, data, confs, serializer=None):
     '''load from binary
     '''
     if confs.has_key('charset'):
         try:
             data = data.decode(confs['charset']).encode('utf8')
         except UnicodeDecodeError:
             data = smart_text(data)
         root = html.fromstring(data)
     else:
         root = html.fromstring(data)
     if root.tag == 'html':
         self._data = data
         self._root = root
Beispiel #29
0
    def test_html_report_content(self):
        test_pairs = [
            ("HelloTest", "断言失败"),
            ("TimeoutTest", "用例执行超时"),
            ("CrashTest", "App Crash"),
            ("QT4iTest", "run_test执行失败"),
        ]

        old_cwd = os.getcwd()
        for test_name, reason in test_pairs:
            try:
                working_dir = test_name + "_" + get_time_str()
                os.makedirs(working_dir)
                os.chdir(working_dir)
                self.addCleanup(shutil.rmtree, working_dir, True)

                test_report = report_types["html"](title="test html report")
                test_runner = runner_types["basic"](test_report)
                test_name = "tests.sampletest.hellotest.%s" % test_name
                print("html report test for test: " + test_name)
                test_runner.run(test_name)
                html_report_file = os.path.join(os.getcwd(), "qta-report.js")
                with codecs_open(html_report_file, encoding="utf-8") as fd:
                    content = fd.read()
                    index = content.find("{")
                    qta_report_data = content[index:]
                    qta_report = json.loads(qta_report_data)
                    failed_test_names = list(qta_report["failed_tests"].keys())
                    self.assertEqual(failed_test_names[0], test_name)
                    failed_tests = qta_report["failed_tests"]
                    self.assertEqual(len(failed_tests), 1)
                    with codecs_open(failed_tests[test_name]["records"][0],
                                     "r",
                                     encoding="utf-8") as fd2:
                        content = fd2.read()
                        index = content.find("{")
                        result_json_data = content[index:]
                        result_json = json.loads(result_json_data)
                        self.assertEqual(result_json["succeed"], False)
                        failed_step = result_json["steps"][-1]
                        self.assertEqual(failed_step["succeed"], False)
                        actual_reson = smart_text(
                            failed_step["logs"][0]["message"])
                        self.assertRegexpMatches(actual_reson, reason)

            finally:
                os.chdir(old_cwd)
Beispiel #30
0
    def log_record(self, level, msg, record=None, attachments=None):
        '''处理一个日志记录
        
        :param level: 日志级别,参考EnumLogLevel
        :type level: string
        :param msg: 日志消息
        :type msg: string
        :param record: 日志记录
        :type record: dict
        :param attachments: 附件
        :type attachments: dict
        '''
        if record is None:
            record = {}
        if attachments is None:
            attachments = {}
        if not isinstance(msg, six.string_types):
            raise ValueError("msg='%r'必须是string类型" % msg)
        msg = smart_text(msg)
        if level >= EnumLogLevel.ERROR:
            self.__steps_passed[self.__curr_step] = False
            if level > self.__error_level:
                self.__error_level = level
            extra_record, extra_attachments = self._get_extra_fail_record_safe(
            )
            record.update(extra_record)
            attachments.update(extra_attachments)

            if self.__failed_priority <= 3 and level == EnumLogLevel.APPCRASH:
                self.__failed_info, self.__failed_priority = "Crash", 3

            if self.__failed_priority <= 2 and level == EnumLogLevel.TESTTIMEOUT:
                self.__failed_info, self.__failed_priority = "用例执行超时", 2

            if self.__failed_priority <= 1 and level == EnumLogLevel.ASSERT:
                self.__failed_info, self.__failed_priority = msg, 1

            if self.__failed_priority <= 1 and "traceback" in record:
                if not self.__failed_info:  # 优先记录第一个异常,第一个异常往往比较大可能是问题的原因
                    self.__failed_info, self.__failed_priority = record[
                        "traceback"].split('\n')[-2], 1

        with self.__lock:
            if not self.__accept_result:
                return
            self.handle_log_record(level, msg, record, attachments)