51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 4915|回复: 9
打印 上一主题 下一主题

[转贴] 基于 python 的接口小框架

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2017-6-1 10:47:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 测试的味道 于 2017-6-1 10:57 编辑

简单介绍
  • 环境:Win7 64,python 3,Pycharm. unittest
  • 流程:读取excel数据-生成测试用例-执行测试用例-生成html报告
excel参数说明


简单说明一下某些参数的意义
1、除了用例名字之外,所有的数据都是json的格式填写(主要是为了方便读取)2、参数用户的选择_user,主要是创建多个会话,用于一些用例需要不同用户间的互动for num, n in enumerate(cls.excel_data['test_config']['_users']):
    setattr(cls, n, requests.Session())
    _user = getattr(cls, n)

3、返回结果的参数提取:{"_get": {"company_id": ["data","rows",0,"id"]}}
就是当_get为真时,提取该次的返回结果;数字代表是当 当前数据为列表时,提取下标为0的数据
例子:dict['company_id'] = result['data'][0]['id'],下面是函数实现

    def get_value(result, param):
        """ eg:需要获取值result['1']['2'], 则param:['1','2']

        :param result: http返回结果
        :param param: 需要获取参数的路径list
        """
        if isinstance(result, list):
            result = result[param.pop(0)]
        num = len(param)
        if num == 1:
            return result[param[0]]
        else:
            return SHTestCase.get_value(result[param.pop(0)], param)

    def set_param(self, result, p):
    """ 若p['_get'],则收集返回数据的某些参数

    :param result: http返回的数据
    """
        if p['_get']:
            for n in p['_get'].keys():
                self.temp_data[n] = self.get_value(result, p['_get'][n])
        self.import_param.clear()     # 每次请求结束后,clear该字典,确保下个请求时,该字典为空,防止参数继承于上次请求
    ```
### 4、返回参数应用:{"_use": {"id":"company_id"}}

就是当_use为真时,获取临时字典的值,传入该次请求,参数传入如下图

    例子:{"id":dict['company_id']},下面是函数实现
```python
        def get_param(self, p):
        """ p['_use']内容,若为真,则提取p['_use'][x]的值,所对应的的临时字典SHTestCase.temp_data的x的值的健(说的有的混乱~~)

        :param p:
        """
        if p['_use']:
            for n in p['_use'].keys():
                self.import_param[n] = self.temp_data[p['_use'][n]]
            self.import_param.update(p['_param'])
            return self.import_param
        else:
            return p['_param']

5、对比数据,暂时实现填写的对比数据和返回数据的对比,支持无限嵌套对比def _cmp(fix_data, return_data):
    """  函数递归,判断fix字典是否和return字典的部分内容一样

    :param fix_data: 正确的字典数据
    :param return_data: 返回的自动数据
    :return:
    """
    for n1 in fix_data:
        if isinstance(fix_data[n1], dict):  # 如果n1是字典数据,进入递归判断
            if not SHTestCase._cmp(fix_data[n1], return_data.get(n1)):
                return False

        elif isinstance(fix_data[n1], list):  # 如果n1是列表数据,进入递归判断
            for num, n3 in enumerate(fix_data[n1]):
                for num1, n4 in enumerate(return_data[n1]):
                    if not return_data[n1]:
                        raise '{}返回数据为空'.format(n1)
                    if SHTestCase._cmp(fix_data[n1][num], return_data[n1][num1]):
                        SHTestCase.judge = True  # 当存在相同数据,judge为真,结束该轮循环;否则,由于递归,judge自动为假,
                        break
                if not SHTestCase.judge:  # 结束子循环后,judge没有为真,则可以判断数据不一致,返回False
                    return False

        else:
            if fix_data[n1] == return_data.get(n1):  # 对非字典和列表的数据,进入判断
                continue
            else:
                SHTestCase.temp_data['error_data'] = '{}:{} , {}:{}'.format(n1, fix_data[n1], n1,
                                                                            return_data.get(n1))
                return False
    SHTestCase.judge = False
    SHTestCase.temp_data['error_data'] = ''

    return True

主要代码
入口:protocol_runner.py

test_suite = unittest.TestSuite()

def set_case():
    for name in ConfigData.excel_data['_name'][1:]:     # 提取所有的用例名字
        def func(self, names=name):
            self.case_logic(self.excel_data[names])

        name = 'test_{:03d}_{}'.format(ConfigData.num, name)
        ConfigData.num += 1
        setattr(AutoPro, name, func)    # 设置子用例到AutoPro模块中
        test_suite.addTest(AutoPro(name))   # 添加子用例

set_case()
runner = CommonRunner('接口')
runner.run_test(test_suite)

excel的地址和下标配置

class ConfigData(object):
    # 设置需要提取数据的excel的下标页名字,和地址
    excel_data = Common.api_read_data1('test_approve_accredit',
                                       r'F:\project\auto_api\auto_protocol\api_config\testcase_data.xlsx')
    num = 2

用例的执行逻辑

def case_logic(self, _data, deep_contrast=True):
    """ 接口用例执行逻辑模板

    """
    param = self.get_param(_data)   # 获取参数
    u = getattr(self, _data['_user'])   # 设置指定用户
    self.re = getattr(u, _data['re'])   # 设置请求方式
    url = '{}{}'.format(self.ip, _data['_api'])
    result = self.re(url, param)
    result = self.result_json(result)
    self.set_param(result, _data)   # 提取需要保存的返回数据
    if deep_contrast:
        self.result_assert(_data['result'], result)     # 对返回数据做比较
    else:
        self.easy_assert(result)
html的报告样式


the last感觉好像这样说其实也不太能说明白,还是直接上代码吧,请各位大大指点一下!!
github地址:https://github.com/pencil1/auto_api
最后感谢带我入坑的:煎饼大大


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1
回复

使用道具 举报

该用户从未签到

5#
发表于 2017-6-1 11:11:23 | 只看该作者
回复 支持 反对

使用道具 举报

该用户从未签到

6#
 楼主| 发表于 2017-6-1 11:12:57 | 只看该作者
回复 支持 反对

使用道具 举报

  • TA的每日心情
    奋斗
    2020-11-21 23:27
  • 签到天数: 1180 天

    连续签到: 51 天

    [LV.10]测试总司令

    9#
    发表于 2020-12-2 15:10:05 | 只看该作者
    有没完整的源码分享下,GitHub上的链接失效了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-11-21 23:27
  • 签到天数: 1180 天

    连续签到: 51 天

    [LV.10]测试总司令

    10#
    发表于 2020-12-2 15:10:30 | 只看该作者
    源码分享下
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-10 06:47 , Processed in 0.073130 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表