mcpField
P
prowler-test-api

prowler-test-api

github.com/prowler-cloud测试与质量15.1k68 次安装今天更新
代码仓库

关于 prowler-test-api

prowler-test-api 是供 Prowler API 贡献者使用的测试技能,提供 JSON:API 请求、租户隔离、测试夹具和 Celery 测试规范。

主要功能

  1. 01JSON:API 请求与响应模式
  2. 02租户隔离测试指引
  3. 03可复用测试夹具参考
  4. 04Celery 任务测试策略
  5. 05API 测试命令

适用场景

  1. 01测试 API 端点变更
  2. 02验证跨租户访问隔离
  3. 03测试异步视图与 Celery 任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/prowler-cloud/prowler --skill prowler-test-api

安装后在 Claude Code 中输入/prowler-test-api确认已加载。

附带文件assets/api_test.pyreferences/test-api-docs.md

详细介绍

关键规则

  • 始终使用 response.json()["data"],不要使用 response.data
  • 对 PATCH/PUT 请求,始终使用 content_type = "application/vnd.api+json"
  • 对 POST 请求,始终使用 format="vnd.api+json"
  • 始终测试跨租户隔离——RLS 返回 404,而不是 403
  • 添加新端点时,绝不要跳过 RLS 隔离测试
  • 测试中绝不要使用看起来真实的 API 密钥(TruffleHog 会将其标记出来)
  • 测试异步任务时,始终同时模拟 .delay() 和 Task.objects.get

1. Fixture 依赖链

create_test_user (session) ─► tenants_fixture (function) ─► authenticated_client
                                     │
                                     └─► aws_provider ─► scans_fixture ─► findings_fixture
关键 Fixture
Fixture说明
create_test_user会话用户([email protected])
tenants_fixture3 个租户:[0]、[1] 有成员关系,[2] 为隔离租户
authenticated_client使用 tenant[0] 的 JWT 的 Django 测试客户端
authenticated_client_for_tenant_factory创建一个使用指定用户和租户的 JWT 的 Django 测试客户端
provider_factory创建一个具有特定于提供方的默认值且已验证的提供方
aws_providertenant[0] 中的 1 个 AWS 提供方
aws_provider_pairtenant[0] 中的 2 个 AWS 提供方
all_provider_types_fixture每种受支持的提供方类型各有 1 个提供方
tasks_fixture2 个带有 TaskResult 的 Celery 任务
RBAC Fixture
Fixture权限
authenticated_client_rbac所有权限(管理员)
authenticated_client_rbac_noroles有成员关系,但没有角色
authenticated_client_no_permissions_rbac所有权限均为 False

普通视图行为测试使用 authenticated_client。它使用开销较低的 JWT, 同时仍会经过真实的请求身份验证流程。只有当测试专门针对令牌获取/刷新、 无效令牌、过期令牌、通过令牌切换租户、API 密钥或未通过身份验证时的 401 行为时,才使用序列化器生成的 JWT 或 API 密钥客户端。若测试需要为其他用户 或租户创建开销较低的 JWT 客户端,请使用 authenticated_client_for_tenant_factory。


2. JSON:API 请求

POST(创建)
response = client.post(
    reverse("provider-list"),
    data={"data": {"type": "providers", "attributes": {...}}},
    format="vnd.api+json",  # NOT content_type!
)
PATCH(更新)
response = client.patch(
    reverse("provider-detail", kwargs={"pk": provider.id}),
    data={"data": {"type": "providers", "id": str(provider.id), "attributes": {...}}},
    content_type="application/vnd.api+json",  # NOT format!
)
读取响应
data = response.json()["data"]
attrs = data["attributes"]
errors = response.json()["errors"]  # For 400 responses

3. RLS 隔离(跨租户)

RLS 返回 404,而不是 403——该资源不可见,而非禁止访问。

def test_cross_tenant_access_denied(self, authenticated_client, tenants_fixture):
    other_tenant = tenants_fixture[2]  # Isolated tenant
    foreign_provider = Provider.objects.create(tenant_id=other_tenant.id, ...)

    response = authenticated_client.get(reverse("provider-detail", args=[foreign_provider.id]))
    assert response.status_code == status.HTTP_404_NOT_FOUND  # NOT 403!

4. Celery 任务测试

测试策略
策略适用场景
模拟 .delay() + Task.objects.get测试会触发任务的视图
task.apply()同步测试任务逻辑
模拟 chain/group测试 Canvas 编排
模拟 connection测试 @set_tenant 装饰器
模拟 apply_async测试 Beat 定时任务
为什么不使用 task_always_eager
问题影响
不进行任务序列化无法发现参数类型错误
不与代理交互会掩盖连接问题
执行上下文不同self.request 的行为会有所不同

请改用: 使用 task.apply() 进行同步执行,通过模拟实现隔离。

完整示例: 请参见 assets/api_test.py 中的 TestCeleryTaskLogic、TestCeleryCanvas、TestSetTenantDecorator 和 TestBeatScheduling。


5. 伪造密钥(TruffleHog)

# BAD - TruffleHog flags these:
api_key = "sk-test1234567890T3BlbkFJtest1234567890"

# GOOD - obviously fake:
api_key = "sk-fake-test-key-for-unit-testing-only"

6. 响应状态码

场景代码
GET 成功200
POST 成功201
异步操作(DELETE/触发扫描)202
同步 DELETE204
验证错误400
缺少权限(RBAC)403
RLS 隔离/未找到404

命令

cd api && uv run pytest -x --tb=short
cd api && uv run pytest -k "test_provider"
cd api && uv run pytest api/src/backend/api/tests/test_rbac.py

资源

评论

支持 Markdown