Пример #1
0
def _current_resmgr_session():
    tc = context.current_testcase()
    if tc is None:
        logger.warn("注意!非用例模式,将返回默认测试文件资源管理器,此处调用可能在测试环境下异常")
        return TestResourceManager(
            LocalResourceManagerBackend()).create_session()
    return tc.test_resources
Пример #2
0
    def post_test(self):
        '''清理测试用例
        '''
        self._run_test_complete = True
        if hasattr(self, '_record_thread_status_dict'
                   ) and self._record_thread_status_dict:
            timeout = 30
            time0 = time.time()
            while time.time() - time0 < timeout:
                for key in self._record_thread_status_dict:
                    if not self._record_thread_status_dict[key]: break
                else:
                    break
                time.sleep(0.1)
            else:
                qta_logger.warn('wait for record screen thread exit timeout')

        self._save_logcat()
        self._save_qt4a_log()
        if hasattr(self, '_logcat_debug_level_list'):
            for device in Device.device_list:
                device_name = '%s' % device.device_id
                if device_name not in self._logcat_debug_level_list:
                    msg = '设备:%s中的logcat没有debug级别的日志,请检查手机日志级别设置 ' % device_name
                    if self._check_log_called:
                        qta_logger.error(msg)
                    else:
                        qta_logger.warn(msg)

        if hasattr(settings, 'QT4A_DEVICE_HOSTS'):
            for device in Device.device_list:
                self.log_info('恢复设备: %s hosts环境' % device.device_id)
                device.modify_hosts()
Пример #3
0
    def _load(self):
        '''加载配置
        :returns: Settings - 设置读取接口
        '''
        # get PROJECT_MODE from user settings
        default_mode = getattr(qtaf_settings, 'PROJECT_MODE', None)
        try:
            pre_settings = self._load_proj_settings_module(
                "testbase.conf.pre_settings")
            mode = getattr(pre_settings, "PROJECT_MODE", default_mode)
        except ImportError as e:
            pre_settings = None
            if os.path.isfile(__file__):
                mode = "standard"
            else:
                mode = "standalone"

        if mode == "standard":  # library mode
            proj_root = getattr(pre_settings, "PROJECT_ROOT", os.getcwd())
            installed_apps = getattr(
                pre_settings, "INSTALLED_APPS",
                getattr(qtaf_settings, 'INSTALLED_APPS', []))

        else:  # egg mode
            proj_root = self._get_standalone_project_root(pre_settings)
            installed_apps = ExLibManager(proj_root).list_names()

        # load settings from qtaf
        self._load_setting_from_module(qtaf_settings)

        # load settings from installed apps
        for appname in installed_apps:
            modname = "%s.settings" % appname
            try:
                __import__(modname)
            except:
                stack = traceback.format_exc()
                logger.warn(
                    "[WARN]load library settings module \"%s\" failed:\n%s" %
                    (modname, stack))
            else:
                self._load_setting_from_module(sys.modules[modname])

        # load settings from user settings
        try:
            proj_settings = self._load_proj_settings_module(
                "testbase.conf.settings")
        except ImportError as e:
            if e.args[0] not in [
                    "No module named settings", "No module named 'settings'"
            ]:
                # project settings found and there was an error
                stack = traceback.format_exc()
                logger.warn("[WARN]load project settings failed:\n%s" % stack)
        else:
            self._load_setting_from_module(proj_settings)

        # trying to set project root automatically
        setattr(self, "PROJECT_ROOT", proj_root)
        setattr(self, "INSTALLED_APPS", installed_apps)
