tep


Nametep JSON
Version 2.2.4 PyPI version JSON
download
home_pagehttps://github.com/dongfanger/tep
Summarytep is a testing framework to help you write pytest more easily. Try Easy Pytest!
upload_time2023-12-26 12:54:34
maintainer
docs_urlNone
authordongfanger
requires_python>=3.8,<4.0
licenseApache-2.0
keywords testing keyword driven framework pytest
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 简介

tep是Try Easy Pytest的首字母缩写,帮你轻松上手pytest。

如果你选择pytest做自动化,又不知道该怎么设计框架,那么可以学习和使用tep。

特点:
- 关键字驱动
- HAR包转换pytest用例

# 安装

Python版本:12.1,下载:https://www.python.org/downloads/

创建虚拟环境:`python -m venv venv`

激活虚拟环境,Windows用户:`activate.bat` Mac用户:`source venv/bin/activate`

安装tep:`pip install tep`

验证安装成功:`tep -V`


``` text
Current Version: V2.2.2

 ____o__ __o____   o__ __o__/_   o__ __o
  /   \   /   \   <|    v       <|     v\
       \o/        < >           / \     <\
        |          |            \o/     o/
       < >         o__/_         |__  _<|/
        |          |             |
        o         <o>           <o>
       <|          |             |
       / \        / \  _\o__/_  / \
```

# 手动编写用例

执行命令`tep new demo`创建项目脚手架,demo为项目名称

```
Created folder: demo
Created folder: demo/case
Created folder: demo/data
Created folder: demo/data/har
Created folder: demo/report
Created file:   demo/replay.py
Created file:   demo/run.py
Created file:   demo/conftest.py
Created file:   demo/pytest.ini
Created file:   demo/.gitignore
Created file:   demo/case/__init__.py
Created file:   demo/case/test_demo.py
Created file:   demo/data/UserDefinedVariables.yaml
```

在case目录中,新建文件test_demo.py

定义函数:

```python
def test():
```

输入关键字`HTTPRequestKeyword`:

```python
def test(HTTPRequestKeyword):
```

填写请求方式和URL:

```python
HTTPRequestKeyword("get", url="http://httpbin.org/status/200")
```

把响应存入response对象:

```python
response = HTTPRequestKeyword("get", url="http://httpbin.org/status/200")
```

添加断言:

```python
assert response.status_code == 200
```

完整代码:

```python
def test(HTTPRequestKeyword):
    response = HTTPRequestKeyword("get", url="http://httpbin.org/status/200")
    assert response.status_code == 200
```

# 抓包转换用例

执行命令`tep new demo`创建项目脚手架,demo为项目名称

```
Created folder: demo
Created folder: demo/case
Created folder: demo/data
Created folder: demo/data/har
Created folder: demo/report
Created file:   demo/replay.py
Created file:   demo/run.py
Created file:   demo/conftest.py
Created file:   demo/pytest.ini
Created file:   demo/.gitignore
Created file:   demo/case/__init__.py
Created file:   demo/case/test_demo.py
Created file:   demo/data/UserDefinedVariables.yaml
```

通过Proxyman等工具抓包,导出为HAR包:

![](README/0f0004e9_5031008.png)

将HAR包放入`data/har`目录中,执行replay.py

在`case/replay`目录下就能看到自动生成的pytest用例。

# HTTP请求

一、GET
1.1 GET

```
HTTPRequestKeyword("get", url="")
```

1.2 GET、Header

```
HTTPRequestKeyword("get", url="", headers={})
```

1.3 GET、Header、查询参数
1.3.1 直接拼在url后面

```
HTTPRequestKeyword("get", url="" + "?a=1&b=2", headers={})
```

1.3.2 JSON转查询参数

```
from urllib.parse import urlencode

query = {}
request("get", url="" + "?" + urlencode(query), headers={})
```

1.4 GET、Header、表单

```
HTTPRequestKeyword("get", url="", headers={}, params={})
```

二、POST
2.1 POST

```
HTTPRequestKeyword("post", url="")
```

2.2 POST、Header

