封装重复操作
  来,我们再整理一下我们的需求:
  首先,不想去重复做拼接url的操作。
  然后,不想每次都去手工打印日志。
  不想和requests session打交道。
  只想定义好参数直接调用。
  我们先看一下实现后,脚本可能是什么样:
 class DemoApi(object):
  def __init__(self, base_url):
  self.base_url = base_url
  @request(url='login', method='post')
  def login(self, username, password):
  """
  登录接口
  """
  data = {
  'username': username,
  'password': password
  }
  return {'data': data}
  @request(url='info', method='get')
  def info(self):
  """
  详情接口
  """
  pass
  调用登录接口的日志:
 ******************************************************
  1、接口描述
  登录接口
  2、请求url
  http://127.0.0.1:5000/login
  3、请求方法
  post
  4、请求headers
  {
  "Accept": "*/*",
  "Accept-Encoding": "gzip, deflate",
  "Connection": "keep-alive",
  "User-Agent": "python-requests/2.7.0 CPython/2.7.10 Darwin/16.4.0"
  }
  5、body参数
  {
  "password": "123456",
  "username": "admin"
  }
  6、响应结果
  {
  "code": 200,
  "msg": "success"
  }
  在这里,我们使用python的装饰器功能,把公共特性封装到装饰器中去实现。现在感觉好多了,没什么多余的东西了,我们可以专注于关键参数的构造,剩下的是如何去实现这个装饰器了,我们先理一下思路:
  获取装饰器参数
  获取函数/方法参数
  把装饰器和函数定义的参数合并
  拼接url
  处理requests session,有则使用,无则新生成一个
  组装所有参数,发送http请求并打印日志
  因篇幅限制,源码不再列出,有兴趣的同学可以查看已经实现的源代码。
  源代码查看地址:https://github.com/yuyu1987/pithy-test/blob/master/pithy/api.py
  七、扩展
  http接口请求的姿势我们定义好了,我们还可以做些什么呢?
  [x] 非HTTP协议接口
  [x] 测试用例编写
  [x] 配置文件管理
  [x] 测试数据管理
  [x] 工具类编写
  [x] 测试报告生成
  [x] 持续集成
  [x] 等等等等
  需要做的还是挺多的,要做什么不要做什么,或者先做哪个,我觉得可以根据以下几点去判断:
  是否有利于提高团队生产效率?
  是否有利于提高测试质量?
  有没有现成的轮子可以用?
  下面几项主要的点进行一下说明,限于篇幅,不再展开了。
  测试报告
  这个应该是大家关心的了,毕竟这是测试工作的产出;
  目前python的主流单元测试框均有report插件,因此不建议自己再编写,除非有特殊需求的。
  pytest:推荐使用pytest-html和allure pytest。
  unittest:推荐使用HTMLTestRunner。
  持续集成
  持续集成推荐使用Jenkins,运行环境、定时任务、触发运行、邮件发送等一系列功能均可以在Jenkins上实现。
  测试用例编写
  推荐遵守如下规则:
  原子性:每个用例保持独立,彼此不耦合,以降低干扰。
  专一性:一个用例应该专注于验证一件事情,而不是做很多事情,一个测试点不要重复验证。
  稳定性:绝大多数用例应该是非常稳定的,也是说不会经常因为除环境以外的因素挂掉,因为如果在一个测试项目中有很多不稳定的用例的话,测试结果不能很好的反应项目质量。
  分类清晰:有相关性的用例应写到一个模块或一个测试类里,这样做即方便维护,又提高了报告的可读性。
  测试工具类
  这个可以根据项目情况去做,力求简化一些类库的使用,数据库访问、日期时间、序列化与反序列化等数据处理,或者封装一些常用操作,如随机生成订单号等等,以提高脚本编写效率。
  测试数据管理
  常见的方式有写在代码里、写在配置文件里(xml、yaml、json、.py、excel等)、写在数据库里等,该处没有什么好推荐的,建议根据个人喜好,怎么方便怎么来可以。
  八、pithy测试框架介绍
  pithy意为简洁有力的,意在简化自动化接口测试,提高测试效率。
  项目地址:点击查看
  帮助文档:点击查看
  目前实现的功能如下:
  一键生成测试项目
  http client封装
  thrift接口封装
  简化配置文件使用
  优化JSON、日期等工具使用
  编写测试用例推荐使用pytest,pytest提供了很多测试工具以及插件,可以满足大部分测试需求。
  安装
