api-test-toolkit 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env bash
2
+ # 生成新的端点模型 + 测试文件模板
3
+ # 用法:./scripts/new-endpoint.sh <资源名>
4
+ #
5
+ # 示例:./scripts/new-endpoint.sh products
6
+ # 创建:
7
+ # src/{{ package_name }}/endpoints/products.py
8
+ # tests/endpoints/test_products.py
9
+
10
+ set -euo pipefail
11
+
12
+ NAME="${1:?用法: $0 <资源名>}"
13
+
14
+ # 用 Python 推导类名
15
+ CLASS_NAME="$(python3 -c "
16
+ import sys
17
+ name = sys.argv[1]
18
+ if name.endswith('s'):
19
+ name = name[:-1]
20
+ parts = name.replace('-', '_').split('_')
21
+ result = ''.join(p.capitalize() for p in parts)
22
+ print(result + 'Endpoint')
23
+ " "$NAME")"
24
+
25
+ SRC_DIR="src/{{ package_name }}/endpoints"
26
+ TEST_DIR="tests/endpoints"
27
+
28
+ mkdir -p "$SRC_DIR" "$TEST_DIR"
29
+
30
+ # ── 端点模型 ────────────────────────────────────────────────
31
+ cat > "$SRC_DIR/$NAME.py" <<PYEOF
32
+ """${CLASS_NAME} — ${NAME} 的 API 端点模型."""
33
+ from __future__ import annotations
34
+
35
+ from api_test_kit.client import ApiResponse
36
+ from api_test_kit.endpoints._base import BaseEndpoint
37
+
38
+
39
+ class ${CLASS_NAME}(BaseEndpoint):
40
+ """${NAME} 的 CRUD 操作."""
41
+
42
+ path = "/${NAME}"
43
+
44
+ # --- 自定义方法写在这里 ---
45
+ PYEOF
46
+
47
+ # ── 测试文件 ─────────────────────────────────────────────────
48
+ cat > "$TEST_DIR/test_${NAME}.py" <<PYEOF
49
+ """${NAME} 端点测试."""
50
+ from __future__ import annotations
51
+
52
+ import pytest
53
+
54
+ from api_test_kit.assertions import assert_status, assert_ok, assert_json_has
55
+ from api_test_kit.endpoints.${NAME} import ${CLASS_NAME}
56
+
57
+
58
+ class Test${CLASS_NAME}List:
59
+ """${NAME} 列表测试."""
60
+
61
+ def test_list_success(self, client):
62
+ """应返回 200 带分页结果."""
63
+ ep = ${CLASS_NAME}(client)
64
+ resp = ep.list(page=1, size=10)
65
+ assert_status(resp, 200)
66
+ assert_ok(resp)
67
+ assert_json_has(resp, r"\$.data.items")
68
+ PYEOF
69
+
70
+ # ── 完成 ─────────────────────────────────────────────────────
71
+ echo "✅ 已创建:"
72
+ echo " $SRC_DIR/$NAME.py"
73
+ echo " $TEST_DIR/test_${NAME}.py"
74
+ echo ""
75
+ echo "下一步:运行 pytest $TEST_DIR/test_${NAME}.py -v"
@@ -0,0 +1 @@
1
+ # tests/__init__.py
@@ -0,0 +1,44 @@
1
+ """全局 fixtures。"""
2
+ from __future__ import annotations
3
+
4
+ import os
5
+
6
+ import pytest
7
+
8
+ from api_test_kit.client import BaseClient, BearerTokenProvider
9
+ from api_test_kit.config import HarnessConfig
10
+ from api_test_kit.e2e.context import ScenarioContext
11
+ from api_test_kit.logger import setup_logging
12
+
13
+
14
+ @pytest.fixture(scope="session")
15
+ def env_config() -> HarnessConfig:
16
+ """加载测试环境配置。
17
+
18
+ 通过 ``API_TEST_ENV`` 环境变量切换环境(默认: staging)。
19
+ """
20
+ env_name = os.getenv("API_TEST_ENV", "staging")
21
+ return HarnessConfig.from_env(env_name)
22
+
23
+
24
+ @pytest.fixture(scope="session")
25
+ def client(env_config: HarnessConfig) -> BaseClient:
26
+ """已鉴权的 HTTP 客户端,session 级别复用。"""
27
+ setup_logging(env_config.log_level)
28
+ client = BaseClient(env_config)
29
+ token = env_config.client_secret
30
+ if token and env_config.auth_type in ("bearer", "api_key"):
31
+ client.authenticate(BearerTokenProvider(token))
32
+ return client
33
+
34
+
35
+ @pytest.fixture
36
+ def unauthenticated_client(env_config: HarnessConfig) -> BaseClient:
37
+ """无鉴权的客户端,用于测试鉴权/错误流程。"""
38
+ return BaseClient(env_config)
39
+
40
+
41
+ @pytest.fixture
42
+ def e2e_context() -> ScenarioContext:
43
+ """每个 E2E 场景的独立上下文。"""
44
+ return ScenarioContext()
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: api-test-toolkit
3
+ Version: 0.2.0
4
+ Summary: AI 友好的 API 自动化测试工具包
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: requests>=2.31
7
+ Requires-Dist: pydantic<3,>=2.5
8
+ Requires-Dist: pydantic-settings>=2.1
9
+ Requires-Dist: python-dotenv>=1.0
10
+ Requires-Dist: jsonpath-ng>=1.6
11
+ Requires-Dist: deepdiff>=7.0
12
+ Requires-Dist: typer<1,>=0.12
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=8.0; extra == "dev"
15
+ Requires-Dist: pytest-xdist>=3.5; extra == "dev"
16
+ Requires-Dist: pytest-html>=4.1; extra == "dev"
17
+ Requires-Dist: allure-pytest>=2.13; extra == "dev"
18
+ Requires-Dist: responses>=0.25; extra == "dev"
19
+ Requires-Dist: faker>=22.0; extra == "dev"
20
+ Requires-Dist: ruff>=0.3; extra == "dev"
21
+ Requires-Dist: mypy>=1.8; extra == "dev"
@@ -0,0 +1,26 @@
1
+ api_test_kit/__init__.py,sha256=ZI9BDQpIDWrtXM_Tib995EM-ZxSbfq6kLGb9XaPuSdg,483
2
+ api_test_kit/assertions.py,sha256=ET78wN_l98CLbO_s-_RsQ0z1K7igs5mjj13BxEFUeDo,4060
3
+ api_test_kit/cli.py,sha256=DGPhQ-LWLLvNaCHYqtsyRJ4bMq9xVBFRhyuDBTkIKkU,1296
4
+ api_test_kit/client.py,sha256=ychiytV8694MlWXbY36gF7HpP3Q3s5qNz-y3K7rQD8s,7923
5
+ api_test_kit/config.py,sha256=Y9-38f9Ir39FR8gqPVbj0lkm-pw3ZxgYRXO3fjT4QZ8,2903
6
+ api_test_kit/logger.py,sha256=NcfvdXvaOkTYUg7MYzfIIb5ome_15bJnyYxo0s0-6jg,760
7
+ api_test_kit/scaffold.py,sha256=7MK7Lk4Lvp-Dj6mi4xhxM155afn8SZnrFM11_ctG4rc,5921
8
+ api_test_kit/e2e/__init__.py,sha256=GRETcT34TdWBoBLzvB1ueI7xB1jQCL5bq3sxsggajgo,435
9
+ api_test_kit/e2e/context.py,sha256=QrWHGT9IFsoPsLTO3ui5bVd6OG5GDuSnwtsJ7OnSp5s,1997
10
+ api_test_kit/e2e/helpers.py,sha256=02tcX0fEtkD0MJi2VdyK5B3fjeB8lAoJ1ufdS_2E_qs,889
11
+ api_test_kit/e2e/scenario.py,sha256=0a0mnjCnIGCcYaFAjJsvopDEvnohgx90oPdPDkx7tjw,3500
12
+ api_test_kit/e2e/step.py,sha256=htGSZdPZNFxDe1DrGt3aldOSYe4m7bq5h5Elra3gcu0,2926
13
+ api_test_kit/endpoints/__init__.py,sha256=une6WuX1_wRCcOfl005tSb5i986lN_TP7NjF1bTGCEU,1338
14
+ api_test_kit/endpoints/_base.py,sha256=9BAL0a6-3vRc7-43V6SC-acznVlaNAeVHKm_gU5rlDw,1347
15
+ api_test_kit/templates/AGENTS.md,sha256=vadIg8o_ovYL2_fhtRyH14vpHR5LF-hZzSvyYfs8XGE,1397
16
+ api_test_kit/templates/README.md,sha256=tkc-Nuh2cMcp_cR5ScXhq2vDmxbIwHNH9P2DTQRdV8Y,670
17
+ api_test_kit/templates/pyproject.toml,sha256=7Oaq_AAf2gt9RzCBulyD3nmPUTujdzRddi8J3kTkzE8,453
18
+ api_test_kit/templates/pytest.ini,sha256=YGH8NZsDDUwKcDQA4DJZnrEYo6cLDAx4jeSrHmNFQ6o,238
19
+ api_test_kit/templates/scripts/new-endpoint.sh,sha256=oIVONvY2vR2YeUekAAMk9rAeDw4hNn2a5AH5ZSaVvxA,2318
20
+ api_test_kit/templates/tests/__init__.py,sha256=iViLDCvp2HIGDniqaMz5X5TKJ-pry3mkNQnWbClsc84,20
21
+ api_test_kit/templates/tests/conftest.py,sha256=y1itnNbVBj0oZ8uT_Ix6fTc48KsdhX19O-cOc7PvHl0,1310
22
+ api_test_toolkit-0.2.0.dist-info/METADATA,sha256=weM_jvp29UWChMnmCeBuN1HxGRLX264iyJSRZ9l9lNc,743
23
+ api_test_toolkit-0.2.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
24
+ api_test_toolkit-0.2.0.dist-info/entry_points.txt,sha256=7N5ZGnaCauNMusu97hWGAdAZmCbgk3v4dJGqD7kIJYo,58
25
+ api_test_toolkit-0.2.0.dist-info/top_level.txt,sha256=aZR715fS60fIKUfQr62k00_KEFB1BdAtUeGXxvKPe8M,13
26
+ api_test_toolkit-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ api-test-toolkit = api_test_kit.cli:app
@@ -0,0 +1 @@
1
+ api_test_kit