如何解决每次测试后如何让Sphinx doctest重置Django数据库?
[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 并在 make doctest
子目录中运行 docs
时,它第一次通过,然后在随后的时间失败,因为它每次都会创建一个新的 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 每次都通过(无需删除和重新创建数据库)?
(我不想更改文档中的单元测试;我想确保数据库已重置或数据未提交并在每次测试后回滚。)
解决方法
对此的快速(肮脏)解决方案是绕过该问题并在运行测试之前刷新数据库:
python ./manage.py migrate
python ./manage.py flush
./docs/make doctest
- 首先应用迁移,以防测试 SQLite 数据库不存在;然后
- 数据库已刷新(您可以使用
--no-input
标志跳过输入提示。但是,如果意外应用于生产数据库可能会很危险,因此默认情况下不包括在内);和 - 最后,在空数据库上运行文档测试。
这在简单示例中有效,但如果运行多个示例创建同一模型的多个实例(并且每个实例将获得不同的自动生成的 id 值)并且测试处于非-确定性顺序。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。