{"id":13625970,"url":"https://github.com/yuyu1987/pithy-test","last_synced_at":"2026-04-06T09:01:38.234Z","repository":{"id":57453105,"uuid":"89916627","full_name":"yuyu1987/pithy-test","owner":"yuyu1987","description":"简化接口测试","archived":false,"fork":false,"pushed_at":"2020-07-03T04:34:06.000Z","size":551,"stargazers_count":141,"open_issues_count":0,"forks_count":66,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-12-15T08:45:08.762Z","etag":null,"topics":["api","automation","interface-test","python"],"latest_commit_sha":null,"homepage":"http://pithy-test.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuyu1987.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-01T10:53:39.000Z","updated_at":"2024-10-09T13:04:57.000Z","dependencies_parsed_at":"2022-08-29T06:51:14.196Z","dependency_job_id":null,"html_url":"https://github.com/yuyu1987/pithy-test","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yuyu1987/pithy-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuyu1987%2Fpithy-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuyu1987%2Fpithy-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuyu1987%2Fpithy-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuyu1987%2Fpithy-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuyu1987","download_url":"https://codeload.github.com/yuyu1987/pithy-test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuyu1987%2Fpithy-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31466228,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T08:36:52.050Z","status":"ssl_error","status_checked_at":"2026-04-06T08:36:51.267Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","automation","interface-test","python"],"created_at":"2024-08-01T21:02:06.801Z","updated_at":"2026-04-06T09:01:38.213Z","avatar_url":"https://github.com/yuyu1987.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# 该项目不再继续更新维护了，请转到新项目 https://github.com/sunhetao/walnuts ，感谢\n\n## 安装\u0026更新\n```sh\n# 安装\npip install pithy-test\n\n# 更新\npip install -U pithy-test\n\n# 删除\npip uninstall pithy-test\n```\n\n\n## 项目文档\n[http://pithy-test.readthedocs.io/](http://pithy-test.readthedocs.io/)\n\n\n## 生成接口测试项目\n\n```shell\n(pyenv)➜  pithy-cli init\n请选择项目类型,输入api或者app: api\n请输入项目名称,如pithy-api-test: pithy-api-test\n开始创建pithy-api-test项目\n开始渲染...\n生成 api/.gitignore                   [√]\n生成 api/apis/__init__.py             [√]\n生成 api/apis/pithy_api.py            [√]\n生成 api/cfg.yaml                     [√]\n生成 api/db/__init__.py               [√]\n生成 api/db/pithy_db.py               [√]\n生成 api/README.MD                    [√]\n生成 api/requirements.txt             [√]\n生成 api/test_suites/__init__.py      [√]\n生成 api/test_suites/test_login.py    [√]\n生成 api/utils/__init__.py            [√]\n生成成功,请使用编辑器打开该项目\n```\n\n\n## 接口测试\n\n### HTTP接口\n这个地方,我扩展了python requests库的使用,在原api不变的基础上,把原先的语句调用,扩展成了函数定义,然后对输出进行了包装,下面对比一下两种写法的不同\n\n```python\nimport requests\nfrom pithy import request\n\n# 直接使用requets的api\ndata = {'key': 'value'}\nrequests.get('http://www.xxx.com', data=data)\n\n\n# 使用封装后的request\n@request(url='http://www.xxx.com')\ndef get(value):\n    data = {'key': value}\n    return {'data': data}\n```\n\n之所以这么做,是因为这样可以更突显出api,更容易参数化,对session以及响应结果更好的处理\n\n#### 使用POST方法,数据传输为form格式\n\n```python\nfrom pithy import request\n\n@request(url='http://httpbin.org/post', method='post')\ndef post(self, key1='value1'):\n    \"\"\"\n    post method\n    \"\"\"\n    data = {\n        'key1': key1\n    }\n    return dict(data=data)\n\n# 使用\nresponse = post('test').to_json()     # 解析json字符,输出为字典\nresponse = post('test').json          # 解析json字符,输出为字典\nresponse = post('test').to_content()  # 输出为字符串\nresponse = post('test').content       # 输出为字符串\nresponse = post('test').get_cookie()  # 输出cookie对象\nresponse = post('test').cookie        # 输出cookie对象\n\n# 结果取值, 假设此处response = {'a': 1, 'b': { 'c': [1, 2, 3, 4]}}\nresponse = post('13111111111', '123abc').json\n\nprint response.b.c   # 通过点号取值,结果为[1, 2, 3, 4]\n\nprint response('$.a') # 通过object path取值,结果为1\n\nfor i in response('$..c[@\u003e3]'): # 通过object path取值,结果为选中c字典里大于3的元素\n    print i\n```\n\n#### 使用GET方法\n\n\n```python\nfrom pithy import request\n\n@request(url='http://httpbin.org//get')\ndef get(self, key1='value1', key2=None):\n    \"\"\"\n    get method\n    \"\"\"\n    if key2 is None:\n        key2 = ['value2', 'value3']\n\n    params = {\n        'key1': key1,\n        'key2': key2\n    }\n    return dict(params=params)\n\n```\n\n\n#### 使用POST方法,数据传输方式为json方式\n\n\n```python\nfrom pithy import request\n\n@request(url='http://httpbin.org/post', method='post')\ndef post(self, key1='value1'):\n    \"\"\"\n    post method\n    \"\"\"\n    data = {\n        'key1': key1\n    }\n    return dict(json=data)\n\n```\n\n#### 使用类的方式组织用接口,使用同一session,指定base_url\n\n\n```python\nfrom pithy import request\n\nclass PithyAPP(object):\n\n    def __init__(self):\n        self.base_url = 'http://httpbin.org\n\n    @request(url='/get')\n    def get(self, key1='value1', key2=None):\n        \"\"\"\n        get method\n        \"\"\"\n        if key2 is None:\n            key2 = ['value2', 'value3']\n\n        params = {\n            'key1': key1,\n            'key2': key2\n        }\n        return dict(params=params)\n\n    @request(url='post', method='post')\n    def post(self, key1='value1'):\n        \"\"\"\n        post method\n        \"\"\"\n        data = {\n            'key1': key1\n        }\n        return dict(data=data)\n\n    @request(url='post', method='post')\n    def json(self, key1='value1'):\n        \"\"\"\n        post method\n        \"\"\"\n        data = {\n            'key1': key1\n        }\n        return dict(json=data)\n    \n    @request(url='login', method='post')\n    def _login(username, password):\n        \"\"\"\n        登录api\n        注: 该方法只是示例,并不能运行,请结合自己的项目使用\n        \"\"\"\n        data = {\n            'username': username,\n            'password': password\n           }\n         return dict(data=data)\n     \n     def login(username, password):\n        \"\"\"\n        登录方法\n        注: 该方法只是示例,并不能运行,请结合自己的项目使用\n        \"\"\"\n        req = self._login(username, password)\n        cookies = res.cookies  # 响应cookies\n        headers = res.headers  # 响应headers\n        self.session.headers.update(xxx=headers.get('xxx')) # 设置session里的headers,设置之后,所有的请求均会带上\n        self.session.cookies.set('xxx', cookies.get('xxx')) # 设置session里的cookies,设置之后,所有的请求均会带上\n\n# 使用，此处两个接口使用同一request session请求\napp = PithyAPP()\napp.get('value1').to_json()\napp.post('value1).to_json()\n\n```\n\n\n\n## 工具类\n### 操作日期函数 \n```python\nfrom pithy import HumanDateTime\n\n# 解析时间戳\nprint(repr(HumanDateTime(1490842267)))\nprint(HumanDateTime(1490842267000))\nprint(HumanDateTime(1490842267.11111))\nprint(HumanDateTime(1490842267111.01))\n\n# 解析字符串格式日期\nprint(HumanDateTime('2017-02-02'))\nprint(HumanDateTime('Thu Mar 30 14:21:20 2017'))\nprint(HumanDateTime(time.ctime()))\nprint(HumanDateTime('2017-3-3'))\nprint(HumanDateTime('3/3/2016'))\nprint(HumanDateTime('2017-02-02 00:00:00'))\n\n# 解析datetime或date类型时间\nprint(HumanDateTime(datetime(year=2018, month=11, day=30, hour=11)))\nprint(HumanDateTime(date(year=2018, month=11, day=30)))\n\n# 增加减少时间\nprint(HumanDateTime('2017-02-02').add_day(1))\nprint(HumanDateTime('2017-02-02').sub_day(1))\nprint(HumanDateTime('2017-02-02').add_hour(1))\nprint(HumanDateTime('2017-02-02').sub_hour(1))\nprint(HumanDateTime('2017-02-02').add(days=1, hours=1, weeks=1, minutes=1, seconds=6))\nprint(HumanDateTime('2017-02-02').sub(days=1, hours=1, weeks=1, minutes=1, seconds=6))\n\n# 转换为时间戳\nprint(HumanDateTime(1490842267.11111).timestamp_second)\nprint(HumanDateTime(1490842267.11111).timestamp_microsecond)\nprint(HumanDateTime('2017-02-02 12:12:12.1111').add_day(1).timestamp_microsecond)\nprint(HumanDateTime('2017-02-02 12:12:12 1111').add_day(1).timestamp_microsecond)\n\n# 比较大小\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003c HumanDateTime('2017-02-02 12:12:11 1111'))\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003c HumanDateTime('2017-02-02 12:13:11 1111'))\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003c '2017-02-02 12:11:11')\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003c '2017-02-02 12:13:11 1111')\nprint(HumanDateTime('2017-02-02 12:12:12 1111') == '2017-02-02 12:13:11 1111')\nprint(HumanDateTime('2017-02-02 12:12:12 1111') == '2017-02-02 12:13:12 1111')\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003c= '2017-02-02 12:13:11 1111')\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003e= '2017-02-02 12:13:11 1111')\nprint(HumanDateTime('2017-02-02 12:12:12 1111') != time.time())\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003c= time.time())\nprint(HumanDateTime('2017-02-02 12:12:12 1111') \u003e= time.time())\n\n# 约等于或者接近\nprint(HumanDateTime('2017-02-02 12:12:12 1111').approach('2017-02-02 12:12:11 1111'))\nprint(HumanDateTime('2017-02-02 12:12:12 1111').approach('2017-02-02 12:12:10 1111'))\nprint(HumanDateTime('2017-02-02 12:12:12 1111').approach('2017-02-02 12:12:10 1111', offset=2))\nprint(HumanDateTime('2017-02-02 12:12:12 1111').approach('2017-02-02 12:12:14 1111', offset=2))\n\n# 调用datetime的方法和属性\nprint(HumanDateTime('2017-02-02 12:12:12 1111').day)\nprint(HumanDateTime('2017-02-02 12:12:12 1111').year)\nprint(HumanDateTime('2017-02-02 12:12:12 1111').second)\nprint(HumanDateTime('2017-02-02 12:12:12 1111').date())\n```\n\n### 操作复杂JSON或字典\n优化JSON字符串和字典的取值方式\n\n```python\n# 1、操作JSON的KEY\nfrom pithy import JSONProcessor\ndict_data = {'a': 1, 'b': {'a': [1, 2, 3, 4]}}\njson_data = json.dumps(dict_data)\nresult = JSONProcessor(json_data)\nprint result.a     # 结果：1\nprint result.b.a   # 结果：[1, 2, 3, 4]\n\n# 这里使用的object path的取值方式,详细语法见:http://objectpath.org/reference.html\nfor i in result('$..a[@\u003e3]'):  # 结果： 4\n    print i\n\n# 2、操作字典的KEY\ndict_data = {'a': 1, 'b': {'a': [1, 2, 3, 4]}}\nresult = JSONProcessor(dict_data)\nprint result.a     # 1\nprint result.b.a   # [1, 2, 3, 4]\n```\n\n## 交流反馈qq群\n\n**563337437**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuyu1987%2Fpithy-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuyu1987%2Fpithy-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuyu1987%2Fpithy-test/lists"}