Unstract Test Rig 深度指南:用统一测试框架编排跨服务集成与端到端测试

发布时间:2026/9/17 11:44:47

Unstract Test Rig 深度指南:用统一测试框架编排跨服务集成与端到端测试 Unstract Test Rig 深度指南用统一测试框架编排跨服务集成与端到端测试【免费下载链接】unstractLLM-Driven Extraction of Unstructured Data — Built for API Deployments ETL Pipeline Workflows项目地址: https://gitcode.com/GitHub_Trending/un/unstractUnstract 是一个面向 LLM 非结构化数据抽取的开源平台含 API 部署与 ETL 流水线工作流其代码库横跨backendDjango、workersCelery 任务、unstract/sdk1SDK、frontendReact等多个服务。如何在一个仓库里统一编排几百个测试组、同时支撑单测、跨服务集成测试和真实 HTTP 端到端测试答案是仓库根目录tests/下的Unstract test rig——一套以 Python 包形式交付的测试编排框架。本文将以tests/README.md为骨架结合tests/rig/源码、tests/groups.yaml、tests/critical_paths.yaml、tox.ini与.github/workflows/ci-test.yaml完整讲解 rig 的架构、配置、选择机制、三种 E2E 运行模式与关键实践帮助读者在本地、CI 和 monorepo 场景下真正驾驭这套测试体系。一、test rig 是什么仓库测试的组织原则tests/README.md开篇即点明目录定位tests/承载 Unstract 平台的跨服务集成测试 端到端测试以及编排仓库内每一套测试的 rig 本身。其组织原则是单元测试与源码同库共置各服务的单测留在它们所测试的代码旁边例如backend/app/tests/、workers/tests/、unstract/sdk1/tests/只有 e2e 与跨服务集成测试放在tests/下由 rig 统一调度。从源码看rig 是一个标准的 Python 包tests/rig/main.py 通过from tests.rig.cli import main暴露入口核心模块包括模块职责cli.py命令行入口run/list-groups/expand/validate/platform/report等子命令groups.py解析并校验tests/groups.yaml构建依赖图、做拓扑展开selection.py将 CLI 参数 / 文件 / tier / 变更文件解析为最终执行列表runtime.pydocker-compose/testcontainers/local三种平台运行时驱动reporting.pyJUnit 解析与 Markdown 汇总报告coverage.py每组独立的覆盖率数据文件与最终合并critical_paths.py关键路径的缺口gap与回归regression检测目录布局速览tests/ ├── groups.yaml # 唯一事实源组、路径、依赖 ├── critical_paths.yaml # 关键用户/系统流程 声明的覆盖 ├── conftest.py # tests/ 树共享的 pytest markers ├── rig/ # rig 本身Python 包 ├── e2e/ │ ├── conftest.py # platform fixture provisioned_workflow 链 │ ├── smoke/ # 登录 → /health 冒烟 │ ├── workflows/ # 工作流执行 e2emock LLM │ ├── api_deployment/ # API 部署 e2e运行、回调投递、扇出全异步 │ ├── etl/ # ETL 流水线 e2eMinIO 源 目标 │ ├── prompt_studio/ # Prompt Studio 取响应 e2e │ └── hurl/ # 未来基于 hurl 的 HTTP 套件 ├── integration/ # 需要基础设施但不需要完整平台的跨服务测试 ├── fixtures/ # 示例 PDF、JSON、adapter 配置 └── compose/ └── docker-compose.test.yaml # 叠加在 docker/docker-compose.yaml 上的测试层需要说明的是tests/下的顶层 conftest.py 只做一件事注册unit/integration/e2e/critical/slow五个共享 marker并重新导出 e2e fixtures使tests/树内任意测试无需路径体操即可from tests.e2e.fixtures import ...。二、快速开始从一条命令到全量测试rig 的所有入口都封装在 tox 环境里见根目录 tox.ini其设计是把决策留给 rigtox 只做薄转发——tox -e unit实际执行的是python -m tests.rig run --tier unit。# 列出每个已定义的组及其层级与依赖边 tox -e rig -- list-groups # 展示某个选择实际会跑什么展开 depends_on 之后 tox -e rig -- expand e2e-workflow # 并行运行所有单元组带覆盖率 tox -e unit # 运行单个组位置参数 tox -e groups -- unit-sdk1 # 运行多个组依赖会被自动拉入 tox -e groups -- unit-backend e2e-smoke # 运行一切unit integration e2e tox -e groups -- all # 预提交 / 快速迭代读取换行分隔的组名列表 echo unit-backend .test-selection tox -e groups -- --from-file .test-selection --no-coverage --no-parallel # E2E 通道默认 docker-compose本地开发用 testcontainers tox -e e2e -- e2e-smoke UNSTRACT_E2E_RUNTIMEtestcontainers tox -e e2e -- e2e-smokerig CLI 也可以绕过 tox 直接调用python -m tests.rig run --tier unit python -m tests.rig validate python -m tests.rig platform up --runtime compose python -m tests.rig report combine从 tox.ini 的实现细节看unit/integration/e2e三个环境共享同一套基础依赖pyyaml、requests、testcontainers[...]、pytest及其插件而sdk1等旧环境被保留为薄别名指向对应 rig 组保证迁移期间旧 CI 命令不断档。三、groups.yaml测试组定义的唯一事实源groups.yaml 是 rig 的组注册表。每个测试组在此声明rig 在启动时会拒绝存在环依赖、未知depends_on目标或非 optional 组路径缺失的清单。一个最小的新组只需要三行my-new-group: tier: unit # unit | integration | e2e workdir: backend # pytest 的调用目录 paths: [some_app/tests] # 作为 pytest 参数传入可选配置键全表键用途runnerpytest默认、hurl、vitest、playwright。见前端组一节markers转发给 pytest-m如unit and not slowpytest_extra额外的 pytest CLI 标志env为该组 pytest 进程设置的环境变量uv_sync_group在 workdir 中先执行uv sync --group nameinstall_editable在 workdir 中执行uv pip install -e .pip_install运行 pytest 前显式安装的依赖requires_services需要的基础设施postgres、redis、minio等postgres_migrate位于defaults下每次运行只应用一次非组级键{workdir, apps, env}——在任何组运行前对已供给的 Postgres 执行manage.py migrate供那些需要读取其他服务 ORM 所有表的测试使用requires_platforme2e 组设为 true——rig 会拉起完整平台depends_on必须先运行的其他组critical标记该组覆盖一条关键路径timeout_seconds覆盖默认 600soptional双重效果(1) 若路径/workdir 缺失则静默跳过占位组、被 gitignore 的云端专属目录(2)非阻塞——若该组运行但失败红色结果仍会出现在摘要中但不会影响整体退出码。用于 CI 不供给的基础设施如 live-DB connector 测试默认值与环境注入defaults段还定义了共享的后端测试环境backend_test_envYAML anchor包含DJANGO_SETTINGS_MODULE: backend.settings.test、占位密钥、Redis broker 地址、结构工具镜像等凡env: *backend_test_env的组都会继承。从 cli.py 看rig 每次运行还会注入UNSTRACT_RIG_SESSION_ID每次调用唯一到每个组的 pytest 环境让 e2e 测试可以证明平台是 rig 拉起的。四、关键路径注册表承诺不会破坏什么critical_paths.yaml 是 rig 的第二份清单。每条记录代表一个高价值的用户或系统流程含id、entryHTTP 端点或内部跳转和covered_by组列表paths: - id: auth-login description: User can log in and obtain a session cookie. covered_by: [e2e-login] proof: markerrig 将每条路径的状态判定为三种covered已覆盖——covered_by中至少一个组本次构建运行绿灯gap缺口——没有任何覆盖组运行绿灯或covered_by为空regression回归——在缓存的 main 基线中曾为 covered现在不再是。关键路径的proof字段支持两档证明强度见 critical_paths.py 与清单注释group默认——任一覆盖组运行绿灯即视为覆盖。粒度较粗即使覆盖测试被删除也能幸存marker——额外要求本次构建中有 ≥1 个携带pytest.mark.critical_path(id)的测试通过。已在清单中注释说明一旦路径的测试被打上 marker就切换到 marker 档。回归检测的缓存是reports/previous-summary.json默认路径记录的是 main 分支上已覆盖的路径集合。rig 本身没有 PR/main 意识——它只输出标记并尊重--fail-on-critical-gap标志。真正决定何时把缺口当作错误的是 CI 工作流见下文分支策略。五、选择机制positional ∪ file ∪ tier ∪ changedselection.py 实现了选择解析处理顺序是先合并选择源再做依赖展开最后拓扑排序positional GROUPS ∪ --from-file 行 ∪ --tier 过滤 ∪ --changed-only diff几个关键语义字面量all展开为清单中的每一个组空解析结果被视为错误而非运行一切——宁可响亮失败也不意外--tier存在时依赖展开停留在该 tier 内部因为 tier 在 CI 中是分开的腿跨 tier 的depends_on会让同一组在每个腿里重复运行selection.py 的模块注释直接说明了这一点--changed-only运行git diff base...HEAD默认 base 为origin/main选择workdir或paths与变更文件重叠的组适合特性分支上的快速反馈。实现还处理了HEAD origin/main的边界此时 diff 为空自动回退到HEAD~1...HEAD推送 main 事件下的合并提交增量。依赖展开由 groups.py 的GroupManifest.expand()完成它使用 Python 标准库graphlib.TopologicalSorter求拓扑序依赖先于被依赖者。同一文件还实现了几项硬校验_validate_no_cycles——加载时发现依赖环直接报错_validate_dep_targets_exist——depends_on指向未知组直接报错_validate_paths——非 optional 组的 workdir/paths 必须存在_validate_platform_groups_depend_on_gate——每个requires_platform组必须传递地依赖 e2e-smoke 门禁组。这是一个结构不变式它从图结构上保证清单永远不会发布一个绕过 smoke 门禁的平台测试且门禁在拓扑序上最先运行。六、E2E 运行时一套协议、三种模式runtime.py 用统一的PlatformRuntime协议name/up()/down()抽象了三种运行模式由--runtime或UNSTRACT_E2E_RUNTIME选择CI 默认compose其他环境默认testcontainers_default_runtime_name有CI环境变量则选 compose否则 testcontainers。模式适用场景工作机制composeCI测试生产镜像docker compose -f docker/docker-compose.yaml -f tests/compose/docker-compose.test.yaml up -d --wait然后走 HTTP。teardown 清空卷down -v --remove-orphanstestcontainers本地迭代基础设施类组通过 testcontainers 拉起 Postgres/Redis/RabbitMQ/MinIO把句柄暴露在PlatformEndpoints.infra上。当前是桩不会自动以子进程方式启动 backend/prompt-service 等完整的 testcontainers 平台 e2e 需要后续接线。需要完整栈时请先用composelocal执行./run-platform.sh之后假设开发者自己管理的栈只从环境变量读取 URLrig 在每次run调用内只拉起一次平台只要选中的组里有requires_platform: true并通过环境变量UNSTRACT_BACKEND_URL、UNSTRACT_PROMPT_SERVICE_URL等导出 URL。关键细节rig 使用env.setdefault(...)所以预先设置的值来自localruntime 或开发者覆盖优先于 runtime 默认值——这方便针对自定义栈迭代但也意味着陈旧的 shell 环境可能掩盖接线 bug。冒烟测试会断言 fixture 的 URL 与环境变量一致专门用来抓这个问题。TestcontainersRuntime 的实现细节值得注意Postgres 用的是pgvector/pgvector:pg15向量扩展契合 Unstract 的检索场景Redisredis:7.2.3、RabbitMQrabbitmq:3.13-management、MinIOminio/minio:latestup()中途失败会调用down()清理半成品栈InfraEndpoints的__post_init__还强制 host/port 成对出现防止部分规格静默落到下游配置。平台就绪探测_wait_ready轮询四个健康目标runtime.pybackend 的/health、platform-service 的/health、x2text 的/api/v1/x2text/health以及frontend 的/nginx 静态 SPA 没有 health 端点index.html 返回 200 就是存活信号。runner 被刻意排除——容器化执行正在被 worker 内执行取代e2e 不应依赖它在线。平台级 pytest fixturestests/e2e/conftest.py 定义了会话级platformfixture如果UNSTRACT_BACKEND_URL未设置就pytest.skip提示用 rig 运行或自行导出变量否则从环境构建PlatformEndpoints。authed_session提供已登录会话登录流程通过UNSTRACT_E2E_LOGIN_PROVIDER可插拔——未设置时走 OSS 表单登录form POST/api/v1/login302 sessionid然后 org 握手下游仓库如带 Auth0 的云端版可以把它指向自己的module.func。CsrfSession统一在 POST/PUT/PATCH/DELETE 上自动盖上X-CSRFToken。e2e 测试若脱离 rig 在其他地方运行会带着清晰的提示信息直接跳过。七、Hermetic LLM让 e2e 永远不碰真实提供商执行路径上的 e2e 测试绝不能调用真实 LLM 提供商因此 rig 在启动平台前设置UNSTRACT_LLM_MOCK_RESPONSE默认值MOCK_LLM_OK任何 runtime 都生效且把导出的空字符串视为未设置。测试 overlay 会把它转发给 worker见 docker-compose.test.yaml 的worker-executor-v2与worker-file-processing-v2unstract.sdk1.llm将其作为mock_response传给 litellm非流式补全路径下litellm 原样返回该字符串并带固定用量10 prompt / 20 completion / 30 total因此回答和 token 数都可精确断言流式stream_complete走的是 litellm 的另一条路径用量不同不要假设那里也是 10/20/30哨兵值如litellm.RateLimitError可强制错误路径未设置生产默认时该钩子是无操作。值得强调的工程决策是否设置该变量是唯一的开关。README 记录了曾经的教训——曾尝试增加ENVIRONMENT双门禁但发现它防不住设计要防的场景从 overlay 复制出来的 worker env 块总是同时携带两个变量而 compose 又给每个服务都声明了ENVIRONMENT导致任何派生的部署都满足门禁。最终该变量连同门禁被一起删除。剩下的保证是没人设置它舱门就是关的活跃时每个进程警告一次。让伪造的消费可被检测而非试图阻止该配置——用法记录本身就应该标明它是 mock 的。CI/本地覆盖优先rig 只填充未设置的值。在 rig 下运行这些测试变量缺失会直接失败脱离 rig 运行则只是跳过执行路径测试——若自己手动启动栈请在 shell 和 worker 两侧都导出它。两个已知边界README 明确列出LLM adapter 的 test-connection 无法通过 mock它会针对某个特定城市做补全的正则匹配MOCK_LLM_OK无法满足——所以adapter-register-llm暂时是 e2e 缺口只 mock LLM 补全不 mock embeddingprovisioned_workflow固定chunk_size0索引路径永远不会触发litellm.embedding。需要分块的测试必须连 embedding 路径一起 mock。八、扇出fan-outMAX_PARALLEL_FILE_BATCHES与一个诚实的开放缺口多文件工作流执行会按文件数切分批次并行处理rig 通过MAX_PARALLEL_FILE_BATCHES控制扇出默认值是1意味着多文件运行的所有文件落在一个批次、串行处理——那样扇出测试在没有任何扇出发生的情况下也会通过测试 overlay 在backend上把它默认设为3这通常才是生效的值worker 会向 backend 询问该值只有联系不上 backend 或拿不到值时才会回退到自己的环境变量overlay 也在worker-api-deployment-v2上设置了它让回退保持一致批次数为min(MAX_PARALLEL_FILE_BATCHES, num_files)所以 N 个文件配 N 的阈值每个文件恰好一个批次。但 README 直白地承认扇出的另一半是开放缺口critical_paths.yaml中的workflow-execution-fan-outcovered_by: []而且补上它需要产品变更而非更聪明的测试。原因很硬核没有任何地方持久化 batch 或 task id——批次索引只是被丢弃的循环局部变量celery task id 只出现在 worker 标准输出里每文件耗时是唯一代理指标但时序在这里不成立CI 上实测三个文件真正扇出后完成时间更分散6.6 / 18.1 / 22.9比共享批次时的 ~2s 步进更宽——三个并发工具容器在繁忙 runner 上的争用开销超过了重叠收益行窗口的重叠也无法区分串行批次会在一次调用里预先创建全部行天然重叠正确的解法是在WorkflowFileExecution上落一个批次或任务标识符——测试断言 N 个文件有 N 个不同 id无时序、无停顿。这也是普通的执行可观测性这正是应在产品里做而非测试里做的理由。e2e-api-deployment目前仍然断言重组rejoin半侧每文件一条结果、所有文件计入successful_files、每文件一行。九、ETL e2eMinIO 源与目标tests/e2e/etl运行一条从源 connector 到目标 connector 的流水线。MinIO 是 compose 栈既启动又注册的唯一存储 connector——本地文件系统 connector 不需要基础设施但从未被注册local_storage/没有__init__.pyregister_connectors会跳过它这正是挂载的./workflow_data:/data卷不能作为 ETL 端点的原因。测试通过发布端口UNSTRACT_MINIO_ENDPOINT默认localhost:9000读写对象而 worker 通过 compose 网络访问同一存储UNSTRACT_MINIO_INTERNAL_URL默认http://unstract-minio:9000。当没有 MinIO 应答时测试跳过因此不会让未发布该端口的 runtime 失败。十、报告每次 run 之后留下什么每次run后rig 在reports/写入reports/ ├── summary.md # 人类可读用于 PR sticky 评论 ├── summary.json # 机器可读 ├── combined-test-report.md # 向后兼容别名 ├── coverage.xml # Cobertura带 --coverage 时 ├── htmlcov/ # 可浏览的覆盖率带 --coverage 时 └── group-name/ ├── junit.xml # pytest --junitxml ├── report.md # pytest-md-report 输出 └── exit.txt # 组 pytest 退出码reports/summary.md有两个部分按组结果表passed/failed/errors/skipped/duration关键路径细分为❌ 回归必须为零、⚠️ 尚未覆盖的关键路径缺口积压、✅ 已覆盖的关键路径折叠。CI 把整个reports/作为 artifact 上传并把combined-test-report.md作为 sticky PR 评论发布ci-test.yaml 的reportjob用marocchino/sticky-pull-request-comment。报告聚合的细节同样值得学习所有 e2e 组vitest/playwright 例外都产出真实 JUnitparse_junit能像 pytest 组一样报告逐测试计数hurl 组只有一条合成行。被依赖失败的组会被阻塞cli.py 会为它合成一个带rig-blocked-by属性的 junit让rig report从 junit 重建结果时渲染出 ⏭️ 阻塞行而不是丢掉该组。十一、覆盖率关键路径覆盖优先不追 100%覆盖率默认开启可用--no-coverage关闭预提交和快速本地运行通常关掉。实现要点coverage.py每个组使用独立的COVERAGE_FILEreports/.coverage.group并行 pytest 调用互不踩踏所有组完成后rig 执行coverage combinecoverage xmlcoverage html跨 tier 合并有讲究coverage combine会消费输入文件直接把上一 tier 的.coverage改名成带后缀的.coverage.__prior__再作为输入喂回去——因为combine只拾取带后缀的数据文件裸.coverage是输出目标覆盖率子进程有 300s 超时失败只记日志不抛异常——覆盖率是尽力而为的报告不能拖垮测试的退出码。团队立场README 原话不追逐 100% 覆盖率。标杆是关键路径覆盖rig 的职责是让缺口和回归可见而不是强制一个数字。十二、分支策略rig 无分支意识门禁在 CIrig 自身没有任何分支感知。分支行为在 GitHub Actions 中实施main 上每个 tier 在自己的 step 中运行tox -e unit→tox -e integration→ 慢速通道的tox -e e2e每次调用都带--fail-on-critical-gap --update-baseline。rig 把已覆盖路径合并而非覆盖进previous-summary.json使第二个 tier 的运行保留第一个 tier 的覆盖记录PR 上同样的分 tier steps 运行但不带--fail-on-critical-gap——缺口可见但不阻塞e2e 工作流只在main push、打了run-e2e标签的 PR、nightly cron、手动 dispatch 时运行。在 ci-test.yaml 中可以看到这套策略的完整落地testjob 用矩阵并行跑unit/integration两个腿fail-fast: false一个腿失败不取消另一个e2e 单独一个 job 先构建镜像再跑reportjob 需要所有三个腿的结果把每个 tier 的 junit 合并成一次关键路径评估e2e 覆盖如 auth-login 会出现在 unit/integration 旁边且是基线的唯一读写者。基线缓存在 main 上以 run id 为 key 保存下次构建用restore-keys前缀取最新。--update-baseline只在main 且全绿时传——PR 不能写 main 的基线红构建也不能写部分基线。开发者本地可以用位置参数、--from-file .test-selection、--tier或--changed-only任意裁剪作用域。十三、添加测试放哪里、怎么接放哪里测试类型backend/app/tests/、workers/tests/、unstract/lib/tests/等该服务的单元测试tests/integration/area/需要真实基础设施但不需要完整平台的跨服务测试tests/e2e/flow/针对运行中平台的 HTTP 级测试tests/e2e/hurl/基于 hurl 的 HTTP 套件Backend无需注册README 给出了一条零配置路径在backend/app/tests/test_name.py写普通测试。文件名必须匹配test_*.py、*_test.py、*_tests.py或 Django 的每 apptests.py——其他名字会被静默忽略。优先test_*.py保持一致tier 是推断的不是声明的触碰数据库的测试继承 DjangoTestCase/APITestCase或使用pytest.mark.django_db会被backend/conftest.py自动标记为integration并在integration-backend组中对着 rig 供给的 Postgres/Redis 运行其余一切进入unit-backend。无需 marker、无需改groups.yaml不要 mock 环境rig 在一个 pytest 会话里完整加载 Django 跑整个 backend 树——patchsys.modules、假设导入顺序、假设单独运行的测试都会在收集时炸掉。用unittest.mock.patch打真实模块只 mock 真正的外部依赖LLM SDK、第三方 API绝不 mock ORM 或 serializer每个测试在setUp里通过 ORM 播种数据。schema 来自 migrations每个会话跑一次每个测试的写入自动回滚需要 CI 没有的凭据外部 DB/SaaS在setUp里用self.skipTest(CRED_VAR not set)守卫——CI 里跳过本地导出环境变量后照常运行。本地运行与查看tox -e groups -- unit-backend --no-coverage # 纯测试 tox -e groups -- integration-backend --no-coverage # DB 测试需要 Docker # 列出某个组会跑什么不需要 DB cd backend uv run --group test pytest . -m integration --collect-only -q其他服务 / 新领域backend 之外marker 是手动的workers强制--strict-markers。要么复用 paths 已覆盖你文件的现有组要么在groups.yaml里加组相关时把它写进critical_paths.yaml某条目的covered_by。推送前用python -m tests.rig validate校验——它同时会跑配置隔离守卫见下。配置隔离守卫一个值得了解的坑cli.py 的_config_isolation_error检查一个隐蔽问题cd workdir pytest paths并不把配置钉死在 workdir——pytest 会从路径参数公共祖先向上搜索配置文件。嵌套项目若没有自己的配置会继承父项目的addoptscoverage 目标、--strict-config导致与测试本身无关的失败。因此 rig 在validate时拒绝会继承别的项目配置的组允许继承仓库根配置——这是正常 monorepo 情形报错信息会给出修复建议在 workdir 加[tool.pytest.ini_options]或建空pytest.ini。README 之外的实现细节是pytest 命令通过uv run --with ...注入 rig 的 pytest 插件pytest-md-report、pytest-xdist、pytest-cov等见 cli.py保证插件在uv run的 venv 重同步后依然存活。十四、前端组vitest 与 Playwright 的接入两个组跑 Node 套件而非 pytest组tierrunner覆盖内容frontendunitvitestjsdom 上的 Vitest React Testing Library——antd→shadcn shims 及其之上的组件。workdir 为frontenduie2eplaywright针对真实 UI 的浏览器 e2e。specs 在tests/e2e/ui/与其他 e2e 套件并排python -m tests.rig run frontend # 整个 vitest 套件 python -m tests.rig run ui # 启动平台然后 playwright cd frontend npm test # 原样保留rig 是增量式的 cd tests/e2e/ui npm install # 一次性playwright/test cd tests/e2e/ui npx playwright install chromiumtests/e2e/ui是自包含的——specs、playwright.config.js和它自己的node_modules都在目录里解析时不碰frontend/。两者都产出真实 JUnit因此parse_junit能像 pytest 组一样报告逐测试计数hurl 只有一条合成行。Vitest 用--outputFilePlaywright 读PLAYWRIGHT_JUNIT_OUTPUT_NAMErig 导出它这就是配置读取它的原因。两者都是optional刻意为之它们通过npx --no-install调外部命令机器/CI 镜像没有node_modules或没有浏览器二进制时跳过而非让构建失败。npx完全缺失时 runner 返回退出码 5——rig 的nothing collected约定。如果 Node runner 在 reporter flush 之前挂掉rig 会回填一个合成 junit让失败仍出现在摘要里而不是变成缺失组。ui组的认证模式ui套件针对两种部署运行UNSTRACT_AUTH_MODE选择流程或自动探测模式流程ossDjango mock 登录form POST/api/v1/login然后是 org 握手。与tests/e2e/conftest.py::authed_session镜像改那个流程会同时破坏两套套件auth0企业版。IdP 掌握凭据交换浏览器驱动托管登录表单应用完成自己的回调auto默认先试 OSSbackend 登录 302 但/api/v1/organization401 就是云认证回退到auth0凭据来自UNSTRACT_ADMIN_USER/UNSTRACT_ADMIN_PASSWORD或UNSTRACT_AUTH0_*对。认证不成功时 specs跳过而非失败与该组的optional标志一致。README 还解释了ui组存在的理由值得引用jsdom 不计算布局所以溢出、定位和视觉状态在frontend组里不可观察。shadcn 迁移期间发现的每个 UI 缺陷——toggle 渲染空白、nav 箭头锚错月份、过滤行在日期范围上破版——都是人肉在浏览器里抓到的不是单测抓到的。这就是ui组要补的洞。十五、常用命令速查表# 发现 python -m tests.rig list-groups python -m tests.rig list-critical-paths python -m tests.rig expand e2e-workflow python -m tests.rig validate # 运行 tox -e unit # 所有 unit 组 tox -e e2e -- e2e-smoke # 单个 e2e 组 tox -e groups -- unit-backend unit-workers # 多个组 tox -e groups -- --from-file .test-selection # opt-in 文件 tox -e groups -- --changed-only # 对比 origin/main 的 diff tox -e groups -- all --no-coverage # 一切快跑 # 平台控制手动 python -m tests.rig platform up --runtime compose python -m tests.rig platform down # 重新聚合已有报告 python -m tests.rig report combine十六、小结从编排框架到工程文化的沉淀通读tests/README.md与tests/rig/源码能看到 Unstract test rig 不是简单的脚本合集而是一套有明确取舍哲学的测试基础设施单元测试与源码共置、tier 自动推断、依赖图拓扑展开、smoke 门禁的结构化强制、Hermetic LLM 防真实调用、关键路径缺口与回归的显式记账以及不追 100% 覆盖率、只守关键路径的清醒边界。对 monorepo 型开源项目而言tests/rig/本身就是一份可复用的设计样本——读者可以直接把其中的组清单模型、选择机制与关键路径评估思路迁移到自己的多服务仓库中。【免费下载链接】unstractLLM-Driven Extraction of Unstructured Data — Built for API Deployments ETL Pipeline Workflows项目地址: https://gitcode.com/GitHub_Trending/un/unstract创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/17 11:44:47

