以编程方式将PostgreSQL集群管理为Python测试设备的工具。

van.pg的Python项目详细描述


测试PostgreSQL数据库

为单元测试轻松创建PostgreSQL数据库(和集群)。

脏数据库

创建测试数据库需要很长时间。一般来说你需要 决定删除/重新创建测试数据库fixture时要小心。

而且,在postgresql中似乎没有一种可靠的方法来计算 数据库是否已提交。

所以范佩吉别无选择,只能让你负责通知 当数据库变脏时。如果做得不好,测试隔离将 妥协。这不理想,但我们能做的最好。

一个例外是如果您始终使用transaction包 (http://pypi.python.org/pypi/transaction)来管理数据库提交。在这个 如果您可以要求资源在事务发生时被污染 坚信的。

testresources

集成

使用这些设备的典型方法是通过testresourceshttp://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)自己打包。

< H3>使用现有的数据库

默认情况下,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

发展

在github上进行开发:

http://github.com/jinty/van.pg

更改

2.0(未发布)

  • 支持Python3.2。
  • 放弃Python2.5支持。
  • 添加tox.ini以测试多个python版本。
  • 将postgresql作为子进程而不是守护进程(通过pg_ctl)运行。
  • 重新组织代码以提高重用和测试覆盖率。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
SpringWeb中的java更新/通知其他用户   java Lambda性能测试   java Bukkit插件:空白符号   java在按下按钮后改变彩色正方形的大小   javajavac相当于“D”?   java序列化接口   属性无法从属性文件返回值   java我应该使用什么查询来使用Jsoup从html页面提取符号?   java Android Studio项目结构问题   JAVA方法和返回值/公共变量(基础)   java将NativeQuery映射到POJO   java如何在下面的程序中消除NumberFormatException?   在java中获取链表与数组中的对象   java Android Firebase将用户发送到聊天室