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

用户名

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

对于最初的开发来说,这是一个不错的策略,但是Sqlite不能满足我们某些需求(例如删除列并添加新的外键)。因此,我认为我们应该删除Sqlite并仅使用Postgres。

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

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

米凯尔·莱皮斯托

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

如果以开始运行测试之前删除/创建/迁移一次的方式来设置测试,并且在测试之间进行测试,则只需截断表中的所有数据并用新数据填充它,它的速度应该快10倍(截断所需的时间通常少于50ms)。您可以轻松截断所有表,例如使用knex-db-managerpackage。

如果您真的想并行运行postgresql测试,则需要与运行并行测试一样多的测试数据库。您可以创建测试数据库的“池”(testdb-1,testdb-2,testdb-3等),并且在每个笑话测试中,首先必须从测试数据库池中请求数据库,以便您可以真正运行多个测试同时,他们不会干扰相同的数据库。

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

这样,您可以在开始运行测试并将其转储之前为测试数据库创建初始状态。为了进行转储和还原,我编写了这些小助手,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);
    }
  });

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章