```
HTTPRequestKeyword("post", url="", headers={})
```

2.3 POST、Header、JSON

```
HTTPRequestKeyword("post", url="", headers={}, json={})
```

2.4 POST、Header、表单

```
HTTPRequestKeyword("post", url="", headers={}, data={})
```

三、PUT
3.1 PUT

```
HTTPRequestKeyword("put", url="")
```

3.2 PUT、Header

```
HTTPRequestKeyword("put", url="", headers={})
```

3.3 PUT、Header、JSON

```
HTTPRequestKeyword("put", url="", headers={}, json={})
```

3.4 PUT、Header、表单

```
HTTPRequestKeyword("put", url="", headers={}, data={})
```

四、DELETE
4.1 DELETE

```
HTTPRequestKeyword("delete", url="")
```

4.2 DELETE、Header

```
HTTPRequestKeyword("delete", url="", headers={})
```

五、上传文件
5.1 上传图片

```
files = {
    'file': ('filename', open('filepath', 'rb'), 'image/jpeg')
}
HTTPRequestKeyword("post", url="", headers={}, files=files)
```
注意requests会自动添加`{"Content-Type":"multipart/form-data"}`,使用headers不能再重复添加

5.2上传zip

```
files = {
    'file': ('filename', open('filepath', 'rb'), 'application/x-zip-compressed')
}
HTTPRequestKeyword("post", url="", headers={}, files=files)
```


# 🌟更新日志🌟
- ✅V2.2.4
  - 去掉loguru,不依赖visual c++,改用Python内置logging
  - 添加pytest.ini配置,支持控制台实时日志
  - 日志输出到pytest-html测试报告
  - 日志的Elapsed,毫秒保留2位小数
- V2.2.3
  - case文件夹下使用中文命名,目录名+模块名(包名+模块名)
  - 修改pytest配置python_files = *.py,识别任意名称
  - 脚手架添加中文命名示例
  - 脚手架添加场景测试用例
  - 脚手架添加Mock服务工具
  - 脚手架添加fixture\fixture_login.py
  - requests日志耗时改为毫秒
- V2.2.2
  - 基于Python12.1版本,poetry update
  - 移除allure报告,去掉--tep-reports命令行参数
  - 定制pytest-html报告内容和样式,单个HTML文件查看报告
- V2.2.1
  - 新增关键字StringKeyword,url使用`${}`替换变量
  - 回放配置添加hookVar,可自定义变量池
  - 回放配置添加hookUrl,可自定义url
  - 回放配置添加hookHeaders,可自定义headers
  - 修复BUG,回放对比生成HTML,删除顶部多余td
- V2.2.0
  - 重要:BodyKeyword改名为JSONKeyword
  - 重要:headers和body均为String,多行字符串表示,用JSONKeyword转为dict
  - 重要:新增关键字VarKeyword,与JSONKeyword结合使用,实现`${}`用法,在字符串中直接替换变量
  - 重要:去掉Result类,无须指定返回类型和定义中间变量,让关键字返回动态起来
  - 抓包自动生成用例,配置新增jsonIndent,默认设置为4,换行且4个空格缩进,可设置None不换行
  - 抓包自动生成用例,配置mode改名为overwrite,默认跳过,True则覆盖
  - 抓包自动生成用例,根据新特性,优化模版代码
- V2.1.2
  - 优化Har,支持指定目录,按增量/全量转换pytest用例
- V2.1.1
  - HAR包转换pytest用例功能纳入脚手架,主推,内容写入教程“快速入门”章节
  - 脚手架.gitignore文件后缀问题修复
- V2.1.0
  - 支持HTTP/2协议,httpx库实现
  - 支持HAR包转换为pytest用例,支持HTTP1和HTTP2协议
  - 基于HAR包的回放对比,字段对比输出TXT,文本对比输出HTML
  - 自定义日志对象,logger和sys_logger输出到用户/系统不同文件
  - 支持接口重试,CODE码/异常匹配,超时设置等,tenacity库实现
