跳转到主要内容

用于测试目的创建和删除临时数据库。

项目描述

用于测试目的创建和删除临时数据库。

此软件包已在Python 3.8、3.9、3.10和3.11上进行了测试。

版权(c)2008-2015,2020-2021 gocept gmbh & co. kg及贡献者。

版权所有。

本软件受Zope公共许可(ZPL)2.1条款约束。ZPL的副本应随本分发一起提供。本软件按“现状”提供,并放弃任何和所有明示或暗示的保证,包括但不限于标题保证、适销性保证、不侵犯保证和针对特定目的的适用性保证。

gocept.testdb 提供了一些小助手类,用于创建和删除临时数据库。

>>> import gocept.testdb
>>> import os.path
>>> import shutil
>>> import sqlalchemy
>>> import tempfile
>>> sql_dir = tempfile.mkdtemp()
>>> schema = os.path.join(sql_dir, 'sample.sql')
>>> with open(schema, 'w') as f:
...     _ = f.write('CREATE TABLE foo (dummy int);')

在本测试过程中,每当创建具有固定名称的数据库时,我们都会使用特定于当前进程的自定义前缀,以便允许在同一台机器上(如CI服务器)并发运行测试。

>>> import os
>>> pid_prefix = 'gocept.testdb.tests-PID%s-' % os.getpid()
>>> db_template = pid_prefix + 'templatetest'

MySQL

gocept.testdb 预期使用 PyMySQL 作为数据库驱动程序。

首先,实例化一个测试数据库对象,并在服务器上创建数据库。您可以指定数据库名称或前缀。

>>> gocept.testdb.MySQL(schema_path=schema, db_name='mytestdb').dsn
'mysql+pymysql://.../mytestdb'
>>> db = gocept.testdb.MySQL(schema_path=schema, prefix='my-tests')
>>> db.dsn
'mysql+pymysql://.../my-tests-...'
>>> db.create()

这将使用适当的命令行工具创建一个具有随机名称的数据库。

您可以使用以下环境变量来定制DSN

MYSQL_HOST

主机名,默认为 localhost

MYSQL_PORT

数据库端口,默认为未设置时使用套接字

MYSQL_USER

用户名,默认为 None,表示使用登录操作系统的用户名。

MYSQL_PASS

密码,默认为 None,表示不需要密码。

MYSQL_COMMAND_POSTFIX

将此后缀附加到MySQL命令上,默认为空字符串。如果您使用的是像 mysql5 而不是 mysql 这样的命令名称,则需要此变量。

然后可以使用dbapi DSN连接到数据库

>>> engine = sqlalchemy.create_engine(db.dsn)

通过在数据库中创建名为 tmp_functest 的表来将该数据库标记为测试数据库

>>> with engine.connect() as conn:
...     with conn.begin():
...         ignore = conn.execute(sqlalchemy.text('SELECT * from tmp_functest'))

数据库对象还提供了方便的方法来检查数据库的状态

>>> db.exists
True
>>> db.is_testing
True

如果您将 schema_path 传递给构造函数,则执行该文件中的SQL代码,例如设置表

>>> with engine.connect() as conn:
...     with conn.begin():
...         ignore = conn.execute(sqlalchemy.text('SELECT * from foo'))

完成操作后,只需简单地删除数据库

>>> engine.dispose()
>>> db.drop()

PostgreSQL

通用

相同的程序也适用于PostgreSQL。您可以使用以下环境变量来定制DSN

POSTGRES_HOST

主机名,默认为 localhost

POSTGRES_PORT

数据库服务器端口,未设置时使用5432

POSTGRES_USER

用户名,默认为 None,表示使用登录操作系统的用户名。

POSTGRES_PASS

密码,默认为 None,表示不需要密码。 注意: 不使用 POSTGRES_PASS,而是使用由 ~/.pgpass 提供的机制 由postgres自身提供

>>> db = gocept.testdb.PostgreSQL(schema_path=schema)
>>> db.create()
>>> engine = sqlalchemy.create_engine(db.dsn)
>>> conn = engine.connect()
>>> ignore = conn.execute(sqlalchemy.text('SELECT * from tmp_functest'))
>>> ignore = conn.execute(sqlalchemy.text('SELECT * from foo'))
>>> conn.invalidate()
>>> db.drop()

