
DataHub Notion 连接器集成测试实战基于真实 Notion API 的端到端验证方案【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub本指南以 DataHub 仓库中 Notion 连接器的集成测试套件metadata-ingestion/tests/integration/notion/为核心系统讲解如何在自己的 Notion 工作区中创建真实页面、配置测试凭据、运行与调试六类端到端测试场景并深入解析连接器针对 unstructured-ingest v0.7.2 兼容性问题所应用的一系列 monkeypatch 源码实现。读完本文你将掌握 Notion 连接器集成测试的完整前置准备、运行方式、断言逻辑与故障排查方法同时理解连接器底层对 Notion API 新字段的容错处理机制。一、这套集成测试在测什么DataHub 的 Notion 连接器源码位于 metadata-ingestion/src/datahub/ingestion/source/notion/notion_source.py在摄取 Notion 页面时依赖第三方库 unstructured-ingest 0.7.2 完成页面解析。该库对 Notion API 的建模存在滞后Notion API 陆续返回is_locked、description、list_start_index、list_format、新的 Icon 类型等字段而 unstructured-ingest 0.7.2 的对应模型类并不认识它们直接触发unexpected keyword argument、KeyError或ValueError等异常。由于这些问题只有在真实页面与真实 API 响应下才会暴露mock 无法复现仓库因此在 metadata-ingestion/tests/integration/notion/test_notion_integration.py 中建立了一套调用真实 Notion API、创建真实页面、跑通完整摄取管道的集成测试重点验证四个方面SyncBlock 兼容性—— 摄取包含原始同步块 引用同步块的页面确认不再抛KeyError: childrenNumberedListItem 支持—— 摄取包含编号列表项的页面确认新 API 字段list_start_index、list_format被正确处理凭据验证—— 对缺失的 AWS Bedrock / 无效的 Cohere 凭据给出早期醒目告警同时保证文档仍被摄取非阻塞设计完整摄取—— 一次性摄取所有测试页面验证全部 monkeypatch 协同工作。二、前置条件创建 Notion Integration 与测试父页面集成测试会在你的 Notion 工作区中真实创建页面因此必须先完成两项配置。1. 创建 Notion Integration打开 Notion 的 My integrations 管理页面点击 New integration命名为 DataHub Test Integration或任意名称选择目标工作区启用Read content能力测试需要读取页面与块内容点击Submit完成创建复制Internal Integration Token以secret_开头即后续的NOTION_API_KEY。2. 创建测试父页面在 Notion 中新建一个页面命名为 DataHub Test Pages或任意名称将该页面分享给测试 Integration点击页面右上角...菜单 →Add connections→ 选择你的测试 Integration从 URL 中提取页面 IDURL 格式为https://www.notion.so/Page-Title-{PAGE_ID}其中PAGE_ID是 32 位十六进制字符串带不带连字符均可脚本会自动去除连字符。若页面未与 Integration 分享测试将报 Page not found 或 Unauthorized 错误这是最常见的失败原因。3. 一键式环境配置脚本仓库提供了交互式配置脚本 metadata-ingestion/tests/integration/notion/setup_test_env.sh它会校验NOTION_API_KEY是否以secret_开头校验父页面 ID 是否为 32 位十六进制自动去除连字符可选配置 AWS Bedrock 与 Cohere 凭据最终输出export ...命令或写入权限为 600 的.env.notion_test文件供source使用。三、运行集成测试设置环境变量# Required: Notion API credentials export NOTION_API_KEYsecret_abc123... export NOTION_TEST_PARENT_PAGE_IDabc123def456abc123def456abc123de # Optional: For embedding credential tests export AWS_ACCESS_KEY_IDyour-aws-key # For Bedrock tests export COHERE_API_KEYyour-cohere-key # For Cohere tests除此之外测试文件还支持两个可选环境变量详见 test_notion_integration.py 的模块注释环境变量必填作用NOTION_API_KEY是Notion Integration 的secret_令牌NOTION_TEST_PARENT_PAGE_ID是测试页面的创建位置父页面 IDNOTION_TEST_SYNCED_BLOCKS_PAGE_ID否指定特定页面测试 SyncBlock 摄取用于复现 PR 讨论中的页面设置后test_notion_synced_blocks_ingestion将优先使用它NOTION_TEST_CLEANUP否是否在测试结束后归档测试页面设为false/0/no/disabled/off可保留页面便于查看默认trueAWS_ACCESS_KEY_ID否Bedrock embedding 测试测试中会被主动清除以验证告警COHERE_API_KEY否Cohere embedding 测试测试中会被替换为无效值运行全部 Notion 集成测试在仓库根目录执行cd metadata-ingestion ../gradlew :metadata-ingestion:testQuick -PtestFiletests/integration/notion/test_notion_integration.py或者激活虚拟环境后直接用 pytestpytest tests/integration/notion/test_notion_integration.py -v运行特定测试# 只测试 synced blocks pytest tests/integration/notion/test_notion_integration.py::test_notion_synced_blocks_ingestion -v # 只测试编号列表 pytest tests/integration/notion/test_notion_integration.py::test_notion_numbered_lists_ingestion -v # 只测试凭据告警 pytest tests/integration/notion/test_notion_integration.py::test_notion_bedrock_credential_warning -v无凭据时的自动跳过机制如果NOTION_API_KEY或NOTION_TEST_PARENT_PAGE_ID未设置所有测试会被自动跳过并给出明确提示。该逻辑实现在 conftest.py 的pytest_collection_modifyitems钩子中它检查环境变量若不满足则为所有位于 notion 目录下的用例统一追加pytest.mark.skip标记SKIPPED [7] tests/integration/notion/conftest.py:16: NOTION_API_KEY and NOTION_TEST_PARENT_PAGE_ID environment variables must be set for Notion integration tests这套机制让 CI 在未注入密钥时也能安全地跳过测试而不会失败。四、Test Fixturessession 级页面生命周期管理测试页面由 conftest.py 中的 session 级 fixtures 统一创建整个测试会话只创建一次结束后自动清理。页面组织结构fixtures 会在工作区中建立一个清晰的层级Workspace Parent Page (NOTION_TEST_PARENT_PAGE_ID) └── DataHub Test Root Page (pytest {timestamp}) ├── Test Page - Synced Blocks (Auto-generated by pytest) ├── Test Page - Simple Content (Auto-generated by pytest) └── Test Page - Complex Content (Auto-generated by pytest)核心 Fixtures 一览notion_client—— 使用NOTION_API_KEY实例化的认证 Notion API 客户端notion_workspace_parent_page_id—— 读取NOTION_TEST_PARENT_PAGE_ID作为测试根页面的父级notion_test_root_page—— 创建名为 DataHub Test Root Page 的根页面带时间戳作为所有测试页面的容器test_page_synced_blocks—— 包含原始同步块synced_from: null带子块与引用同步块synced_from: {block_id: ...}无子块的测试页原始块创建后通过blocks.children.list找到其 block ID再用blocks.children.append追加引用块test_page_numbered_lists—— 含三个编号列表项的页面First/Second/Third numbered itemtest_page_complex_content—— 混合多种块类型的页面heading、paragraph、bulleted list、code、带 emoji 图标的 callouttest_page_ids_for_ingestion—— 汇总上述三个测试页面 ID 的列表供完整摄取测试使用。清理机制每个页面 fixture 在 yield 之后都会调用pages.update(page_id..., archivedTrue)将页面归档而非删除。清理行为受should_cleanup_pages()控制conftest.py当NOTION_TEST_CLEANUP为true时自动归档否则保留页面并在终端打印访问链接。归档整个 Test Root Page 会级联归档其所有子页面。若清理失败如网络问题可按以下标题手动归档或删除Test Page - Synced Blocks (Auto-generated by pytest)Test Page - Simple Content (Auto-generated by pytest)Test Page - Complex Content (Auto-generated by pytest)五、六大测试场景详解所有测试都通过 DataHub 的Pipeline.create构造真实摄取管道source 类型为notionsink 为file把产物写入临时 JSON 文件后做断言。下面逐一拆解。1. SyncBlock Monkeypatch ——test_notion_synced_blocks_ingestion管道配置test_notion_integration.pypipeline Pipeline.create( { run_id: test-notion-synced-blocks, source: { type: notion, config: { api_key: api_key, page_ids: [page_id_to_test], recursive: False, advanced: { continue_on_failure: False, raise_on_error: True, }, }, }, sink: {type: file, config: {filename: str(tmp_path / notion_synced_blocks.json)}}, } )该测试的核心断言是摄取不抛KeyError: children并验证日志中出现两处关键信息Applied monkeypatch to SyncBlockmonkeypatch 确实被应用synced blocks compatibility (original reference)同时处理原始块与引用块。测试还会检查输出 JSON 是否包含页面标题与同步块内容ORIGINAL synced block content、Bullet point in synced block。需要说明的是由于 unstructured-ingest v0.7.2 的限制同步块内容可能无法完整提取此时只要摄取过程无异常、monkeypatch 已生效测试仍视为通过。2. NumberedListItem Monkeypatch ——test_notion_numbered_lists_ingestion针对 Notion API 在编号列表项上新增的list_start_index起始序号如从 2 开始与list_formatnumbers/letters/roman字段unstructured-ingest 0.7.2 会因不识别而抛TypeError。测试使用continue_on_failure: True、raise_on_error: False容忍部分失败核心断言是日志出现Applied monkeypatch to NumberedListItem并尽量验证三个列表项文本被摄取。3. 完整摄取 ——test_notion_full_ingestion一次性摄取全部测试页面验证所有 monkeypatch 协同工作。它逐一断言日志中存在test_notion_integration.pyApplied monkeypatch to SyncBlockApplied monkeypatch to NumberedListItemApplied monkeypatch to unstructured-ingest Page classdatabase property classes即 Applied monkeypatch to 22 database property classes4. AWS Bedrock 凭据告警 ——test_notion_bedrock_credential_warning先通过monkeypatch.delenv清除AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_PROFILE再配置embedding.provider: bedrock、model: amazon.titan-embed-text-v1。断言日志出现WARNING: AWS Bedrock embeddings configured but credentials not detected。该告警的生成逻辑位于 notion_source.py当配置了 Bedrock 且环境变量、AWS profile、~/.aws/credentials均不存在时输出一段醒目提示说明文档仍会被摄取但语义搜索不可用。5. Cohere 凭据错误 ——test_notion_cohere_credential_warning配置embedding.provider: cohere、model: embed-english-v3.0、api_key: invalid-key-for-testing故意使用无效凭据从三个维度验证凭据错误检测test_notion_integration.py日志出现EMBEDDING CREDENTIAL ERROR或日志出现EMBEDDING GENERATION FAILED FOR ALL ... DOCUMENTS或NotionSourceReport中num_embedding_failures 0且num_documents_with_embeddings 0。底层逻辑在 notion_source.py捕获 embedding 异常后若错误文本命中authfailure、credentials、unauthorized、invalid_api_key、accessdenied等关键词即判定为凭据错误并以logger.error输出且不记录文档状态保证下次运行修复凭据后会自动重试。6. 连接测试 ——test_notion_test_connection直接调用NotionSource.test_connection(config)断言report.basic_connectivity.capable为真且能力报告中的Page/Database Access项capable为真验证连接器对真实凭据的连接检测与页面访问上报能力。六、monkeypatch 的源码级原理所有 monkeypatch 都在 notion_source.py 中以_monkeypatch_*静态方法的形式实现并统一遵循导入目标类 → 保存原始方法 → 替换为补丁实现 → 日志确认的模式。除测试重点验证的两个外还包括补丁方法解决的问题日志消息_patch_notion_client_for_is_lockedNotion API 2025 年起返回is_locked字段Page 类初始化报错Applied monkeypatch to unstructured-ingest Page class for is_locked field support_monkeypatch_database_property_description数据库属性新增description字段22 个属性类报错Applied monkeypatch to 22 database property classes..._monkeypatch_sync_blocksynced_from为 null 的原始块在列表接口中可能无children触发KeyError引用块需按DuplicateSyncedBlock解析Applied monkeypatch to SyncBlock for synced blocks compatibility (original reference)_monkeypatch_numbered_list_item_new_fields编号列表新增list_start_index、list_format字段Applied monkeypatch to NumberedListItem for new Notion API fields_monkeypatch_icon_dispatcher_unknown_typesNotion 新增内置命名 Icon 类型Icon.from_dict抛ValueErrorApplied monkeypatch to Icon dispatcher for unknown icon types_monkeypatch_notion_types_filter_unknown_fields为所有FromJSONMixin类统一过滤未知 kwargs兜底未来新增字段通用过滤无独立日志其中 SyncBlock 补丁notion_source.py值得细看当synced_from非空时将数据交给DuplicateSyncedBlock.from_dict解析为引用块当其为 null 且无children时首次遇到会通过report.warning记录 Synced Blocks Limitation提示同步块内容会因 v0.7.2 限制而缺失但页面本身照常摄取。对应的统计字段定义在 notion_report.py 的NotionSourceReport中num_documents_with_embeddings、num_embedding_failures、embedding_failures、num_synced_blocks_skipped、synced_blocks_skipped等供测试与运维诊断使用。七、故障排查测试全部被跳过原因环境变量未设置。解决导出NOTION_API_KEY与NOTION_TEST_PARENT_PAGE_ID并确认pytest_collection_modifyitems的跳过条件不再命中。Page not found 或 Unauthorized原因测试父页面未分享给 Integration。解决在页面 ... 菜单 → Add connections 中选择你的测试 Integration并确认 Integration 启用了 Read content 能力。Embedding 测试意外失败原因在预期失败的场景中提供了真实凭据。解决凭据告警类测试刻意使用缺失或无效凭据即使没有真实的 AWS/Cohere 凭据也应通过请勿为这些用例注入真实密钥。Too Many Requests原因Notion API 限流付费 3 req/s免费 1 req/s。解决测试本身只创建极简页面且串行执行若仍触发限流等待数秒后重跑或在 CI 中降低运行频率。八、CI/CD 集成GitHub Actions 示例- name: Run Notion Integration Tests env: NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }} NOTION_TEST_PARENT_PAGE_ID: ${{ secrets.NOTION_TEST_PARENT_PAGE_ID }} run: | cd metadata-ingestion ../gradlew :metadata-ingestion:testQuick -PtestFiletests/integration/notion/test_notion_integration.pyCI 注意事项NOTION_API_KEY必须以 secret 形式存储严禁提交到仓库为 CI 使用独立的 Notion 工作区避免与业务数据混用频繁运行需考虑限流影响未提供凭据时测试会自动跳过因此 CI 不会因缺少密钥而中断。九、手动测试 Synced BlocksNotion API 目前不支持以编程方式创建 synced block因此自动化 fixture 只能构造原始块而引用块依赖原始块 ID 的查找。若要完整覆盖原始 引用场景可手动执行在测试工作区手动创建一个页面添加一个Original synced block并写入内容在页面其他位置或另一个页面引用该同步块将页面分享给测试 Integration把页面 ID 设置到NOTION_TEST_SYNCED_BLOCKS_PAGE_ID环境变量后运行测试。测试将验证原始块与引用块均能被正确摄取。十、深入阅读Notion 连接器源码metadata-ingestion/src/datahub/ingestion/source/notion/notion_source.py连接器配置定义page_ids、database_ids、recursive、embedding等字段metadata-ingestion/src/datahub/ingestion/source/notion/notion_config.py测试报告模型metadata-ingestion/src/datahub/ingestion/source/notion/notion_report.py测试 fixtures 与自动跳过逻辑metadata-ingestion/tests/integration/notion/conftest.py集成测试用例本体metadata-ingestion/tests/integration/notion/test_notion_integration.py交互式环境配置脚本metadata-ingestion/tests/integration/notion/setup_test_env.shNotion API 的字段与限制细节如 synced block 的创建约束、限流阈值可查阅官方开发者文档并结合本套测试的实际运行结果验证连接器行为。【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考