Exemplo n.º 1
0
    def __init__(self, yml_file_path):
        api = self.api_content(yml_file_path)

        # if api.has_key(YamlTag.Body) and api.has_key(YamlTag.Procedure):
        #     print "不允许同时配置Body和Procedure标签"
        #     return None

        # Yaml 文件名及输出结果的路径
        file_name = os.path.split(yml_file_path)[1]
        root_dir = YamlHelper.same_prefix(os.path.abspath(yml_file_path), os.getcwd())
        self.interface_name = file_name[0 : file_name.index(".")]
        self.response_file = "{0}/response/{1}.yml".format(root_dir, self.interface_name)

        # Yaml配置文件定义的全局变量,对应globa标签下的变量
        self.variables = YamlVariables(api[YamlTag.Global])

        # Yaml请求实例
        self.request = YamlHttpRequest(
            YamlHelper.var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Url)),
            YamlHelper.dict_var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Auth)),
            YamlHelper.dict_var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Header)),
            YamlHelper.var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Method)),
            YamlHelper.var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Action)),
        )

        print "全局变量列表: "
        for key in self.variables.variables:
            print "key = {0} \t\t value = {1}".format(key, self.variables.variables[key])

        # 前置操作
        self.precondition = YamlStep(YamlHelper.yaml_tag_value(api, YamlTag.Precondition))

        # 请求的主体,用来进行请求参数的组合
        self.body = YamlHelper.yaml_tag_value(api, YamlTag.Body)

        # 执行过程 -- 为避免与body重复,可考虑不要该标签
        # self.procedure = YamlStep()

        # 后置操作
        self.postcondition = YamlStep(YamlHelper.yaml_tag_value(api, YamlTag.Postcondition))

        # 参数数据组合
        self.data_combination = self.data_combine()
