Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎉 SDK 准备就绪 #145

Merged
merged 58 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
e579072
添加copier模板库
wu-clan Feb 29, 2024
0e08fe7
Merge branch 'master' into build-SDK
wu-clan Mar 1, 2024
a1910c5
使用原始CLI用于构建基础
wu-clan Mar 1, 2024
554e54d
更新ruff规则并格式化代码
wu-clan Mar 1, 2024
22c6ff1
重构配置文件读取为动态
wu-clan Mar 1, 2024
9f8d81b
重构路径配置为动态
wu-clan Mar 1, 2024
d5b01e5
启用ruff预览规则
wu-clan Mar 1, 2024
3d966db
重构路径配置为动态
wu-clan Mar 3, 2024
5325d9d
重构路径配置实现
wu-clan Mar 4, 2024
59e5363
修复路径变量调用
wu-clan Mar 4, 2024
2a6043d
同步修复配置变量调用
wu-clan Mar 4, 2024
1957c1d
添加执行脚本
wu-clan Mar 4, 2024
1a0980a
更新cli文件结构
wu-clan Mar 4, 2024
03ced55
默认不导出run方法
wu-clan Mar 4, 2024
47e0d12
删除遗留文件
wu-clan Mar 4, 2024
6109b4b
添加设置项目路径cli命令
wu-clan Mar 4, 2024
edd0dd4
Merge branch 'master' into build-SDK
wu-clan Mar 6, 2024
2be5dac
更新全局变量命名和测试数据读取方法
wu-clan Mar 6, 2024
830e737
修复项目生成cli
wu-clan Mar 6, 2024
c61526d
修复日志路径判断
wu-clan Mar 6, 2024
d725cd9
支持用例验证cli只使用文件名
wu-clan Mar 6, 2024
f4a89dc
添加测试用例自动生成运行参数
wu-clan Mar 7, 2024
a2f67c3
更新版本号为0.6.0
wu-clan Mar 7, 2024
5e6a5ab
Merge branch 'master' into build-SDK
wu-clan Mar 7, 2024
41851d3
修复相对路径读取
wu-clan Mar 7, 2024
b0e2457
修复新项目创建
wu-clan Mar 7, 2024
7803008
更新创建项目命令为交互式
wu-clan Mar 7, 2024
8144e7c
固定cappa版本为0.17.1
wu-clan Mar 7, 2024
344470f
更新路径和配置解析
wu-clan Mar 8, 2024
2bebd4a
修复路径和设置解析
wu-clan Mar 8, 2024
7184b9b
Merge branch 'master' into build-SDK
wu-clan Mar 9, 2024
6820602
Merge branch 'master' into build-SDK
wu-clan Mar 9, 2024
3baa472
更新依赖包
wu-clan Mar 9, 2024
1c2b76e
重命名ding文件
wu-clan Mar 9, 2024
4743cbd
Merge branch 'master' into build-SDK
wu-clan Mar 9, 2024
45134bb
修复配置文件解析
wu-clan Mar 9, 2024
17b4dec
Merge branch 'master' into build-SDK
wu-clan Mar 9, 2024
752f4dc
更新运行自动创建测试用例参数
wu-clan Mar 9, 2024
10999c4
更新README说明
wu-clan Mar 9, 2024
055bda6
Merge branch 'master' into build-SDK
wu-clan Mar 9, 2024
565a945
修复lint
wu-clan Mar 9, 2024
0f30bb4
更新配置解析触发时间
wu-clan Mar 10, 2024
4251dcd
添加typed文件
wu-clan Mar 10, 2024
b932d54
Merge branch 'master' into build-SDK
wu-clan Mar 10, 2024
8dc6bb7
为发布pypi包做准备
wu-clan Mar 10, 2024
2c185ff
更新创建新项目cli控制台打印
wu-clan Mar 10, 2024
202db57
TODO
wu-clan Mar 10, 2024
324cc07
修复路径配置读取
wu-clan Mar 10, 2024
6461395
Merge branch 'master' into build-SDK
wu-clan Mar 11, 2024
84882ea
Merge branch 'master' into build-SDK
wu-clan Mar 11, 2024
05d3ffd
为版本0.6.0做准备
wu-clan Mar 11, 2024
beeea03
修复配置导入
wu-clan Mar 11, 2024
f7920bc
更新创建项目终端打印
wu-clan Mar 11, 2024
b603e22
删除终端报错堆栈输出
wu-clan Mar 11, 2024
9d33f27
修复系统类型判断
wu-clan Mar 11, 2024
32f84ac
Merge branch 'master' into build-SDK
wu-clan Mar 11, 2024
8a28731
更新终端shell文本输入
wu-clan Mar 12, 2024
44c1eff
更新下载使用文档
wu-clan Mar 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ httpfpt/log/
.idea/
httpfpt/data/online*
.ruff_cache/
testcases/
17 changes: 6 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
![GitHub release (with filter)](https://img.shields.io/github/v/release/wu-clan/httpfpt)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

> [!IMPORTANT]
> 当前分支为 SDK 版本,如需修改源码进行功能定制,建议切换到 [master](https://github.com/wu-clan/httpfpt) 分支

基于 HTTP 请求的快速数据驱动 pytest 接口自动化测试框架

我在掘金发表了关于 `HttpFpt` 的前身和由来,包括部分功能点的说明, 感兴趣
Expand Down Expand Up @@ -37,29 +40,21 @@

## ⬇️ 下载

克隆:

```shell
git clone https://github.com/wu-clan/httpfpt.git
pip install httpfpt
```

## 🧑‍💻 Use

1. 安装依赖:

```shell
pip install -r requirements.txt
```

2. 安装 redis 数据库并启动服务
1. 安装 redis 数据库并启动服务

[Redis Windows](https://github.com/redis-windows/redis-windows)

[Linux / macOS](https://redis.io/download/)

[Docker](https://hub.docker.com/_/redis)

3. 安装 mysql 数据库(可选,如果你需要本地数据库)
2. 安装 mysql 数据库(可选,如果你需要本地数据库)

[Windows / Linux / macOS](https://dev.mysql.com/downloads/installer/)

Expand Down
63 changes: 23 additions & 40 deletions httpfpt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,13 @@
import cappa

from cappa import Subcommands
from rich.traceback import install as rich_install
from typing_extensions import TYPE_CHECKING, Annotated
from typing_extensions import Annotated

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from httpfpt.run import run
from httpfpt.utils.cli.about_testcase import generate_testcases, testcase_data_verify
from httpfpt.utils.cli.import_case_data import (
import_apifox_case_data,
import_git_case_data,
import_har_case_data,
import_jmeter_case_data,
import_openapi_case_data,
import_postman_case_data,
)
from httpfpt.utils.cli.version import get_version
from httpfpt.utils.rich_console import console

if TYPE_CHECKING:
from cappa.parser import Value


def cmd_run_test_parse(value: Value) -> bool | Value:
"""运行测试命令参数解析"""
if len(value) == 0: # type: ignore
return True
else:
return value
from httpfpt.utils.cli.new_project import create_new_project
from httpfpt.utils.cli.version import get_version


@cappa.command(name='httpfpt-cli')
Expand All @@ -52,29 +31,23 @@ class HttpFptCLI:
help='Print version information.',
),
]
run_test: Annotated[
list[str] | None,
start_project: Annotated[
bool,
cappa.Arg(
value_name='<PYTEST ARGS / NONE>',
short='-r',
long='--run',
default=None,
help='Run test cases, do not support use with other commands, but support custom pytest running parameters,'
' default parameters see `httpfpt/run.py`.',
parse=cmd_run_test_parse,
num_args=-1,
value_name='<PROJECT NAME, PROJECT PATH>',
long='--startproject',
default=False,
help='Create a new project.',
required=False,
),
]
subcmd: Subcommands[TestCaseCLI | ImportCLI | None] = None

def __call__(self) -> None:
if self.version:
get_version()
if self.run_test:
if self.version or self.subcmd:
console.print('\n❌ 暂不支持 -r/--run 命令与其他 CLI 命令同时使用')
raise cappa.Exit(code=1)
run(*self.run_test) if isinstance(self.run_test, list) else run()
if self.start_project:
create_new_project()


@cappa.command(name='testcase', help='Test case tools.')
Expand Down Expand Up @@ -103,6 +76,8 @@ class TestCaseCLI:
]

def __call__(self) -> None:
from httpfpt.utils.cli.about_testcase import generate_testcases, testcase_data_verify

if self.data_verify:
testcase_data_verify(self.data_verify)
if self.generate:
Expand Down Expand Up @@ -176,6 +151,15 @@ class ImportCLI:
]

def __call__(self) -> None:
from httpfpt.utils.cli.import_case_data import (
import_apifox_case_data,
import_git_case_data,
import_har_case_data,
import_jmeter_case_data,
import_openapi_case_data,
import_postman_case_data,
)

if self.openai:
import_openapi_case_data(self.openai)
if self.apifox:
Expand All @@ -192,7 +176,6 @@ def __call__(self) -> None:

def cappa_invoke() -> None:
"""cli 执行程序"""
rich_install()
cappa.invoke(HttpFptCLI)


Expand Down
7 changes: 7 additions & 0 deletions httpfpt/common/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ def __str__(self) -> str:
return self.msg


class ConfigInitError(HttpFptErrorMixin, RuntimeError):
"""配置初始化错误"""

def __init__(self, msg: str) -> None:
super().__init__(msg)


class AuthError(HttpFptErrorMixin, ValueError):
"""认证错误"""

Expand Down
4 changes: 2 additions & 2 deletions httpfpt/common/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from loguru import logger

from httpfpt.core.path_conf import LOG_PATH
from httpfpt.core.path_conf import httpfpt_path

if TYPE_CHECKING:
import loguru
Expand All @@ -28,7 +28,7 @@ def log() -> loguru.Logger:

:return:
"""
log_path = LOG_PATH
log_path = httpfpt_path.log_dir

if not os.path.join(log_path):
os.makedirs(log_path)
Expand Down
22 changes: 11 additions & 11 deletions httpfpt/common/send_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from httpfpt.common.errors import AssertError, SendRequestError
from httpfpt.common.log import log
from httpfpt.core.get_conf import config
from httpfpt.core.get_conf import httpfpt_config
from httpfpt.db.mysql_db import mysql_client
from httpfpt.enums.request.body import BodyType
from httpfpt.enums.request.engin import EnginType
Expand Down Expand Up @@ -63,11 +63,11 @@ def _requests_engin(**kwargs) -> RequestsResponse:
:param kwargs:
:return:
"""
kwargs['timeout'] = kwargs['timeout'] or config.REQUEST_TIMEOUT
kwargs['verify'] = kwargs['verify'] or config.REQUEST_VERIFY
kwargs['proxies'] = kwargs['proxies'] or config.REQUEST_PROXIES_REQUESTS
kwargs['allow_redirects'] = kwargs['allow_redirects'] or config.REQUEST_REDIRECTS
request_retry = kwargs['retry'] or config.REQUEST_RETRY
kwargs['timeout'] = kwargs['timeout'] or httpfpt_config.REQUEST_TIMEOUT
kwargs['verify'] = kwargs['verify'] or httpfpt_config.REQUEST_VERIFY
kwargs['proxies'] = kwargs['proxies'] or httpfpt_config.REQUEST_PROXIES_REQUESTS
kwargs['allow_redirects'] = kwargs['allow_redirects'] or httpfpt_config.REQUEST_REDIRECTS
request_retry = kwargs['retry'] or httpfpt_config.REQUEST_RETRY
del kwargs['retry']
# 消除安全警告
requests.packages.urllib3.disable_warnings() # type: ignore
Expand All @@ -93,11 +93,11 @@ def _httpx_engin(**kwargs) -> HttpxResponse:
:param kwargs:
:return:
"""
kwargs['timeout'] = kwargs['timeout'] or config.REQUEST_TIMEOUT
verify = kwargs['verify'] or config.REQUEST_VERIFY
proxies = kwargs['proxies'] or config.REQUEST_PROXIES_HTTPX
redirects = kwargs['allow_redirects'] or config.REQUEST_REDIRECTS
request_retry = kwargs['retry'] or config.REQUEST_RETRY
kwargs['timeout'] = kwargs['timeout'] or httpfpt_config.REQUEST_TIMEOUT
verify = kwargs['verify'] or httpfpt_config.REQUEST_VERIFY
proxies = kwargs['proxies'] or httpfpt_config.REQUEST_PROXIES_HTTPX
redirects = kwargs['allow_redirects'] or httpfpt_config.REQUEST_REDIRECTS
request_retry = kwargs['retry'] or httpfpt_config.REQUEST_RETRY
del kwargs['verify']
del kwargs['proxies']
del kwargs['allow_redirects']
Expand Down
8 changes: 4 additions & 4 deletions httpfpt/common/yaml_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import yaml

from httpfpt.common.log import log
from httpfpt.core.path_conf import TEST_DATA_PATH, YAML_REPORT_PATH
from httpfpt.core.path_conf import httpfpt_path
from httpfpt.utils.time_control import get_current_time


Expand Down Expand Up @@ -78,7 +78,7 @@ def write_yaml_report(
:param mode: 文件写入模式
:return
"""
_yaml_report_path = YAML_REPORT_PATH
_yaml_report_path = httpfpt_path.yaml_report_dir
if not os.path.exists(_yaml_report_path):
os.makedirs(_yaml_report_path)
_file = os.path.join(_yaml_report_path, filename)
Expand All @@ -99,9 +99,9 @@ def write_yaml_vars(data: dict) -> None:
:param data:
:return:
"""
_file = os.path.join(TEST_DATA_PATH, 'global_vars.yaml')
_file = os.path.join(httpfpt_path.data_path, 'global_vars.yaml')
try:
_vars = read_yaml(TEST_DATA_PATH, filename='global_vars.yaml')
_vars = read_yaml(httpfpt_path.data_path, filename='global_vars.yaml')
_vars.update(data)
with open(_file, encoding='utf-8', mode='w') as f:
yaml.dump(_vars, f, allow_unicode=True)
Expand Down
8 changes: 4 additions & 4 deletions httpfpt/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from httpfpt.common.log import log
from httpfpt.common.variable_cache import variable_cache
from httpfpt.common.yaml_handler import write_yaml_report
from httpfpt.core.get_conf import config as sys_config
from httpfpt.core.get_conf import httpfpt_config


@pytest.fixture(scope='session', autouse=True)
Expand Down Expand Up @@ -62,7 +62,7 @@ def pytest_configure(config):
if metadata:
from pytest_metadata.plugin import metadata_key

config.stash[metadata_key]['Project Name'] = sys_config.PROJECT_NAME
config.stash[metadata_key]['Project Name'] = httpfpt_config.PROJECT_NAME
del config.stash[metadata_key]['Packages']
del config.stash[metadata_key]['Platform']
del config.stash[metadata_key]['Plugins']
Expand All @@ -76,7 +76,7 @@ def pytest_html_results_summary(prefix):
:return:
"""
# 向 html 报告中的 summary 添加额外信息
prefix.extend([html.p(f'Tester: {sys_config.TESTER_NAME}')])
prefix.extend([html.p(f'Tester: {httpfpt_config.TESTER_NAME}')])


@pytest.mark.optionalhook
Expand All @@ -87,7 +87,7 @@ def pytest_html_report_title(report):
:param report:
:return:
"""
report.title = f'{sys_config.TEST_REPORT_TITLE}'
report.title = f'{httpfpt_config.TEST_REPORT_TITLE}'


@pytest.mark.optionalhook
Expand Down
Loading
Loading