.. image:: https://raw.githubusercontent.com/dbfixtures/pytest-mysql/master/logo.png :width: 100px :height: 100px
pytest-mysql
.. image:: https://img.shields.io/pypi/v/pytest-mysql.svg :target: https://pypi.python.org/pypi/pytest-mysql/ :alt: Latest PyPI version
.. image:: https://img.shields.io/pypi/wheel/pytest-mysql.svg :target: https://pypi.python.org/pypi/pytest-mysql/ :alt: Wheel Status
.. image:: https://img.shields.io/pypi/pyversions/pytest-mysql.svg :target: https://pypi.python.org/pypi/pytest-mysql/ :alt: Supported Python Versions
.. image:: https://img.shields.io/pypi/l/pytest-mysql.svg :target: https://pypi.python.org/pypi/pytest-mysql/ :alt: License
这是什么?
一个用于依赖正在运行的 MySQL 或 MariaDB 数据库的测试的 pytest 插件。 它提供了进程和客户端 fixtures。
.. warning::
已在 MySQL 8.0+ 和 MariaDB 10.11+ 上测试。
.. image:: https://raw.githubusercontent.com/dbfixtures/pytest-mysql/main/docs/images/architecture.svg :alt: 项目架构图 :align: center
如何使用
该插件包含三个 fixtures:
- mysql - 一个函数作用域的客户端 fixture,在每个测试后删除测试数据库以确保可重复性。
- mysql_proc - 一个会话作用域的流程 fixture,在首次使用时启动本地 MySQL 实例,并在测试会话结束时停止它。
- mysql_noproc - 一个会话作用域的 fixture,连接到已运行的 MySQL 实例。
只需在您的测试 fixture 列表中包含其中一个 fixture 即可。
如果需要,您还可以创建额外的 MySQL 客户端和流程 fixtures:
.. code-block:: python
from pytest_mysql import factories
from getpass import getuser
mysql_my_proc = factories.mysql_proc( port=None, user=getuser()) mysql_my = factories.mysql('mysql_my_proc')
.. note::
每个 MySQL 进程 fixture 都可以通过 fixture 工厂参数以不同于其他 fixture 的方式进行配置。
Prerequisites
在运行测试的机器上安装 MySQL 或 MariaDB。
此插件依赖于这些安装提供的二进制文件(例如 mysqld and mysqladmin)。
使用 mysql_proc 从已安装的二进制文件启动本地 MySQL 进程。
使用 mysql_noproc 连接到已运行的 MySQL/MariaDB 服务器。
Quickstart: first test
安装插件:
.. code-block:: shell
pip install pytest-mysql
创建一个使用内置 fixture 的最小测试:
.. code-block:: python
def test_mysql_fixture_available(mysql): assert mysql is not None
运行你的测试:
.. code-block:: shell
pytest -q
配置
您可以通过三种方式定义设置:fixture 工厂参数、命令行选项以及 pytest.ini 配置选项。
这些设置按以下顺序应用:
* ``Fixture factory argument``
* ``Command-line option``
* ``Configuration option in your pytest.ini file``
.. list-table:: 配置选项 :header-rows: 1
-
- MySQL/MariaDB 选项
- Fixture 工厂参数
- 命令行选项
- pytest.ini 选项
- Noproc 进程 fixture
- 默认值
-
- 可执行文件路径
- mysqld_exec
- --mysql-mysqld
- mysql_mysqld
-
- mysqld
-
- 安全可执行文件路径
- mysqld_safe
- --mysql-mysqld-safe
- mysql_mysqld_safe
-
- mysqld_safe
-
- 用于旧版安装的 mysql_install_db 路径
- install_db
- --mysql-install-db
- mysql_install_db
-
- mysql_install_db
-
- Admin 可执行文件路径
- admin_executable
- --mysql-admin
- mysql_admin
-
- mysqladmin
-
- 数据库主机名
- host
- --mysql-host
- mysql_host
- 是
- localhost
-
- 数据库端口
- port
- --mysql-port
- mysql_port
- 是 (3306)
- 随机
-
- 空闲端口搜索次数
- port_search_count
- --mysql-port-search-count
- mysql_port_search_count
-
- 5
-
- 要使用的 MySQL 用户
- user
- --mysql-user
- mysql_user
-
- root
-
- 用户密码
- passwd
- --mysql-passwd
- mysql_passwd
-
-
- 测试数据库名称
- dbname
- --mysql-dbname
- mysql_dbname
-
- test
-
- 启动参数
- params
- --mysql-params
- mysql_params
-
示例用法:
-
将其作为参数传递到您自己的 fixture 中
.. code-block:: python
mysql_proc = factories.mysql_proc( port=8888)
-
运行测试时使用
--mysql-port命令行选项.. code-block::
pytest tests --mysql-port=8888
-
在
mysql_portin your `` 文件中指定你的端口为此,请在
[pytest]section of yourpytest.ini下添加如下所示的一行:.. code-block:: ini
[pytest] mysql_port = 8888
示例
以下示例展示了在首次冒烟测试通过后的高级集成模式。
为测试填充数据库
使用 SQLAlchemy +++++++++++++++
本示例展示了如何填充数据库并创建 SQLAlchemy ORM 连接:
以下示例是 pyramid_fullauth <https://github.com/fizyk/pyramid_fullauth/>_ 测试中简化的会话 fixture:
.. code-block:: python
from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.pool import NullPool from zope.sqlalchemy import register
@pytest.fixture
def db_session(mysql):
"""SQLAlchemy 的会话。"""
from pyramid_fullauth.models import Base # pylint:disable=import-outside-toplevel
# 假设已设置,这些可以从 pytest-mysql 配置或 mysql_proc 中获取
connection = f'mysql+mysqldb://root:@127.0.0.1:3307/tests?charset=utf8'
engine = create_engine(connection, echo=False, poolclass=NullPool)
pyramid_basemodel.Session = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
pyramid_basemodel.bind_engine(
engine, pyramid_basemodel.Session, should_create=True, should_drop=True)
yield pyramid_basemodel.Session
transaction.commit()
Base.metadata.drop_all(engine)
@pytest.fixture
def user(db_session):
"""测试用户 fixture。"""
from pyramid_fullauth.models import User
from tests.tools import DEFAULT_USER
new_user = User(**DEFAULT_USER)
db_session.add(new_user)
transaction.commit()
return new_user
def test_remove_last_admin(db_session, user): """ 示例测试检查内部登录,但展示了在 SQLAlchemy 测试中的用法 """ user = db_session.merge(user) user.is_admin = True transaction.commit() user = db_session.merge(user)
with pytest.raises(AttributeError):
user.is_admin = False
.. note::
参见 `pyramid_fullauth's conftest file <https://github.com/fizyk/pyramid_fullauth/blob/2950e7f4a397b313aaf306d6d1a763ab7d8abf2b/tests/conftest.py#L35>`_ 处的原始代码。
根据您的需求,中间代码可以在 SQLAlchemy 堆栈的情况下触发 alembic 迁移,或执行任何其他代码
连接到 MySQL/MariaDB(在 docker 中)
要连接到在 Docker 中运行的 MySQL 或 MariaDB,请使用 noproc fixtures。
.. code-block:: sh
docker run --name some-db -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -d mysql --expose 3306
.. code-block:: sh
docker run --name some-db -e MARIADB_ALLOW_EMPTY_PASSWORD=yes -d mariadb --expose 3306
这会在 Docker 容器中启动 MySQL/MariaDB,但使用本地安装的 MySQL 或 MariaDB 实例也是类似的。
在测试中,请确保你的测试像这样使用 mysql_noproc fixture:
.. code-block:: python
mysql_in_docker = factories.mysql_noproc() mysql = factories.mysql("mysql_in_docker")
def test_mysql_docker(mysql):
"""运行测试。"""
cur = mysql.cursor()
cur.query("CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);")
mysql.commit()
cur.close()
并运行测试:
.. code-block:: sh
pytest --mysql-host=127.0.0.1
在 Docker 中/以 root 身份运行
MySQL 和 MariaDB 默认拒绝以 root 身份运行,但我们可以通过在配置文件中设置 user=root 来强制它们运行。
然而,最常见且安全的做法是更改在 Docker 中运行测试的用户:
.. code-block::
USER nobody
此行应将您的 Docker 进程切换为以用户 nobody. See this comment for example <https://github.com/dbfixtures/pytest-mysql/issues/62#issuecomment-367975723>_ 身份运行。
Package resources
- Bug tracker: https://github.com/dbfixtures/pytest-mysql/issues
Release
首先安装 pipenv 和 --dev 依赖项,然后运行:
.. code-block::
pipenv run tbump [NEW_VERSION]