TL; DR:如果我使用pytest
和其他一些仅用于测试的依赖项,是否可以断言这些仅用于测试的依赖项没有泄漏到实际的非测试代码中? >
在Java中,当我运行测试时,测试本身和被测试代码将在不同的类加载器中运行,它们各自的依赖项在此作用域。因此,如果测试中的代码无意中引用了testng
,则即使testng
正在运行测试,测试也将失败。
在Python中可以实现相同的效果吗?如果我的非测试代码意外导入了pytest
,我可以抓住它并使测试失败吗?我看不到如何实现的。
尽管setuptools
和pip
等使相对独立的安装/运行和开发/测试依赖关系保持相对容易,甚至避免污染当前的venv,但在运行测试时它们仍然存在。这意味着为模块运行python setup.py test
可以通过,但是python setup.py install
后跟导入模块一样简单的操作可能会失败。
给出:
cat setup.py
from setuptools import setup, find_packages
setup(
name="brettpy",
version="0.0.1",
packages=find_packages(),
setup_requires=["pytest-runner",],
tests_require=["pytest",],
)
cat setup.cfg
[aliases]
test=pytest
cat brettpy/__init__.py
import pytest
cat tests/test_brettpy.py
def test_import_brettpy():
import brettpy
del brettpy
def test_run_main():
from brettpy import __main__ as main
main.main()
... python setup.py test
将通过,但是python setup.py install && python -m brettpy
将失败,并显示以下信息:
ModuleNotFoundError: No module named 'pytest'
其他人如何确保测试依赖项不会渗入实际代码中并在安装时引起缺少依赖项的错误?感觉像是测试框架应该能够捕获的错误。
答案 0 :(得分:3)
您可以使用Python的test
来显式测试modulefinder
的导入。这可能不是最漂亮的解决方案:
from modulefinder import ModuleFinder
def test_imports():
finder = ModuleFinder()
finder.run_script("PATH_TO_MAIN_SCRIPT")
tests_require = ["pytest",] # you can also get this list straight from `setup.py`
overlapping = [mod for mod in finder.modules.keys() for req in tests_require if req in mod]
assert not overlapping
或者如果您不想使用列表理解:
for mod_name in finder.modules.keys():
for req in tests_require:
assert req not in mod_name # module could be pytest.something, _pytest, etc.
答案 1 :(得分:-3)
您可以尝试执行以下操作:here
def no_test():
try:
pytest
except NameError:
pass
else:
exit()