pip install pithy-test
pip install pytest
  使用
  一键生成测试项目
 >>>  pithy-cli init
  请选择项目类型,输入api或者app: api
  请输入项目名称,如pithy-api-test: pithy-api-test
  开始创建pithy-api-test项目
  开始渲染...
  生成 api/.gitignore                   [√]
  生成 api/apis/__init__.py             [√]
  生成 api/apis/pithy_api.py            [√]
  生成 api/cfg.yaml                     [√]
  生成 api/db/__init__.py               [√]
  生成 api/db/pithy_db.py               [√]
  生成 api/README.MD                    [√]
  生成 api/requirements.txt             [√]
  生成 api/test_suites/__init__.py      [√]
  生成 api/test_suites/test_login.py    [√]
  生成 api/utils/__init__.py            [√]
  生成成功,请使用编辑器打开该项目
  生成项目树:
>>> tree pithy-api-test
  pithy-api-test
  ├── README.MD
  ├── apis
  │   ├── __init__.py
  │   └── pithy_api.py
  ├── cfg.yaml
  ├── db
  │   ├── __init__.py
  │   └── pithy_db.py
  ├── requirements.txt
  ├── test_suites
  │   ├── __init__.py
  │   └── test_login.py
  └── utils
  └── __init__.py
  4 directories, 10 files
  调用HTTP登录接口示例
  from pithy import request
  @request(url='http://httpbin.org/post', method='post')
  def post(self, key1='value1'):
  """
  post method
  """
  data = {
  'key1': key1
  }
  return dict(data=data)
  # 使用
  response = post('test').to_json()     # 解析json字符,输出为字典
  response = post('test').json          # 解析json字符,输出为字典
  response = post('test').to_content()  # 输出为字符串
  response = post('test').content       # 输出为字符串
  response = post('test').get_cookie()  # 输出cookie对象
  response = post('test').cookie        # 输出cookie对象
  # 结果取值, 假设此处response = {'a': 1, 'b': { 'c': [1, 2, 3, 4]}}
  response = post('13111111111', '123abc').json
  print response.b.c   # 通过点号取值,结果为[1, 2, 3, 4]
  print response('$.a') # 通过object path取值,结果为1
  for i in response('$..c[@>3]'): # 通过object path取值,结果为选中c字典里大于3的元素
  print i
  优化JSON、字典使用
  # 1、操作JSON的KEY
  from pithy import JSONProcessor
  dict_data = {'a': 1, 'b': {'a': [1, 2, 3, 4]}}
  json_data = json.dumps(dict_data)
  result = JSONProcessor(json_data)
  print result.a     # 结果:1
  print result.b.a   # 结果:[1, 2, 3, 4]
  # 2、操作字典的KEY
  dict_data = {'a': 1, 'b': {'a': [1, 2, 3, 4]}}
  result = JSONProcessor(dict_data)
  print result.a     # 1
  print result.b.a   # [1, 2, 3, 4]
  # 3、object path取值
  raw_dict = {
  'key1':{
  'key2':{
  'key3': [1, 2, 3, 4, 5, 6, 7, 8]
  }
  }
  }
  jp = JSONProcessor(raw_dict)
  for i in jp('$..key3[@>3]'):
  print i
  # 4、其它用法
  dict_1 = {'a': 'a'}
  json_1 = '{"b": "b"}'
  jp = JSONProcessor(dict_1, json_1, c='c')
  print(jp)
  九、总结
  在本文中,我们以提高脚本开发效率为前提,一步一步打造了一个简易的测试框架,但因水平所限,并未涉及测试数据初始化清理、测试中如何MOCK等话题,前路依然任重而道远,希望给大家一个启发,不足之处还望多多指点,非常感谢。