Пример #4
0
    def _load(self):
        '''加载配置
        :returns: Settings - 设置读取接口
        '''
        # get PROJECT_MODE from user settings
        try:
            pre_settings = self._load_proj_settings_module(
                "testbase.conf.pre_settings")
        except ImportError as e:
            logger.warn("[WARNING]settings module not found: %s" % str(e))
            pre_settings = None

        mode = getattr(pre_settings, "PROJECT_MODE",
                       getattr(qtaf_settings, 'PROJECT_MODE', None))

        if mode == "standard":  # library mode
            installed_apps = getattr(
                pre_settings, "INSTALLED_APPS",
                getattr(qtaf_settings, 'INSTALLED_APPS', []))

        else:  # egg mode
            proj_root = self._get_standalone_project_root(pre_settings)
            installed_apps = ExLibManager(proj_root).list_names()

        # load settings from qtaf
        self._load_setting_from_module(qtaf_settings)

        # load settings from installed apps
        for appname in installed_apps:
            modname = "%s.settings" % appname
            try:
                __import__(modname)
            except ImportError as e:
                logger.warn(
                    "[WARN]load library settings module \"%s\" failed: %s" %
                    (modname, str(e)))
            else:
                self._load_setting_from_module(sys.modules[modname])

        # load settings from user settings
        try:
            proj_settings = self._load_proj_settings_module(
                "testbase.conf.settings")
        except ImportError:
            pass
        else:
            self._load_setting_from_module(proj_settings)

        # trying to set project root automatically
        if mode != "standard":
            self.PROJECT_ROOT = proj_root
            self.INSTALLED_APPS = ExLibManager(proj_root).list_names()
        else:
            proj_root = getattr(self, "PROJECT_ROOT", None)
            if pre_settings is not None and not proj_root:
                proj_root = os.path.dirname(pre_settings.__file__)
                setattr(self, "PROJECT_ROOT", proj_root)
Пример #5
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
Пример #6
0
    def acquire_device(self, device_id=None, **kwargs):
        '''申请设备接口
        
        :param device_id: 设备ID,用于本地调试
        :type device_id:  string
        '''
        if device_id:
            kwargs['id'] = device_id
        resource = self.test_resources.acquire_resource('android',
                                                        condition=kwargs)
        device = DeviceProviderManager().connect_device(resource)
        if not device:
            raise RuntimeError('Connect device %s failed' % resource)

        try:
            self.test_result.log_record(
                EnumLogLevel.Environment, '申请 %s 设备成功:%s(%s)' %
                ('Android', device.model, device.device_id),
                {"device": device.imei})
        except Exception as e:
            qta_logger.warn('GetDeviceImei error:%s' % e)

        if hasattr(settings, 'QT4A_DEVICE_HOSTS'):
            device_hosts = settings.QT4A_DEVICE_HOSTS
            if device_hosts:
                self.logInfo('设置设备hosts为:\n%s' % device_hosts)
                host_list = []
                pattern = re.compile(r'\s*(\S+)\s+(\S+)\s*')
                for line in device_hosts.split('\n'):
                    line = line.strip()
                    if not line: continue
                    ret = pattern.match(line)
                    if not ret: raise RuntimeError('hosts格式错误: %r' % line)
                    host_list.append((ret.group(1), ret.group(2)))
                device.modify_hosts(host_list)

        self.add_logcat_callback(device)

        if hasattr(
                settings,
                'QT4A_RECORD_SCREEN') and settings.QT4A_RECORD_SCREEN == True:
            if not hasattr(self, '_record_thread_status_dict'):
                self._record_thread_status_dict = {}
            self._record_thread_status_dict[device.device_id] = False
            qta_logger.info('%s start record screen thread' % device.device_id)
            t = util.ThreadEx(target=self._record_screen_thread,
                              args=(device, ),
                              name='Device Record Screen Thread')
            t.setDaemon(True)
            t.start()
        device.adb.start_logcat()
        return device