- V2.0.1 cli修改,查看版本`tep -V`,V大写,创建脚手架`tep new demo`,使用new
- V2.0.0 tep关键字驱动框架
- V1.0.0 tep小工具完整教程
- V0.2.3 tep小工具首次开源
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/dongfanger/tep",
    "name": "tep",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "testing,keyword driven,framework,pytest",
    "author": "dongfanger",
    "author_email": "dongfanger@outlook.com",
    "download_url": "https://files.pythonhosted.org/packages/fa/ea/6ba8ac0ed63c6acafc6234c9d54fda9fedde9535e5730662bee06817308b/tep-2.2.4.tar.gz",
    "platform": null,
    "description": "# \u7b80\u4ecb\n\ntep\u662fTry Easy Pytest\u7684\u9996\u5b57\u6bcd\u7f29\u5199\uff0c\u5e2e\u4f60\u8f7b\u677e\u4e0a\u624bpytest\u3002\n\n\u5982\u679c\u4f60\u9009\u62e9pytest\u505a\u81ea\u52a8\u5316\uff0c\u53c8\u4e0d\u77e5\u9053\u8be5\u600e\u4e48\u8bbe\u8ba1\u6846\u67b6\uff0c\u90a3\u4e48\u53ef\u4ee5\u5b66\u4e60\u548c\u4f7f\u7528tep\u3002\n\n\u7279\u70b9\uff1a\n- \u5173\u952e\u5b57\u9a71\u52a8\n- HAR\u5305\u8f6c\u6362pytest\u7528\u4f8b\n\n# \u5b89\u88c5\n\nPython\u7248\u672c\uff1a12.1\uff0c\u4e0b\u8f7d\uff1ahttps://www.python.org/downloads/\n\n\u521b\u5efa\u865a\u62df\u73af\u5883\uff1a`python -m venv venv`\n\n\u6fc0\u6d3b\u865a\u62df\u73af\u5883\uff0cWindows\u7528\u6237\uff1a`activate.bat` Mac\u7528\u6237\uff1a`source venv/bin/activate`\n\n\u5b89\u88c5tep\uff1a`pip install tep`\n\n\u9a8c\u8bc1\u5b89\u88c5\u6210\u529f\uff1a`tep -V`\n\n\n``` text\nCurrent Version: V2.2.2\n\n ____o__ __o____   o__ __o__/_   o__ __o\n  /   \\   /   \\   <|    v       <|     v\\\n       \\o/        < >           / \\     <\\\n        |          |            \\o/     o/\n       < >         o__/_         |__  _<|/\n        |          |             |\n        o         <o>           <o>\n       <|          |             |\n       / \\        / \\  _\\o__/_  / \\\n```\n\n# \u624b\u52a8\u7f16\u5199\u7528\u4f8b\n\n\u6267\u884c\u547d\u4ee4`tep new demo`\u521b\u5efa\u9879\u76ee\u811a\u624b\u67b6\uff0cdemo\u4e3a\u9879\u76ee\u540d\u79f0\n\n```\nCreated folder: demo\nCreated folder: demo/case\nCreated folder: demo/data\nCreated folder: demo/data/har\nCreated folder: demo/report\nCreated file:   demo/replay.py\nCreated file:   demo/run.py\nCreated file:   demo/conftest.py\nCreated file:   demo/pytest.ini\nCreated file:   demo/.gitignore\nCreated file:   demo/case/__init__.py\nCreated file:   demo/case/test_demo.py\nCreated file:   demo/data/UserDefinedVariables.yaml\n```\n\n\u5728case\u76ee\u5f55\u4e2d\uff0c\u65b0\u5efa\u6587\u4ef6test_demo.py\n\n\u5b9a\u4e49\u51fd\u6570\uff1a\n\n```python\ndef test():\n```\n\n\u8f93\u5165\u5173\u952e\u5b57`HTTPRequestKeyword`\uff1a\n\n```python\ndef test(HTTPRequestKeyword):\n```\n\n\u586b\u5199\u8bf7\u6c42\u65b9\u5f0f\u548cURL\uff1a\n\n```python\nHTTPRequestKeyword(\"get\", url=\"http://httpbin.org/status/200\")\n```\n\n\u628a\u54cd\u5e94\u5b58\u5165response\u5bf9\u8c61\uff1a\n\n```python\nresponse = HTTPRequestKeyword(\"get\", url=\"http://httpbin.org/status/200\")\n```\n\n\u6dfb\u52a0\u65ad\u8a00\uff1a\n\n```python\nassert response.status_code == 200\n```\n\n\u5b8c\u6574\u4ee3\u7801\uff1a\n\n```python\ndef test(HTTPRequestKeyword):\n    response = HTTPRequestKeyword(\"get\", url=\"http://httpbin.org/status/200\")\n    assert response.status_code == 200\n```\n\n# \u6293\u5305\u8f6c\u6362\u7528\u4f8b\n\n\u6267\u884c\u547d\u4ee4`tep new demo`\u521b\u5efa\u9879\u76ee\u811a\u624b\u67b6\uff0cdemo\u4e3a\u9879\u76ee\u540d\u79f0\n\n```\nCreated folder: demo\nCreated folder: demo/case\nCreated folder: demo/data\nCreated folder: demo/data/har\nCreated folder: demo/report\nCreated file:   demo/replay.py\nCreated file:   demo/run.py\nCreated file:   demo/conftest.py\nCreated file:   demo/pytest.ini\nCreated file:   demo/.gitignore\nCreated file:   demo/case/__init__.py\nCreated file:   demo/case/test_demo.py\nCreated file:   demo/data/UserDefinedVariables.yaml\n```\n\n\u901a\u8fc7Proxyman\u7b49\u5de5\u5177\u6293\u5305\uff0c\u5bfc\u51fa\u4e3aHAR\u5305\uff1a\n\n![](README/0f0004e9_5031008.png)\n\n\u5c06HAR\u5305\u653e\u5165`data/har`\u76ee\u5f55\u4e2d\uff0c\u6267\u884creplay.py\n\n\u5728`case/replay`\u76ee\u5f55\u4e0b\u5c31\u80fd\u770b\u5230\u81ea\u52a8\u751f\u6210\u7684pytest\u7528\u4f8b\u3002\n\n# HTTP\u8bf7\u6c42\n\n\u4e00\u3001GET\n1.1 GET\n\n```\nHTTPRequestKeyword(\"get\", url=\"\")\n```\n\n1.2 GET\u3001Header\n\n```\nHTTPRequestKeyword(\"get\", url=\"\", headers={})\n```\n\n1.3 GET\u3001Header\u3001\u67e5\u8be2\u53c2\u6570\n1.3.1 \u76f4\u63a5\u62fc\u5728url\u540e\u9762\n\n```\nHTTPRequestKeyword(\"get\", url=\"\" + \"?a=1&b=2\", headers={})\n```\n\n1.3.2 JSON\u8f6c\u67e5\u8be2\u53c2\u6570\n\n```\nfrom urllib.parse import urlencode\n\nquery = {}\nrequest(\"get\", url=\"\" + \"?\" + urlencode(query), headers={})\n```\n\n1.4 GET\u3001Header\u3001\u8868\u5355\n\n```\nHTTPRequestKeyword(\"get\", url=\"\", headers={}, params={})\n```\n\n\u4e8c\u3001POST\n2.1 POST\n\n```\nHTTPRequestKeyword(\"post\", url=\"\")\n```\n\n2.2 POST\u3001Header\n\n```\nHTTPRequestKeyword(\"post\", url=\"\", headers={})\n```\n\n2.3 POST\u3001Header\u3001JSON\n\n```\nHTTPRequestKeyword(\"post\", url=\"\", headers={}, json={})\n```\n\n2.4 POST\u3001Header\u3001\u8868\u5355\n\n```\nHTTPRequestKeyword(\"post\", url=\"\", headers={}, data={})\n```\n\n\u4e09\u3001PUT\n3.1 PUT\n\n```\nHTTPRequestKeyword(\"put\", url=\"\")\n```\n\n3.2 PUT\u3001Header\n\n```\nHTTPRequestKeyword(\"put\", url=\"\", headers={})\n```\n\n3.3 PUT\u3001Header\u3001JSON\n\n```\nHTTPRequestKeyword(\"put\", url=\"\", headers={}, json={})\n```\n\n3.4 PUT\u3001Header\u3001\u8868\u5355\n\n```\nHTTPRequestKeyword(\"put\", url=\"\", headers={}, data={})\n```\n\n\u56db\u3001DELETE\n4.1 DELETE\n\n```\nHTTPRequestKeyword(\"delete\", url=\"\")\n```\n\n4.2 DELETE\u3001Header\n\n```\nHTTPRequestKeyword(\"delete\", url=\"\", headers={})\n```\n\n\u4e94\u3001\u4e0a\u4f20\u6587\u4ef6\n5.1 \u4e0a\u4f20\u56fe\u7247\n\n```\nfiles = {\n    'file': ('filename', open('filepath', 'rb'), 'image/jpeg')\n}\nHTTPRequestKeyword(\"post\", url=\"\", headers={}, files=files)\n```\n\u6ce8\u610frequests\u4f1a\u81ea\u52a8\u6dfb\u52a0`{\"Content-Type\":\"multipart/form-data\"}`\uff0c\u4f7f\u7528headers\u4e0d\u80fd\u518d\u91cd\u590d\u6dfb\u52a0\n\n5.2\u4e0a\u4f20zip\n\n```\nfiles = {\n    'file': ('filename', open('filepath', 'rb'), 'application/x-zip-compressed')\n}\nHTTPRequestKeyword(\"post\", url=\"\", headers={}, files=files)\n```\n\n\n# \ud83c\udf1f\u66f4\u65b0\u65e5\u5fd7\ud83c\udf1f\n- \u2705V2.2.4\n  - \u53bb\u6389loguru\uff0c\u4e0d\u4f9d\u8d56visual c++\uff0c\u6539\u7528Python\u5185\u7f6elogging\n  - \u6dfb\u52a0pytest.ini\u914d\u7f6e\uff0c\u652f\u6301\u63a7\u5236\u53f0\u5b9e\u65f6\u65e5\u5fd7\n  - \u65e5\u5fd7\u8f93\u51fa\u5230pytest-html\u6d4b\u8bd5\u62a5\u544a\n  - \u65e5\u5fd7\u7684Elapsed\uff0c\u6beb\u79d2\u4fdd\u75592\u4f4d\u5c0f\u6570\n- V2.2.3\n  - case\u6587\u4ef6\u5939\u4e0b\u4f7f\u7528\u4e2d\u6587\u547d\u540d\uff0c\u76ee\u5f55\u540d+\u6a21\u5757\u540d\uff08\u5305\u540d+\u6a21\u5757\u540d\uff09\n  - \u4fee\u6539pytest\u914d\u7f6epython_files = *.py\uff0c\u8bc6\u522b\u4efb\u610f\u540d\u79f0\n  - \u811a\u624b\u67b6\u6dfb\u52a0\u4e2d\u6587\u547d\u540d\u793a\u4f8b\n  - \u811a\u624b\u67b6\u6dfb\u52a0\u573a\u666f\u6d4b\u8bd5\u7528\u4f8b\n  - \u811a\u624b\u67b6\u6dfb\u52a0Mock\u670d\u52a1\u5de5\u5177\n  - \u811a\u624b\u67b6\u6dfb\u52a0fixture\\fixture_login.py\n  - requests\u65e5\u5fd7\u8017\u65f6\u6539\u4e3a\u6beb\u79d2\n- V2.2.2\n  - \u57fa\u4e8ePython12.1\u7248\u672c\uff0cpoetry update\n  - \u79fb\u9664allure\u62a5\u544a\uff0c\u53bb\u6389--tep-reports\u547d\u4ee4\u884c\u53c2\u6570\n  - \u5b9a\u5236pytest-html\u62a5\u544a\u5185\u5bb9\u548c\u6837\u5f0f\uff0c\u5355\u4e2aHTML\u6587\u4ef6\u67e5\u770b\u62a5\u544a\n- V2.2.1\n  - \u65b0\u589e\u5173\u952e\u5b57StringKeyword\uff0curl\u4f7f\u7528`${}`\u66ff\u6362\u53d8\u91cf\n  - \u56de\u653e\u914d\u7f6e\u6dfb\u52a0hookVar\uff0c\u53ef\u81ea\u5b9a\u4e49\u53d8\u91cf\u6c60\n  - \u56de\u653e\u914d\u7f6e\u6dfb\u52a0hookUrl\uff0c\u53ef\u81ea\u5b9a\u4e49url\n  - \u56de\u653e\u914d\u7f6e\u6dfb\u52a0hookHeaders\uff0c\u53ef\u81ea\u5b9a\u4e49headers\n  - \u4fee\u590dBUG\uff0c\u56de\u653e\u5bf9\u6bd4\u751f\u6210HTML\uff0c\u5220\u9664\u9876\u90e8\u591a\u4f59td\n- V2.2.0\n  - \u91cd\u8981\uff1aBodyKeyword\u6539\u540d\u4e3aJSONKeyword\n  - \u91cd\u8981\uff1aheaders\u548cbody\u5747\u4e3aString\uff0c\u591a\u884c\u5b57\u7b26\u4e32\u8868\u793a\uff0c\u7528JSONKeyword\u8f6c\u4e3adict\n  - \u91cd\u8981\uff1a\u65b0\u589e\u5173\u952e\u5b57VarKeyword\uff0c\u4e0eJSONKeyword\u7ed3\u5408\u4f7f\u7528\uff0c\u5b9e\u73b0`${}`\u7528\u6cd5\uff0c\u5728\u5b57\u7b26\u4e32\u4e2d\u76f4\u63a5\u66ff\u6362\u53d8\u91cf\n  - \u91cd\u8981\uff1a\u53bb\u6389Result\u7c7b\uff0c\u65e0\u987b\u6307\u5b9a\u8fd4\u56de\u7c7b\u578b\u548c\u5b9a\u4e49\u4e2d\u95f4\u53d8\u91cf\uff0c\u8ba9\u5173\u952e\u5b57\u8fd4\u56de\u52a8\u6001\u8d77\u6765\n  - \u6293\u5305\u81ea\u52a8\u751f\u6210\u7528\u4f8b\uff0c\u914d\u7f6e\u65b0\u589ejsonIndent\uff0c\u9ed8\u8ba4\u8bbe\u7f6e\u4e3a4\uff0c\u6362\u884c\u4e144\u4e2a\u7a7a\u683c\u7f29\u8fdb\uff0c\u53ef\u8bbe\u7f6eNone\u4e0d\u6362\u884c\n  - \u6293\u5305\u81ea\u52a8\u751f\u6210\u7528\u4f8b\uff0c\u914d\u7f6emode\u6539\u540d\u4e3aoverwrite\uff0c\u9ed8\u8ba4\u8df3\u8fc7\uff0cTrue\u5219\u8986\u76d6\n  - \u6293\u5305\u81ea\u52a8\u751f\u6210\u7528\u4f8b\uff0c\u6839\u636e\u65b0\u7279\u6027\uff0c\u4f18\u5316\u6a21\u7248\u4ee3\u7801\n- V2.1.2\n  - \u4f18\u5316Har\uff0c\u652f\u6301\u6307\u5b9a\u76ee\u5f55\uff0c\u6309\u589e\u91cf/\u5168\u91cf\u8f6c\u6362pytest\u7528\u4f8b\n- V2.1.1\n  - HAR\u5305\u8f6c\u6362pytest\u7528\u4f8b\u529f\u80fd\u7eb3\u5165\u811a\u624b\u67b6\uff0c\u4e3b\u63a8\uff0c\u5185\u5bb9\u5199\u5165\u6559\u7a0b\u201c\u5feb\u901f\u5165\u95e8\u201d\u7ae0\u8282\n  - \u811a\u624b\u67b6.gitignore\u6587\u4ef6\u540e\u7f00\u95ee\u9898\u4fee\u590d\n- V2.1.0\n  - \u652f\u6301HTTP/2\u534f\u8bae\uff0chttpx\u5e93\u5b9e\u73b0\n  - \u652f\u6301HAR\u5305\u8f6c\u6362\u4e3apytest\u7528\u4f8b\uff0c\u652f\u6301HTTP1\u548cHTTP2\u534f\u8bae\n  - \u57fa\u4e8eHAR\u5305\u7684\u56de\u653e\u5bf9\u6bd4\uff0c\u5b57\u6bb5\u5bf9\u6bd4\u8f93\u51faTXT\uff0c\u6587\u672c\u5bf9\u6bd4\u8f93\u51faHTML\n  - \u81ea\u5b9a\u4e49\u65e5\u5fd7\u5bf9\u8c61\uff0clogger\u548csys_logger\u8f93\u51fa\u5230\u7528\u6237/\u7cfb\u7edf\u4e0d\u540c\u6587\u4ef6\n  - \u652f\u6301\u63a5\u53e3\u91cd\u8bd5\uff0cCODE\u7801/\u5f02\u5e38\u5339\u914d\uff0c\u8d85\u65f6\u8bbe\u7f6e\u7b49\uff0ctenacity\u5e93\u5b9e\u73b0\n- V2.0.1 cli\u4fee\u6539\uff0c\u67e5\u770b\u7248\u672c`tep -V`\uff0cV\u5927\u5199\uff0c\u521b\u5efa\u811a\u624b\u67b6`tep new demo`\uff0c\u4f7f\u7528new\n- V2.0.0 tep\u5173\u952e\u5b57\u9a71\u52a8\u6846\u67b6\n- V1.0.0 tep\u5c0f\u5de5\u5177\u5b8c\u6574\u6559\u7a0b\n- V0.2.3 tep\u5c0f\u5de5\u5177\u9996\u6b21\u5f00\u6e90",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "tep is a testing framework to help you write pytest more easily. Try Easy Pytest!",
    "version": "2.2.4",
    "project_urls": {
        "Homepage": "https://github.com/dongfanger/tep",
        "Repository": "https://github.com/dongfanger/tep"
    },
    "split_keywords": [
        "testing",
        "keyword driven",
        "framework",
        "pytest"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fa86c5e3e2dbe38217afcec5256d6e66d84dede4e1bdbdab5e0104b35a55a601",
                "md5": "15143d2f97eeba9edfe0d6f6ed7f5826",
                "sha256": "66fc091daf752afa08ea7201a239ca4dc02b2ac0243f7b86668e8abfe6df1a88"
            },
            "downloads": -1,
            "filename": "tep-2.2.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "15143d2f97eeba9edfe0d6f6ed7f5826",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 35910,
            "upload_time": "2023-12-26T12:54:31",
            "upload_time_iso_8601": "2023-12-26T12:54:31.941368Z",
            "url": "https://files.pythonhosted.org/packages/fa/86/c5e3e2dbe38217afcec5256d6e66d84dede4e1bdbdab5e0104b35a55a601/tep-2.2.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "faea6ba8ac0ed63c6acafc6234c9d54fda9fedde9535e5730662bee06817308b",
                "md5": "cd759f8d9423843a24ef66b6798536ab",
                "sha256": "f95febb0f96470405b561c470890a05db3dd6801e932b2d94caad6454f38987c"
            },
            "downloads": -1,
            "filename": "tep-2.2.4.tar.gz",
            "has_sig": false,
            "md5_digest": "cd759f8d9423843a24ef66b6798536ab",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 31470,
            "upload_time": "2023-12-26T12:54:34",
            "upload_time_iso_8601": "2023-12-26T12:54:34.225926Z",
            "url": "https://files.pythonhosted.org/packages/fa/ea/6ba8ac0ed63c6acafc6234c9d54fda9fedde9535e5730662bee06817308b/tep-2.2.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-26 12:54:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "dongfanger",
    "github_project": "tep",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "tep"
}
        
Elapsed time: 0.14719s