是否可以使用python / pytest来测试测试相关性是否尚未泄漏到真实代码中

时间:2019-06-05 00:44:40

标签: python pytest

TL; DR:如果我使用pytest和其他一些仅用于测试的依赖项,是否可以断言这些仅用于测试的依赖项没有泄漏到实际的非测试代码中? >

在Java中,当我运行测试时,测试本身和被测试代码将在不同的类加载器中运行,它们各自的依赖项在此作用域。因此,如果测试中的代码无意中引用了testng,则即使testng正在运行测试,测试也将失败。

在Python中可以实现相同的效果吗?如果我的非测试代码意外导入了pytest,我可以抓住它并使测试失败吗?我看不到如何实现的。

尽管setuptoolspip等使相对独立的安装/运行和开发/测试依赖关系保持相对容易,甚至避免污染当前的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'

其他人如何确保测试依赖项不会渗入实际代码中并在安装时引起缺少依赖项的错误?感觉像是测试框架应该能够捕获的错误。

2 个答案:

答案 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()