测试Python中的PostgreSQL数据库

21
我不明白如何测试我的存储库。
我想确保我已经将对象及其所有参数保存到数据库中,并且当我执行SQL语句时,我确实收到了我应该得到的结果。
但是,我不能在unittest case的setUp方法中重复创建“CREATE TABLE test_table”,因为它会被创建多次(同一testcase的测试是并行运行的)。因此,只要我在同一类中创建了需要在同一表上工作的2个方法,它就无法正常工作(表名称冲突)。
同样,我也不能在setUpModule中放置“CREATE TABLE test_table”,因为现在该表只被创建一次,但由于测试是并行运行的,没有任何防止将同一对象多次插入我的表中的机制,这会破坏某些字段的唯一性约束。
同样,我也不能在每个方法中使用“CREATE SCHEMA some_random_schema_name”,因为我需要全局“SET search_path TO ...”给定数据库,因此每个并行运行的方法都会受到影响。
我唯一能想到的办法是为每个测试创建“CREATE DATABASE”,并带有唯一名称,并为每个数据库建立单独的连接。这看起来非常浪费资源。有更好的方法吗?
此外,我也不能使用SQLite内存,因为我需要测试PostgreSQL。
1个回答

26

最好的解决方案是使用testing.postgresql模块。它会在用户空间中启动一个数据库,然后在运行结束时将其删除。您可以将以下内容放入unittest套件中-无论是在setUpsetUpClass还是setUpModule中-具体取决于您想要的持久性:

import testing.postgresql

def setUp(self):
    self.postgresql = testing.postgresql.Postgresql(port=7654)
    # Get the url to connect to with psycopg2 or equivalent
    print(self.postgresql.url())

def tearDown(self):
    self.postgresql.stop()

如果您希望数据库在测试之间/之后持久化,可以使用 base_dir 选项运行它以设置一个目录 - 这将防止在关闭后删除它:

name = "testdb"
port = "5678"
path = "/tmp/my_test_db"
testing.postgresql.Postgresql(name=name, port=port, base_dir=path)

除了测试外,它还可以用作上下文管理器,在 with 块退出时会自动清理和关闭:

with testing.postgresql.Postgresql(port=7654) as psql:
    # do something here

我在应用服务器上没有正在运行的 PSQL 服务器 - 我该如何连接到一个 PSQL 服务器,例如使用 JDBC 连接? - viru
3
这个问题主要是关于使用Python测试Postgres数据库,我的答案是关于使用Python设置一个临时的psql服务器。而你的问题涉及使用JDBC连接到Postgres,两者并没有太大关联。我建议你开一个新问题进行提问,而不是在此处添加评论。 - match
1
testing.postgres启动本地postgres服务器 - 你不需要指定任何东西 - 我不确定我理解问题的意思? - match
4
testing.postgres是一个工具,它启动一个临时的postgres服务器。您需要安装postgres,但不需要运行它,因为testing.postgres将处理这部分工作。 - match
2
我仍然在许多项目中每天使用它 - 尽管我还没有查看 GitHub 上的问题,以确定它是否因为已经“完成”或者因为停滞不前而安静下来。 - match
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接