Windows 10 安装 HBase 实用指南:Docker 方案保姆级落地

1. 为什么在 Windows 10 上装 HBase 是个“反常识”操作? HBase 是 Apache 旗下典型的 JVM 生态原生分布式数据库 ,它的设计哲学从根上就长在 Linux 的土壤里:依赖 POSIX 文件系统语义、依靠 shell 脚本协调进程、默认绑定 ZooKeeper 集群…

2026/9/17 11:39:45

SQLyog连MySQL 8报错2058?认证插件不兼容的排查与解决指南

讲真,SQLyog连MySQL 8报“错误号码2058”这个坑,我前前后后踩了不止一次。每次换电脑、重装环境,只要是从MySQL 5.7升到8.0,十有八九就会在图形客户端这一环翻车。更恼火的是,报错信息就一行,中文环境下写着…

2026/9/17 12:54:52

CCD图像传感器原理与应用:从MOS电容到工业巡线

简介:这是一份关于CCD图像传感器的专业课件PPT教案,面向学习光电成像、微电子或相关课程的高校师生,以及初次接触图像传感器的技术人员。资源共1个pptx文件,压缩包大小725KB,已有80人学习。课件共43页,系统…

2026/9/17 12:54:52

STM32开发转向VS Code:解耦工具链实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 12:49:52

离散数学证明题的逻辑链重构与公理调用训练

简介:本资源是面向高校计算机、数学及相关专业学生的离散数学证明题专项训练材料,聚焦逻辑学、集合论、关系论、群论与函数论五大核心模块的典型证明题型,帮助学习者突破抽象推理难点、掌握严谨证明方法。文档为单个Word文件(.doc…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码