PostHog 营收分析测试数据:Stripe 仿真数据集与可复现 E2E 测试底座 PostHog 营收分析测试数据Stripe 仿真数据集与可复现 E2E 测试底座【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthogPostHog 的 Revenue Analytics营收分析功能依赖 Stripe 数据仓库同步表来计算 MRR 等指标其集成测试需要一个边界条件齐全、预期结果确定的 Stripe 仿真数据集。本文基于products/revenue_analytics/backend/views/test/data/目录的测试数据文档完整解析这 5 张 CSV 仿真的 Stripe 表的设计意图、逐行数据含义以及它们如何通过create_data_warehouse_table_from_csv装配成 ClickHouse 测试表支撑 MRR 视图与 persons/groups join 的端到端断言。读完本文你可以理解这套测试数据为何长这样、每个客户样本各覆盖了哪类边界并能独立复现测试中的预期营收数值。目录定位为集成测试服务的 Stripe 仿真数据该目录下的 5 个 CSV 文件模拟 Stripe 数据仓库表结构被 revenue analytics 的集成测试以及 persons/groups join 测试共同消费。目录清单如下文件对应 Stripe 资源说明stripe_customers.csvCustomer6 个客户3 个国家stripe_subscriptions.csvSubscription每客户 1 个订阅stripe_charges.csvCharge22 笔4 种货币stripe_invoices.csvInvoice20 张全部已支付stripe_products.csvProduct9 个服务型产品structure.py—ClickHouse 列类型定义与示例事件配置README.md—本数据集的设计说明这套数据的核心设计目标不是看起来像真实 Stripe 数据而是让每个客户样本覆盖一种特定的解析或计算路径使测试断言可以精确到某个客户应该算出某笔钱。客户表posthog_person_distinct_id 的解析路径矩阵stripe_customers.csv包含 6 个客户创建于 2023 年 1 月初分布在 US、CA、UK 三个国家国家信息存于address列的 JSON 中。真正的设计亮点在metadata列中的posthog_person_distinct_id字段——它模拟了营收数据向 PostHog Person 关联join时 distinct ID 可能出现的所有情形客户姓名国家posthog_person_distinct_id解析路径cus_1John DoeUSperson_cus_1在 customer 上直接从 customer 解析cus_2Jane DoeUS(无)从订阅sub_2解析cus_3John SmithCA(无)从 chargech_3解析cus_4Jane SmithCA(无)任何地方都没有 distinct IDcus_5John Doe JrUK(无)从 chargech_15解析比订阅sub_5更新cus_6John Doe Jr JrUK(无)任何地方都没有 distinct ID六个样本分别命中customer 直连、subscription 间接、charge 间接、无关联、多来源取最新等分支。特别值得注意的是cus_5它的订阅sub_52025 年 2 月早于 chargech_152025 年 3 月当两个来源都携带posthog_person_distinct_id时解析逻辑应该优先采用更新的 charge 侧取值person_cus_5_from_charge这是一个专门用来验证新鲜度优先规则的反例设计。另外所有客户的metadata中都带有一个遗留的id键如cus_1_metadata它专门服务于元数据 join 场景的测试——README 指明该字段被test_get_revenue_for_schema_source_for_metadata_join用例使用。订阅表时长跨度与 distinct ID 冲突源stripe_subscriptions.csv中每个客户恰好一个订阅status全部为active但时长分为两档前两个约为年付2025-01-23 创建、2026-01-23 到期后四个约为 3 个月2025-02-23 创建、2025-05-23 到期。这种差异会影响 MRR 类查询中当前活跃订阅的窗口判定。订阅客户产品创建到期posthog_person_distinct_idsub_1cus_1prod_12025-01-232026-01-23(无)sub_2cus_2prod_22025-01-232026-01-23person_cus_2sub_3cus_3prod_32025-01-232025-06-23(无)sub_4cus_4prod_42025-02-232025-05-23(无)sub_5cus_5prod_52025-02-232025-05-23person_cus_5_from_subsub_6cus_6prod_62025-02-232025-05-23(无)sub_5上的person_cus_5_from_sub与 charge 表ch_15上的person_cus_5_from_charge构成同一客户的两个 distinct ID 冲突来源是前述新鲜度规则的测试输入。收费表状态、退款与大额异常值stripe_charges.csv共 22 笔 charge横跨 2025 年 1 月至 4 月覆盖 USD、EUR、GBP、JPY 四种货币。按状态分布19 笔 succeeded——正常支付1 笔 failed——ch_5cus_57500 EUR失败原因insufficient_funds同时paid0、amount_captured0、receipt_url为空用于验证失败交易不应计入营收2 笔 pending——ch_11cus_19000 USD无 invoice 关联invoice列为空与ch_18cus_3100 USD。ch_11是pending 且脱离 invoice的双重边界样本ch_22则是 succeeded 但无 invoice 的样本两者验证了营收计算对 invoice 关联缺失的健壮性。退款分两种形态Charge客户形态金额ch_4cus_4全额退款20,000 / 20,000 USDch_6cus_1部分退款2,500 / 12,500 GBPch_12cus_2全额退款22,000 / 22,000 EURCSV 中refunded标志与amount_refunded数值成对出现测试可同时校验布尔标记与部分退款金额两个维度。按客户汇总客户笔数币种总额已退备注cus_16USD, GBP, EUR96,5002,5001 pendingch_11、1 部分退款ch_6、1 无 invoicech_22cus_24EUR, USD, GBP85,00022,0001 全额退款ch_12cus_34GBP, JPY, USD340,10001 笔超大额ch_13334,500 USD、1 pendingch_18cus_44USD, EUR70,00020,0001 全额退款ch_4cus_54EUR, GBP, USD52,50001 笔失败ch_5cus_60—0完全没有 chargecus_6是有订阅、有 invoice 但零 charge的极端样本用于验证该场景下营收只能从 invoice/subscription 侧得出。charge 表上携带posthog_person_distinct_id的只有两笔ch_3cus_3person_cus_32025-01-31与ch_15cus_5person_cus_5_from_charge2025-03-03。发票表订阅关联的边界样本stripe_invoices.csv共 20 张 invoice全部paid且billing_reasonsubscription_cycle自 2025 年 1 月至 5 月每个月的 23 号创建。其中lines列内嵌完整的 Stripe line items JSON含plan、price、subscription_item_details等嵌套结构使测试能够校验对复杂 JSON 列的解析客户发票数关联订阅无订阅关联边界样本cus_13in_1、in_9、in_17均属sub_1—cus_26in_2、in_10、in_18sub_2in_3、in_11、in_19cus_33in_4、in_12、in_20均属sub_3—cus_42in_5、in_13均属sub_4—cus_54in_6、in_14sub_5in_7、in_15cus_62in_8、in_16均属sub_6—cus_2与cus_5的无订阅 invoice 是刻意保留的边界用于测试不绑定周期性计费的 invoice 处理路径。全部 invoice 的 metadata 中均不含posthog_person_distinct_id保证 distinct ID 解析不会从 invoice 侧引入额外来源。产品表预留扩展位stripe_products.csv定义了prod_1至prod_9共 9 个service类型产品active1。其中prod_1–prod_6被订阅表引用prod_7–prod_9处于未使用状态为后续测试预留。structure.py列类型映射与示例事件配置真正让 CSV 文件变成可建表的测试底座的是 structure.py。它做两件事1. 定义 ClickHouse 列类型。每个STRIPE_*_COLUMNS字典通过内部函数_convert_columns把列名 - ClickHouse 基础类型的映射转换为 warehouse source 所需的列结构def _convert_columns(basic_types: dict[str, str]): return { str(key): { hogql: CLICKHOUSE_HOGQL_MAPPING[value].__name__, clickhouse: value, valid: True, } for key, value in basic_types.items() }从源码结构看hogql字段名取自 CLICKHOUSE_HOGQL_MAPPING 中对应类型的映射类名如String、Int64、DateTime各自的 HogQL 类型这保证测试表列类型与真实 Stripe 数据源同步进来的类型一致而不是测试私定的宽松类型。各表列定义要点STRIPE_CHARGE_COLUMNS33 列金额用Int64布尔位paid、captured、disputed、livemode、refunded用Int8时间用DateTime嵌套结构metadata、billing_details等统一为StringJSON 文本STRIPE_CUSTOMER_COLUMNS7 列id、created、name、email、phone、address、metadataSTRIPE_INVOICE_COLUMNS50 列覆盖lines、period_start_at/period_end_at、billing_reason等 MRR 计算直接依赖的字段STRIPE_SUBSCRIPTION_COLUMNS7 列id、customer、plan、created、ended_at、status、metadataSTRIPE_PRODUCT_COLUMNS15 列。2. 定义事件型营收的示例配置。对于基于事件而非 Stripe 表的营收测试模块级常量REVENUE_ANALYTICS_CONFIG_SAMPLE_EVENT提供默认配置REVENUE_ANALYTICS_CONFIG_SAMPLE_EVENT RevenueAnalyticsEventItem( eventNamepurchase, revenuePropertyrevenue, productPropertyproduct, couponPropertycoupon, subscriptionPropertysubscription, subscriptionDropoffDays45, subscriptionDropoffModelast_event, revenueCurrencyPropertyRevenueCurrencyPropertyConfig(propertycurrency), )含义是事件名purchase营收取revenue属性、货币取currency属性订阅流失判定为最后一次事件后 45 天无购买subscriptionDropoffModelast_event。该配置被 test_orchestrator.py 直接赋给team.revenue_analytics_config.events也被 test_mrr_views.py 以model_copy派生出变体配置使用。测试如何消费这份数据从 test_mrr_views.py 的setUp流程可以看到完整装配链路定位数据目录data_dir Path(__file__).parent / data调用create_data_warehouse_table_from_csv来自 products/warehouse_sources/backend/facade/testing.py逐个建表参数依次为 CSV 路径、资源名如stripe_invoice、列定义字典、测试用 warehouse source bucketINVOICES_TEST_BUCKET等与 team返回(table, source, credential, ..., cleanup)五元组后续表复用首张表创建出的source与credential为每张表创建ExternalDataSchema对象should_syncTrue使营收分析能像对待真实 Stripe 同步源一样查询它们测试统一固定查询时间戳QUERY_TIMESTAMP 2025-05-31——这个日期落在数据集设计的时间窗内晚于 4 月的最后一批 charge 与 invoice早于 3 个月期订阅到期保证当前活跃判定稳定。同一套数据也被 persons/groups join 相关的 Stripe 元数据解析测试消费例如 test_stripe_customer_metadata_resolution.py 用同样的create_data_warehouse_table_from_csv装配 subscriptions、invoices、charges 三张表验证posthog_person_distinct_id在 customer/subscription/charge 三个层级的解析优先级。此外目录下的 test_core.py 与__snapshots__快照目录则承担 HogQL 查询结果的快照比对。预期营收数值断言的基准表README 最后给出了每个客户换算到基准货币 GBP 后的预期营收这些数值作为硬断言出现在多个测试文件的test_with_data_group_by_all用例中客户营收 (GBP)出处cus_1517.71test_with_data_group_by_allcus_2222.61test_with_data_group_by_allcus_31,923.37test_with_data_group_by_allcus_4170.96test_with_data_group_by_allcus_51,379.39test_with_data_group_by_allcus_61,337.35test_with_data_group_by_all这几个数字本身就编码了全部边界条件的预期结果cus_1包含部分退款与 pending charge 的扣减cus_2反映全额退款cus_3由 334,500 USD 的超大额 charge 主导cus_4在全额退款后仅剩少量净收入而cus_6在零 charge 的情况下仍有营收——说明该场景下收入来自 invoice/subscription 侧。任何改动 MRR 聚合、退款处理、货币换算或 distinct ID 解析的提交只要破坏上述某一条路径都会让对应客户的断言值偏离基准而立即暴露。小结products/revenue_analytics/backend/views/test/data/是一个数据即规格的测试底座6 个客户样本构成 distinct ID 解析路径矩阵22 笔 charge 覆盖失败/挂起/全额退款/部分退款/无 invoice/超大额等边界20 张 invoice 保留无订阅关联样本structure.py则把 CSV 桥接到与真实 Stripe 源一致的 ClickHouse 类型上。复现验证时只需运行该目录相邻的test_mrr_views.py等测试类依赖仓库的 Django ClickHouse 测试环境即可对照预期营收基准表逐客户核对结果。【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考