返回

文章详情

Pgtestdb的模板克隆方法进行测试非常快速

Hacker News2026年7月30日 15:49

昨天我被Cup o’ Go提醒了Peter Downs的pgtestdb的存在,这是一个Go/Postgres测试包。pgtestdb是围绕Postgres模板数据库构建的,这是一个内置功能,你可以直接在普通的psql shell中尝试:CREATE DATABASE dbname TEMPLATE template_to_copy; 复制模板的速度非常快,比从零迁移一个测试数据库更快,尤其比一些当前项目使用的重型Docker技术快得多。在低层次上,Postgres枚举模板的关系,并以8 kB页面块的形式复制其物化堆、索引和目录文件。几年前我记得读到过这个功能,但说实话,我已经忘记它的存在了,我很好奇它与其他测试方法的表现如何,因此我让Codex将pgtestdb插入River的测试套件中,以看看它会表现如何。我想认为,River的测试方法在速度和可靠性上或多或少是一个黄金标准。它使用一组自定义的测试助手,根据模式隔离测试用例,这种方法虽然比测试事务慢,但具有一些优势:在测试失败的情况下,保留测试状态以便检查。能够测试全局数据库功能,例如监听/通知。能够测试多个事务交互和回滚的边缘。结果在Postgres中,模式的重量轻于数据库,因此基于模式的方法具有这个优势。然而,你不能克隆一个模式,因此基于模式的方法每次都必须运行迁移,从这一点来看,pgtestdb具有明显优势。这应该会给我们一个有趣的比较。以下是我得到的结果:方法 计数 平均 p90 p95 最大 pgtestdb克隆 466 98.4ms 247.4ms 299.5ms 465.1ms 创建+迁移模式 81 99.4ms 152.1ms 209.0ms 327.0ms 我们发现这两种方法的时机非常相似,都在约100毫秒的设置时间范围内。我一直内化的观点是,涉及创建新数据库的任何事情相对较慢,所以我对pgtestdb方法在这里表现出的速度感到惊讶。考虑到River的现有基于模式的方法已经很快,并且测试模式隔离恰好有助于验证River的基于模式的配置如广告所述有效,我将保留River的测试,但我将建议在我们的文档中提到pgtestdb,特别是对于那些旨在进行端到端测试的用户(即由客户端插入的作业→由工作者完全完成)。通过重用进行优化 我在上面有点低估了。尽管基于模式的方法的设置时间与pgtestdb的完整数据库相似,但整体测试套件的运行速度在前者上快约3.5倍:方法 墙时 pgtestdb克隆 51.07秒 创建+迁移模式 14.54秒 但这并不是因为模式快得多。River的测试助手具有一种有用的优化,即它们将创建尽可能多的测试模式,这取决于Go的瞬时并行化的要求,但在测试用例完成时保持它们池化。如果一个未分配的模式准备就绪,测试用例将清理并重用它,而不是从头生成一个新模式。这说起来容易做到,因为你需要考虑诸如模式版本等细节——即在跨模式版本测试时,每个测试用例必须仅重用它所期望的相同版本的模式。这是非常可行的,当然,但需要一点思考。我在LLM之前编写了River的实现,我花了几天时间将所有bug排除掉。我提到重用是因为它也可以与pgtestdb一起进行,可能作为软件包的一部分,或者作为调用其中的项目的补充。启动测试数据库的100毫秒是相当快的,但如果你正在构建一个将有10,000个测试的完整应用,理想情况下你希望测试设置的速度是10倍快。重用将其降至10-20毫秒,更符合测试事务的时间。

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