【发布时间】:2021-01-27 16:43:38
【问题描述】:
[TL;DR] 当使用 Sphinx 的 make doctest 时,测试中创建的 Django 模型被提交到数据库;我们如何防止它们自动提交或在每次测试之间重置数据库(使用与pytest 类似的方法)?
设置
我使用脚本创建了一个基本的 Django 应用程序:
python -m pip install django sphinx pytest pytest-django pytest-sphinx
django-admin startproject project_name
cd project_name
mkdir project_name/app
python manage.py startapp app project_name/app
touch pytest.ini
touch conftest.py
mkdir docs
cd docs ; sphinx-quickstart ; cd ..
(在sphinx-quickstart 中创建单独的源目录和构建目录。)
然后:
- 已将
project_name/app/models.py更改为:
"""Models for the test application."""
from django.db import models
class Animal(models.Model):
"""A django model for an animal.
.. rubric: Example
.. testsetup:: animal
from project_name.app.models import Animal
.. testcode:: animal
frog = Animal.objects.create(name="frog")
print( frog )
.. testoutput:: animal
Animal object (1)
"""
name = models.CharField(max_length=200)
- 编辑
project_name/settings.py以将'project_name.app'添加到INSTALLED_APPS。 - 编辑
docs/source/conf.py以在“路径设置”下添加行:
import os
import sys
import django
sys.path.insert(0, os.path.abspath('../..'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'project_name.settings'
django.setup()
并在“常规配置”下设置:
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
]
- 将
docs/source/index.rst替换为:
.. toctree::
:maxdepth: 2
:caption: Contents:
Project Name Documentation
==========================
.. currentmodule:: project_name.app.models
.. autoclass:: Animal
- 将
pytest.ini替换为:
[pytest]
DJANGO_SETTINGS_MODULE = project_name.settings
addopts = --doctest-modules
- 将
conftest.py替换为:
import pytest
@pytest.fixture(autouse=True)
def enable_db_access_for_all_tests(db):
pass
- 然后运行:
python manage.py makemigrations
python manage.py migrate
问题
当我运行pytest时,文档中的测试每次都运行并通过;但是,当我使用 Sphinx 并在 docs 子目录中运行 make doctest 时,它第一次通过,然后随后失败,因为它每次都会创建一个新的 Animal 实例并将其提交到数据库和不会重新创建数据库。
Running Sphinx v3.4.3
loading pickled environment... done
building [mo]: targets for 0 po files that are out of date
building [doctest]: targets for 1 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
running tests...
Document: index
---------------
**********************************************************************
File "../../project_name/app/models.py", line ?, in animal
Failed example:
frog = Animal.objects.create(name="frog")
print( frog )
Expected:
Animal object (1)
Got:
Animal object (2)
**********************************************************************
如何更改docs/source/conf.py(或其他适当的脚本)以使用类似于pytest 的方法,以便每次都通过Sphinx doctest(无需删除并重新创建数据库)?
(我不想更改文档中的单元测试;我想确保数据库已重置或数据未提交并在每次测试后回滚。)
【问题讨论】:
-
不是一个完整的答案,但是如果没有 Sphinx,您将如何运行 pytest 以不提交和回滚事务?如果你有这样的例子,也许你可以把它应用到 doctests 和 Sphinx 上?
-
@StevePiercy 你只需运行
pytest并安装pytest-django包;我相信,它被设置为(开箱即用)使用假数据库或关闭AUTOCOMMIT,以便回滚事务。 Sphinx 使用一个调用sphinx-build的 make 文件,该文件使用sphinx.ext.doctest进而调用doctest包....所以解决方案可能是构建一个自定义 sphinx 扩展,其中大部分代码来自 @987654355 @ 调用pytest而不是doctest。 -
挖掘更多,
pytest-django添加了一个夹具,sets up the Django test environment 用于其测试。
标签: python django pytest python-sphinx doctest