Пример #7
0
    def _record_screen_thread(self, device):
        '''录屏线程
        '''
        from androiddriver.devicedriver import qt4a_path
        record_time = 4 * 1000  # 每次录制的时间
        framerate = 8
        quality = 20
        remote_tmp_path_tmpl = '%s/screen.record.%%d' % qt4a_path
        max_record_file_count = 4  # 最大临时存储的录屏文件数目
        index = 0
        device.delete_file('%s/screen.record.*' % qt4a_path)

        while not hasattr(
                self,
                '_run_test_complete') or self._run_test_complete == False:
            # 尚未结束
            remote_tmp_path = remote_tmp_path_tmpl % (index %
                                                      max_record_file_count)
            device.run_shell_cmd(
                '%s/screenshot record -p %s -t %d -f %d -q %d' %
                (qt4a_path, remote_tmp_path, record_time, framerate, quality))
            index += 1
            if index >= max_record_file_count: index -= max_record_file_count

        if not self.test_result.passed:
            merge_file_list = []
            for i in range(max_record_file_count):
                merge_file_list.append(remote_tmp_path_tmpl %
                                       ((i + index) % max_record_file_count))
            device.run_shell_cmd(
                'cat %s > %s' % (' '.join(merge_file_list),
                                 remote_tmp_path_tmpl % max_record_file_count))
            local_tmp_path = tempfile.mktemp('.record')
            device.pull_file(remote_tmp_path_tmpl % max_record_file_count,
                             local_tmp_path)
            save_dir = tempfile.mkdtemp('.screenshot')
            frame_list = Device.extract_record_frame(local_tmp_path, save_dir)
            video_path = self.__class__.__name__ + '_' + get_valid_file_name(
                device.device_id) + '_' + str(int(time.time())) + '.mp4'
            result = Device.screen_frame_to_video(frame_list, framerate,
                                                  video_path)
            if result == None:
                qta_logger.warn('opencv not installed')
            else:
                self.test_result.info('最近15秒录屏',
                                      attachments={video_path: video_path})
            shutil.rmtree(save_dir)

        self._record_thread_status_dict[device.device_id] = True
Пример #8
0
def __init_runner_types():
    global runner_types
    if runner_types:
        return
    runner_types["basic"] = TestRunner
    runner_types["multithread"] = ThreadingTestRunner
    runner_types["multiprocess"] = MultiProcessTestRunner
    for ep in pkg_resources.iter_entry_points(RUNNER_ENTRY_POINT):
        if ep.name not in runner_types:
            try:
                runner_types[ep.name] = ep.load()
            except:
                stack = traceback.format_exc()
                logger.warn("load TestRunner type for %s failed:\n%s" %
                            (ep.name, stack))
Пример #9
0
def load_datadrive_tests(cls, name=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

    tests = []
    for item in drive_data:
        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 should use \"%s\" instread of \"%s\"" % (
                cls, casedata_name, item)
            logger.warn(warn_msg)

        if isinstance(testdata, dict) and "__attrs__" in testdata:
            attrs = testdata.get("__attrs__")
        else:
            attrs = None
        tests.append(cls(testdata, casedata_name, attrs))
    return tests
Пример #10
0
    def acquire_device(self, device_id=None, **kwargs):
        '''申请设备接口
        
        :param device_id: 设备ID,用于本地调试
        :type device_id:  string
        '''
        if device_id:
            kwargs['id'] = device_id
        resource = self.test_resources.acquire_resource('android',
                                                        condition=kwargs)
        device = DeviceProviderManager().connect_device(resource)
        if not device:
            raise RuntimeError('Connect device %s failed' % resource)

        try:
            self.test_result.log_record(
                EnumLogLevel.Environment, '申请 %s 设备成功:%s(%s)' %
                ('Android', device.model, device.device_id),
                {"device": device.imei})
        except Exception, e:
            qta_logger.warn('GetDeviceImei error:%s' % e)
Пример #11
0
def __init_report_types():
    global report_types
    if report_types:
        return
    report_types.update({
        "empty": EmptyTestReport,
        "stream": StreamTestReport,
        "xml": XMLTestReport,
        "json": JSONTestReport,
        "html": HtmlTestReport,
    })

    # Register other `ITestReport` implementations from entry points
    for ep in pkg_resources.iter_entry_points(REPORT_ENTRY_POINT):
        if ep.name not in report_types:
            try:
                report_types[ep.name] = ep.load()
            except:
                stack = traceback.format_exc()
                logger.warn("load ITestReport entry point for %s failed:\n%s" %
                            (ep.name, stack))