如何与NodeJS、Jest和Knex并行运行Postgres测试



我有一个项目是在生产/阶段使用Postgres和在开发中使用Sqlite开发的。使用Sqlite,我们能够在13秒内并行运行所有测试。

对于最初的开发来说,这是一个很好的策略,但有些事情Sqlite做不到,我们需要(例如,删除列和添加新的外键)。所以我认为我们应该放弃Sqlite,只使用Postgres。

测试套件运行大约需要一分钟的时间,如果测试失败,我通常必须手动删除迁移表。它不能提供良好的测试体验。

对于使用NodeJS、Knex和Jest在Postgres数据库上并行运行测试,您有什么建议吗

在每次测试之前运行迁移并回滚迁移非常缓慢,甚至可能需要几秒钟的时间才能运行。因此,您可能不需要能够并行运行测试来达到足够好的速度。

如果您设置测试的方式是,在开始运行测试之前只删除/创建/迁移一次,而在测试之间只截断表中的所有数据并用新数据填充,则速度应该快10倍(截断时间通常不到50ms)。您可以很容易地截断所有的表,例如使用knex-db-manager包。

如果您真的喜欢并行运行postgresql测试,那么您需要与运行并行测试一样多的测试数据库。您可以创建测试数据库的"池"(testdb-1、testdb-2、testdb-3…),在每个玩笑测试中,您首先必须从测试数据库池中请求数据库,这样您就可以真正同时运行多个测试,并且它们不会干扰同一个数据库。

最后,在测试数据库中重置数据的一种更快速的方法是使用pg-dump/pg-restore和二进制数据库转储。在某些情况下,它可能比运行填充脚本更快或更容易处理。尤其是在每次测试中使用相同初始数据的情况下。

通过这种方式,您可以在开始运行测试之前为测试数据库创建初始状态,并对其进行转储。为了转储和还原,我编写了这些小助手,我可能会在某个时候将其添加到knex-db-manager中。

转储/恢复的参数有点棘手(特别是设置密码),所以这些片段可能会有所帮助:

倾倒:

shelljs.env.PGPASSWORD = config.knex.connection.password;
const leCommand = [
`pg_dump -a -O -x -F c`,
`-f '${dumpFileName}'`,
`-d ${config.knex.connection.database}`,
`-h ${config.knex.connection.host}`,
`-p ${config.knex.connection.port}`,
`-U ${config.knex.connection.user}`,
].join(' ');
console.log('>>>>>>>> Command started:', leCommand);
shelljs.rm('-f', dumpFileName);
shelljs.exec(leCommand, (code, stdout, stderr) => {
console.log('======= Command ready:', leCommand, 'with exit code:', code);
if (code === 0) {
console.log('dump ready:', stdout);
} else {
console.log('dump failed:', stderr);
}
});

恢复:

shelljs.env.PGPASSWORD = config.knex.connection.password;
const leCommand = [
`pg_restore -a -O -x -F c`,
`-d ${config.knex.connection.database}`,
`-h ${config.knex.connection.host}`,
`-p ${config.knex.connection.port}`,
`-U ${config.knex.connection.user}`,
`--disable-triggers`,
`'${dumpFileName}'`,
].join(' ');
console.log('>>>>>>>> Command started:', leCommand);
shelljs.exec(leCommand, (code, stdout, stderr) => {
console.log('======= Command ready:', leCommand, 'with exit code:', code);
if (code === 0) {
console.log('restore ready:', stdout);
} else {
console.log('restore failed:', stderr);
}
});

相关内容

  • 没有找到相关文章

最新更新