Exemplo n.º 2
0
class YamlInterface:
    # 构造函数
    def __init__(self, yml_file_path):
        api = self.api_content(yml_file_path)

        # if api.has_key(YamlTag.Body) and api.has_key(YamlTag.Procedure):
        #     print "不允许同时配置Body和Procedure标签"
        #     return None

        # Yaml 文件名及输出结果的路径
        file_name = os.path.split(yml_file_path)[1]
        root_dir = YamlHelper.same_prefix(os.path.abspath(yml_file_path), os.getcwd())
        self.interface_name = file_name[0 : file_name.index(".")]
        self.response_file = "{0}/response/{1}.yml".format(root_dir, self.interface_name)

        # Yaml配置文件定义的全局变量,对应globa标签下的变量
        self.variables = YamlVariables(api[YamlTag.Global])

        # Yaml请求实例
        self.request = YamlHttpRequest(
            YamlHelper.var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Url)),
            YamlHelper.dict_var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Auth)),
            YamlHelper.dict_var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Header)),
            YamlHelper.var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Method)),
            YamlHelper.var_expr(self.variables.variables, YamlHelper.yaml_tag_value(api, YamlTag.Action)),
        )

        print "全局变量列表: "
        for key in self.variables.variables:
            print "key = {0} \t\t value = {1}".format(key, self.variables.variables[key])

        # 前置操作
        self.precondition = YamlStep(YamlHelper.yaml_tag_value(api, YamlTag.Precondition))

        # 请求的主体,用来进行请求参数的组合
        self.body = YamlHelper.yaml_tag_value(api, YamlTag.Body)

        # 执行过程 -- 为避免与body重复,可考虑不要该标签
        # self.procedure = YamlStep()

        # 后置操作
        self.postcondition = YamlStep(YamlHelper.yaml_tag_value(api, YamlTag.Postcondition))

        # 参数数据组合
        self.data_combination = self.data_combine()

    # 获取接口详情内容
    def api_content(self, yml_file_path):
        yml_file = open(yml_file_path)
        yml_dict = yaml.load(yml_file)
        return yml_dict[YamlTag.Interface]

    # 发送请求
    def execute(self):
        # 标签执行顺序:
        # 1.global - 构造函数中定义
        # 2.action/header/method/auth - 构造函数中定义
        # 3.precondition
        # 4.body/procedure
        # 5.postcondition
        print u"开始执行接口用例"
        # 遍历所有数组合发送所有的HTTP请求
        for data_item in self.data_combination:
            if self.precondition.expr_lines:
                print u"开始执行前置操作"
                self.precondition.execute(self.variables.variables)

            print u"开始执行过程方法"
            response = self.request.invoke(data_item)
            self.save_check_response(data_item, response)

            if self.postcondition.expr_lines:
                print u"开始执行后置操作"
                self.postcondition.execute(self.variables.variables)

    # 保存请求记录
    def save_check_response(self, data_item, response):
        # 先判断文件夹和文件是否存在
        if not os.path.exists(self.response_file):
            if not os.path.exists(os.path.split(self.response_file)[0]):
                os.makedirs(os.path.split(self.response_file)[0])
            res_file = open(self.response_file, "w")
            res_file.close()

        # 读写文件
        # 如果已经存在该配置了,则忽略
        old_yml_dict = yaml.load(open(self.response_file, "r"))
        response_dict = yaml.load(response.text)
        res_file = open(self.response_file, "a")

        # 获取key值,由于dict具有无序性,再创建key时需要以key做一次排序
        key_str = "key_"
        # iteritems() 返回一个字典键值对的元组集合
        sorted_data_item = sorted(data_item.iteritems(), key=lambda k: k[0], reverse=False)
        for item in sorted_data_item:
            key_str = key_str + str(item[1]) + "_"
        key_str = key_str[0 : len(key_str) - 1]

        result_dict = {}
        # 先要判断key是否存在,如果存在则不做任何处理,不存在则插入
        if (old_yml_dict is None) or (not old_yml_dict.has_key(key_str)):
            print "插入新的key: {0}".format(key_str)
            result_dict[key_str] = data_item
            result_dict[key_str][YamlTag.Response] = response_dict
            yaml.dump(result_dict, res_file, default_flow_style=False, indent=4)
            res_file.write("\n")
        else:
            print "已经存在key: {0}".format(key_str)
            print "已存在的key的内容为: {0}".format(old_yml_dict[key_str][YamlTag.Response])
            # 存在该Key,就需要去比较该key的值和response的值
            # 比较 old_yml_dict[YamlTag.Response] 与 response_dict 的值,以old_yml_dict为准
            flag = YamlHelper.left_cmp_dict(old_yml_dict[key_str][YamlTag.Response], response_dict)
        res_file.close()
        return flag

    # 排列组合
    def data_combine(self):
        # 将Yaml提供的字典类型转换成列表类型
        # yamlLst格式如: ["name", ["value,", "value2", "value3"], ["password", ["value1", "value2", "value3"]]]
        yamlLst = []
        for key in self.body:
            if self.body[key].has_key(YamlTag.Values):
                # 如果有values标签,则使用该标签
                values = self.body[key][YamlTag.Values]
            else:
                # 没有values标签,则使用该类型下的默认值
                value_type = self.body[key][YamlTag.Type]
                values = YamlHelper.yaml_default(value_type)
            yamlLst.append([key, values])

        lst = [self.lst_dict_lst(item) for item in yamlLst]
        dc = lst[0]
        if len(lst) == 1:
            return dc
        else:
            for i in range(1, len(lst)):
                dc = self.assemble_dict_lst(dc, lst[i])
        return dc

    # lst的格式: ["name", ["value,", "value2", "value3"]]
    # 返回形如: [{"name":"value1"}, {"name":"value2"}, {"name":"value3"}]
    def lst_dict_lst(self, lst):
        key = lst[0]  # 列表第一个元素为key
        values = lst[1]  # 列表第二个元素为一个列表,列举该key下的可选值
        return [{key: value} for value in values]

    # 将 [{"name":"value1"}, {"name":"value2"}, {"name":"value3"}]
    # 与 [{"password":"******"}, {"password":"******"}]
    # 两个列表进行排列组合成一个新的列表
    def assemble_dict_lst(self, src_lst, dst_lst):
        assemble_lst = []
        for src_dict in src_lst:
            for dst_dist in dst_lst:
                assemble_lst.append(dict(src_dict, **dst_dist))
        return assemble_lst

    # 单个请求执行
    def single_request(self, **args):
        response = self.request.invoke(args)
        return response.text