编码

对于PostgreSQL,可以在构造函数中指定可选的编码、数据库名称和数据库名称前缀参数。它们在创建数据库时使用。

>>> gocept.testdb.PostgreSQL(encoding='UTF8', db_name='mytestdb').dsn
'postgresql://...localhost.../mytestdb'
>>> gocept.testdb.PostgreSQL(prefix='my-tests').dsn
'postgresql://...localhost.../my-tests-...'

模板

对于PostgreSQL,可以将可选的模板参数传递给构造函数。它指定用于创建测试数据库的模板数据库的名称。如果模板数据库不存在,则使用指定的模式创建它。

第一次使用 db_template 参数创建数据库时,如果模板数据库不存在,则会创建模板数据库和所需的数据库。

>>> db = gocept.testdb.PostgreSQL(schema_path=schema, db_template=db_template)

现在有了模板,就不再使用模式来创建数据库(它是从模板数据库中复制的)。

但是,在创建数据库时,我们可以强制重新从模式创建模板数据库。这样做现在将根据修改后的模式给我们留下测试数据库和模板数据库。

>>> db = gocept.testdb.PostgreSQL(
...     schema_path=schema, db_template=db_template, force_template=True)

如果模式文件比现有的模板数据库新,则模板数据库(以及测试数据库)也将重新创建。

然而,如果无法正确设置模板数据库,则将其完全删除,以避免损坏的模板数据库干扰后续测试。

drop-all 命令行脚本

数据库类的 drop_all 功能可以通过名为 drop-all 的命令行脚本来独立使用。该脚本会删除与通过命令行参数传入的前缀匹配的任何测试数据库,无论它们是在 PostgreSQL 还是 MySQL 服务器上。使用方法:

$ bin/drop-all "<prefix>"

测试清理

>>> shutil.rmtree(sql_dir)

开发

要运行此包的 buildout,请将 local.cfg.example 复制到 local.cfg 并根据需要编辑它。

  • 如果您的 MySQL 命令看起来像 mysql5 而不是 mysql,则需要 MYSQL_COMMAND_POSTFIX

  • MySQL 必须为测试打开一个端口。您需要在您的 my.cnf 中配置此端口。

运行测试

安装 tox 并运行测试,调用 tox

使用 docker 容器进行测试

先决条件

  • mysqladminmysql 必须在 $PATH 上。

  • createdb 必须在 $PATH 上。

  • 运行以下命令(您可能需要更改使用的密码)

    docker run --name mysql56 -e MYSQL_ROOT_PASSWORD=84_L224JF0GlTXcL -d -p 3307:3306 mysql:5.6
    docker run --name postgres96 -e POSTGRES_PASSWORD=j§V7iJY@1xTG67J@ -d -p 5433:5432 postgres:9.6
    echo "localhost:5433:*:postgres:j§V7iJY@1xTG67J@" >> ~/.pgpass
    chmod 600 ~/.pgpass

运行测试

  • MYSQL_PORT=3307 MYSQL_USER=root MYSQL_PASS=84_L224JF0GlTXcL POSTGRES_PORT=5433 POSTGRES_USER=postgres tox

源代码

源代码可在 https://github.com/gocept/gocept.testdb 找到

错误报告

请将您发现的任何错误报告到 https://github.com/gocept/gocept.testdb/issues

变更日志

6.0 (2023-08-28)

向后不兼容的更改

  • 删除对 Python 2.7、3.6 的支持。

  • 删除对 SQLAlchemy < 1.2 的支持。

功能

  • 添加对 Python 3.10、3.11 的支持。

  • 添加对 SQLAlchemy 2.x 的支持。

5.2.1 (2023-03-16)

  • 限制支持的 SQLAlchemy 为 < 2。

5.2 (2021-04-26)

  • 确保与 pytest > 6.0 兼容。

  • 添加对 Python 3.9 的支持。

  • 将 CI 切换到 GHA。

  • 修复 PostgreSQL drop_db 以能够强制删除具有开放连接的数据库,即使没有与用户同名的数据库名。

