# 简介
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"
}