如何让 pytest 在已安装的模块中发现和 运行 doctests?
How to let pytest discover and run doctests in installed modules?
我正在添加单元测试和一种 "legacy" Python 包。一些模块包含嵌入在文档字符串中的自己的文档测试。我的目标是 运行 这些文档测试和新的专用单元测试。
跟随 this Q&A ("How to make py.test run doctests as well as normal tests directory?") I'm using the --doctest-modules
选项到 pytest
。当 运行ning 从源存储库中时,pytest
确实从 src
目录下的 Python 模块中发现了嵌入式文档测试。
但是,我的目标是测试源代码分发是否完全构建和安装,然后针对 installed 包测试所有内容。为此,我使用 tox
来自动构建 sdist
(源代码分发)tarball,将其安装在虚拟环境中,然后 运行 对安装的版本进行测试.为确保测试导入的是已安装的版本,而不是源存储库中的版本,我遵循建议 in this article,存储库现在如下所示:
repo/
src/
my_package/
__init__.py
module_a.py
module_b.py
...
tests/
test_this.py
test_that.py
requirements.txt
setup.py
tox.ini
(tests
下的测试脚本像import my_package
一样导入包,这会命中安装的版本,因为存储库布局确保src/my_package
目录不在模块搜索路径。)
并且在 tox
配置文件中,相关部分看起来像
[tox]
envlist = py27,py36,coverage-report
[testenv]
deps =
-rrequirements.txt
commands =
coverage run -p -m pytest --
[pytest]
addopts = --doctest-modules
到目前为止,测试 运行 很好,并且从 src/my_package
下的模块中提取了 doctests,而不是从安装在 tox
虚拟环境中的包中提取。
我与此设置相关的问题如下:
- 这真的是一个问题吗?
tox
似乎可以确保您安装的是源存储库中的内容,但确实如此吗?
- 我如何指示
pytest
以一种干净的方式从已安装的模块中实际 运行 doctests?我可以想到一些解决方案,例如在 doc
目录中构建专用文档树,然后让 pytest
使用 --doctest-glob
选项在其中找到文档测试。但是有没有一种方法可以在不先构建文档的情况下做到这一点?
pytest
从 当前目录 收集测试(除非您指示它以其他方式传递显式目录)。在tox.ini
中使用tox substitutions添加安装目录。即,要么传递目录:
[testenv]
deps =
-rrequirements.txt
commands =
coverage run -p -m pytest {envsitepackagesdir}/my_package
或更改目录:
[testenv]
changedir = {envsitepackagesdir}/my_package
deps =
-rrequirements.txt
commands =
coverage run -p -m pytest --
我找到了我自己问题的答案。
引用pytest
issue #2042:
currently doctest-modules
is fundamentally incompatible with testing
against a installed package due to module search in checkout vs module
usage from site-packages
所以到目前为止,解决方案不存在。
这就是我解决导入不匹配的方法:
$ pytest tests/ --doctest-modules --pyargs myrootpkg <other args>
这里的问题是,一旦开始明确指定源路径(在本例中为 --pyargs
),您还必须指定所有其他源路径(本例中为 tests/
) pytest
将停止扫描根目录。不过,这在使用 src
布局时应该不是问题,因为测试通常不会分散在存储库周围。
我正在添加单元测试和一种 "legacy" Python 包。一些模块包含嵌入在文档字符串中的自己的文档测试。我的目标是 运行 这些文档测试和新的专用单元测试。
跟随 this Q&A ("How to make py.test run doctests as well as normal tests directory?") I'm using the --doctest-modules
选项到 pytest
。当 运行ning 从源存储库中时,pytest
确实从 src
目录下的 Python 模块中发现了嵌入式文档测试。
但是,我的目标是测试源代码分发是否完全构建和安装,然后针对 installed 包测试所有内容。为此,我使用 tox
来自动构建 sdist
(源代码分发)tarball,将其安装在虚拟环境中,然后 运行 对安装的版本进行测试.为确保测试导入的是已安装的版本,而不是源存储库中的版本,我遵循建议 in this article,存储库现在如下所示:
repo/
src/
my_package/
__init__.py
module_a.py
module_b.py
...
tests/
test_this.py
test_that.py
requirements.txt
setup.py
tox.ini
(tests
下的测试脚本像import my_package
一样导入包,这会命中安装的版本,因为存储库布局确保src/my_package
目录不在模块搜索路径。)
并且在 tox
配置文件中,相关部分看起来像
[tox]
envlist = py27,py36,coverage-report
[testenv]
deps =
-rrequirements.txt
commands =
coverage run -p -m pytest --
[pytest]
addopts = --doctest-modules
到目前为止,测试 运行 很好,并且从 src/my_package
下的模块中提取了 doctests,而不是从安装在 tox
虚拟环境中的包中提取。
我与此设置相关的问题如下:
- 这真的是一个问题吗?
tox
似乎可以确保您安装的是源存储库中的内容,但确实如此吗? - 我如何指示
pytest
以一种干净的方式从已安装的模块中实际 运行 doctests?我可以想到一些解决方案,例如在doc
目录中构建专用文档树,然后让pytest
使用--doctest-glob
选项在其中找到文档测试。但是有没有一种方法可以在不先构建文档的情况下做到这一点?
pytest
从 当前目录 收集测试(除非您指示它以其他方式传递显式目录)。在tox.ini
中使用tox substitutions添加安装目录。即,要么传递目录:
[testenv]
deps =
-rrequirements.txt
commands =
coverage run -p -m pytest {envsitepackagesdir}/my_package
或更改目录:
[testenv]
changedir = {envsitepackagesdir}/my_package
deps =
-rrequirements.txt
commands =
coverage run -p -m pytest --
我找到了我自己问题的答案。
引用pytest
issue #2042:
currently
doctest-modules
is fundamentally incompatible with testing against a installed package due to module search in checkout vs module usage fromsite-packages
所以到目前为止,解决方案不存在。
这就是我解决导入不匹配的方法:
$ pytest tests/ --doctest-modules --pyargs myrootpkg <other args>
这里的问题是,一旦开始明确指定源路径(在本例中为 --pyargs
),您还必须指定所有其他源路径(本例中为 tests/
) pytest
将停止扫描根目录。不过,这在使用 src
布局时应该不是问题,因为测试通常不会分散在存储库周围。