以编程方式将PostgreSQL集群管理为Python测试设备的工具。
van.pg的Python项目详细描述
测试PostgreSQL数据库
为单元测试轻松创建PostgreSQL数据库(和集群)。
脏数据库
创建测试数据库需要很长时间。一般来说你需要 决定删除/重新创建测试数据库fixture时要小心。
而且,在postgresql中似乎没有一种可靠的方法来计算 数据库是否已提交。
所以范佩吉别无选择,只能让你负责通知 当数据库变脏时。如果做得不好,测试隔离将 妥协。这不理想,但我们能做的最好。
一个例外是如果您始终使用transaction包 (http://pypi.python.org/pypi/transaction)来管理数据库提交。在这个 如果您可以要求资源在事务发生时被污染 坚信的。
与testresources
集成使用这些设备的典型方法是通过testresources (http://pypi.python.org/pypi/testresources/):
>>> from testresources import ResourcedTestCase >>> from van.pg import DatabaseManager >>> import psycopg2>>> def init_db(db): ... conn = psycopg2.connect(host=db.host, database=db.database) ... cur = conn.cursor() ... cur.execute("CREATE TABLE foo (bar INTEGER);") ... conn.commit() ... conn.close()>>> class MyTest(ResourcedTestCase): ... ... resources = [('db', DatabaseManager(initialize_sql=init_db))] ... ... def runTest(self): ... conn = psycopg2.connect(host=self.db.host, database=self.db.database) ... cur = conn.cursor() ... cur.execute("INSERT INTO foo VALUES (1);") ... conn.commit() ... cur = conn.cursor() ... cur.execute("SELECT * FROM foo") ... self.assertEqual(cur.fetchall(), [(1, )]) ... # NOTE: must close connections or dropping databases fails ... conn.close() ... self.db.dirtied() # we changed the DB, so it needs re-loading
实际运行测试:
>>> from unittest import TextTestRunner >>> import sys >>> runner = TextTestRunner(stream=sys.stdout) >>> runner.run(MyTest()) # doctest: +ELLIPSIS . ... OK ...
使用模板数据库
如果需要多次重新创建同一个数据库,可以更快地让 PostgreSQL从模板数据库复制数据库。您可以让一个数据库管理器作为另一个数据库管理器的模板:
>>> template_db = DatabaseManager(initialize_sql=init_db) >>> class MyTest2(MyTest): ... resources = [('db', DatabaseManager(template=template_db))]>>> runner.run(MyTest2()) # doctest: +ELLIPSIS . ... OK ...
transaction集成
如果关键字argumendirty_on_commit为true,则数据库管理器将标记 在通过 transaction模块。这意味着每一个污染数据库的测试 必须手动通知它。
>>> man = DatabaseManager(dirty_on_commit=True)
如果使用此功能,则需要依赖于事务 (http://pypi.python.org/pypi/transaction)自己打包。
默认情况下,van.pg在临时目录中创建一个新的postgresql集群 并启动一个postgresql守护进程。这在大多数情况下都有效,但不是很有效 快。
如果您有一个已经运行的postgresql集群,可以告诉van.pg使用 通过设置环境变量van_pg_host。例如,运行 pg对本地postgresql服务器的测试 /tmp/pgcluster do:
$ VAN_PG_HOST=/tmp/pgcluster python setup.py test
警告:目标数据库中任何以test_db开头的数据库都可能 被丢弃。
闭合连接
测试完成后,请小心正确关闭与数据库的所有连接 结束了。PostgreSQL不允许在打开数据库时删除数据库 连接。这将导致van.pg在尝试放弃测试时出错 数据库。
以编程方式创建集群
在较低的级别上,您还可以通过编程方式操作自己的postgresql集群。
初始化群集:
>>> from van.pg import Cluster >>> cluster = Cluster() >>> cluster.initdb()
在临时目录中创建数据库:
>>> import os >>> dbdir = cluster.dbdir >>> 'PG_VERSION' in os.listdir(dbdir) True
启动:
>>> cluster.start()
创建/测试数据库:
>>> dbname = cluster.createdb()
我们可以连接到数据库:
>>> import psycopg2 >>> conn = psycopg2.connect(database=dbname, host=cluster.dbdir) >>> cur = conn.cursor()
旋转数据库以确保我们可以执行基本操作:
>>> cur.execute("CREATE TABLE x (y int)") >>> cur.execute("INSERT INTO x VALUES (1)") >>> conn.commit() >>> cur.execute("SELECT * from x") >>> cur.fetchall()[0][0] 1
停止群集后台程序:
>>> conn.close() >>> cluster.stop()
再次启动:
>>> cluster.start() >>> conn = psycopg2.connect(database=dbname, host=cluster.dbdir) >>> cur = conn.cursor() >>> cur.execute("SELECT * from x") >>> cur.fetchall()[0][0] 1
以及清理:
>>> conn.close() >>> cluster.cleanup() >>> cluster.dbdir is None True >>> os.path.exists(dbdir) False
更改
2.0(未发布)
- 支持Python3.2。
- 放弃Python2.5支持。
- 添加tox.ini以测试多个python版本。
- 将postgresql作为子进程而不是守护进程(通过pg_ctl)运行。
- 重新组织代码以提高重用和测试覆盖率。