创建一个单元测试,检查两个psql架构是否相同

时间:2016-07-10 10:55:24

标签: node.js database postgresql unit-testing

我的这个项目有一个巨大的数据库模式,有时会更新。

所以我有一个名为schema.sql的文件,它有当前模式,还有一个目录,其中包含我随时间推移部署的所有补丁(称为patches/20160710.sql,其中包含一个名为第一个模式的文件origin.sql)。

如果我进行全新安装,我会使用schema.sql,否则我会在更新时应用补丁。

我有测试服务器,我在生产中更新架构之前进行了测试,并且几乎所有内容都自动化了。到目前为止效果很好。

不幸的是,一旦我写了一个不同的东西,请转到schema.sql和补丁。我的单元测试仅针对一个新的数据库运行,因此测试没有失败,我发现错误只是我在测试服务器上尝试了补丁。

我想编写一个单元测试,它需要schema.sql,部署它,并将模式与origin.sql上应用的所有修补程序生成的模式进行比较。

我还需要检查一些表具有相同的值。

数据库是postgresql,软件在node.js。

测试由Gitlab CI运行,带有自定义docker镜像,所以我真的可以用任何语言做更好的测试。

当然,两个补丁和schema.sql都有相同的数据库名称,所以我认为我必须应用schema.sql,以某种方式转储它,然后删除数据库并从补丁中重新创建它,再次转储并比较结果。

这种方法是否有意义,或者有更好的方法来实现我正在做的事情?

如果这有意义,那么转储两个数据库并比较它们的好方法是什么?

1 个答案:

答案 0 :(得分:1)

感谢Abelisto的提示,我制作了一个类似于这个的脚本(我的bash-fu不太好,所以随时可以改进它):

#!/bin/bash
ORIGINAL_DB="tmp1"
INCREMENTAL_DB="tmp2"
SCHEMA="schema"

function clean_up {
  sudo -u postgres dropdb ORIGINAL_DB
  sudo -u postgres dropdb INCREMENTAL_DB
  sudo -u postgres createdb ORIGINAL_DB
  sudo -u postgres createdb INCREMENTAL_DB
}

function import_schemas {
  sudo -u postgres psql ORIGINAL_DB < database/sql/schema.sql

  for f in database/sql/patches/*.sql ; do
    [[ -f "$f" ]] || continue
    sudo -u postgres psql INCREMENTAL_DB < $f
  done
}

function compare_schemas {
  sudo -u postgres pg_dump ORIGINAL_DB --schema=SCHEMA --schema-only > foo1.sql
  sudo -u postgres pg_dump INCREMENTAL_DB --schema=SCHEMA --schema-only > foo2.sql
  line_diff=$(diff foo1.sql foo2.sql | egrep '^<|>' | wc -l)

  if [ $line_diff -ne 0 ]
  then
    diff foo1.sql foo2.sql
    exit -1
  fi
}

function compare_values {
  sudo -u postgres psql ORIGINAL_DB -c "SELECT * FROM roles_permissions ORDER BY idrole, idpermission;" > data1.txt
  sudo -u postgres psql INCREMENTAL_DB -c "SELECT * FROM roles_permissions ORDER BY idrole, idpermission;" > data2.txt

  line_diff=$(diff data1.txt data2.txt | egrep '^<|>' | wc -l)

  if [ $line_diff -ne 0 ]
  then
    exit -1
  fi
}

clean_up
import_schemas
compare_schemas
compare_values

exit 0