5.1 (2020-07-06)

  • 在删除之前强制关闭到测试数据库的连接,因此无需事先执行此操作。(从 4.x 端口迁移,但更改日志中缺失。)

  • 计算一个足够随机的数据库名称,以适应并行执行。(从 4.2 端口迁移。)

5.0 (2020-07-02)

向后不兼容的更改

  • 注意:此版本基于 1.3 版本,忽略 4.x 版本中做出的更改!其中一些更改将稍后添加。

  • 删除对 Python 2.6 和 Python 3.3 到 3.5 的支持。

  • 删除仅包含向后兼容导入的模块 gocept.testdb.db,现在从 gocept.testdb.mysqlgocept.testdb.postgres 导入。

功能

  • 正式支持 Python 3.6 到 3.8。

  • 添加指定连接到数据库的端口的选项,因此考虑了环境变量 MYSQL_PORTPOSTGRES_PORT。这简化了在自定义端口上使用 docker 容器。

其他更改

  • 将代码迁移到 Github。

1.3 (2015-10-07)

  • 删除对 Python 3.2 的支持。

  • 简化文档。

1.3a1(2015-09-24)

  • 正式支持 Python 3.2 到 Python 3.4。

  • 将 PyMySQL 驱动程序切换为支持 Python 3 的 MySQL。

  • 添加环境变量 MYSQL_COMMAND_POSTFIX 以使用类似 mysql5 的 MySQL 命令而不是 mysql

1.2.1 (2013-09-03)

  • 改进删除数据库的重试逻辑:确保在尝试删除之前数据库确实存在。(#12706)

1.2 (2013-06-21)

  • 对 Python 3 的临时兼容性(尽管尚不存在兼容的 mysql 驱动程序)。

  • 修复了测试代码,该代码对 PostgreSQL 服务器上使用的现有数据库或依赖于时间条件的假设做出了隐式假设。

1.1.1 (2013-03-19)

  • 在更改自v1.1版本引入的LC_COLLATE时,使用< cite>template0。

1.1 (2013-03-19)

  • 在创建数据库时添加设置< cite>LC_COLLATE的可能性。

1.0 (2013-03-12)

  • 允许为mysql命令添加后缀。

1.0b5 (2011-12-22)

  • 使用时间戳随机化数据库名称以避免冲突。

1.0b4 (2011-09-23)

  • drop-all 入口现在也工作,如果PostgreSQL或MySQL未安装/运行。

1.0b3 (2011-05-13)

  • 添加了< cite>connect 便利方法。

1.0b2 (2011-05-04)

  • 添加了< cite>is_testing 属性作为便利API。

  • 添加了< cite>exists 属性作为便利API。

1.0b1 (2011-04-12)

  • 更改了使用测试数据库的协议:将实例化Database实例与在服务器上创建数据库分开。现在创建Database实例成本低,因此可以与之交互并传递,将昂贵的数据库创建延迟到显式调用db.create()时。这也与db.drop()更对称。

  • 添加了删除所有匹配testdb命名方案可能已留在服务器上的数据库的功能,这些数据库可能是早期测试运行留下的。可选地还可以删除模板数据库。

  • 添加了指定MySQL和PostgreSQL数据库名称的选项。

  • 添加了指定PostgreSQL模板数据库的选项。如果它不存在,则从指定的模式创建它。还可以强制创建模板,即使它已存在(删除当前的模板数据库)。每当模式自上次创建模板数据库以来发生变化时,模板数据库将自动更新。

0.4 (2010-12-15)

  • 添加了指定PostgreSQL数据库编码的选项。

  • 将PostgreSQL协议从postgres:更新到postgresql:,因为前者已在SQLAlchemy 0.6中弃用,因此至少需要SQLAlchemy 0.5.6版本。

  • 添加了如何进一步开发此包的文档。

  • 添加了关于使用< cite>Database前缀的文档。

0.3 (2010-10-15)

  • PostgreSQL:不要使用--quite调用createdb/dropdb,而只使用psql。

0.2 (2009-02-26)

  • 实现了使用密码的mysql身份验证。尽管如此,仍然不支持postgres密码。

0.1 (2008-09-26)

  • 第一个版本

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面