pytest是否应该从虚拟环境中的依赖项模块收集测试?

时间:2018-10-22 20:08:53

标签: python sqlalchemy pytest

我正在尝试在不同于典型开发机器的另一台笔记本电脑上设置项目。这个项目有多个基于pytest的测试,我在项目的整个生命周期中都编写了这些测试。当我跑步时

$ pytest -k tests/my_test.py

我从sqlalchemy测试中获得如下错误列表:

_ ERROR collecting env/lib64/python3.5/site-packages/sqlalchemy/testing/suite/test_update_delete.py _
env/lib/python3.5/site-packages/py/_path/local.py:662: in pyimport
    __import__(modname)
env/lib/python3.5/site-packages/sqlalchemy/testing/suite/__init__.py:2: in <module>
    from sqlalchemy.testing.suite.test_cte import *
<frozen importlib._bootstrap>:968: in _find_and_load
    ???
<frozen importlib._bootstrap>:957: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:664: in _load_unlocked
    ???
<frozen importlib._bootstrap>:634: in _load_backward_compatible
    ???
env/lib/python3.5/site-packages/_pytest/assertion/rewrite.py:211: in load_module
    py.builtin.exec_(co, mod.__dict__)
env/lib/python3.5/site-packages/sqlalchemy/testing/suite/test_cte.py:11: in <module>
    class CTETest(fixtures.TablesTest):
env/lib/python3.5/site-packages/sqlalchemy/testing/suite/test_cte.py:99: in CTETest
    @testing.requires.ctes_with_update_delete
E   AttributeError: 'NoneType' object has no attribute 'ctes_with_update_delete'

为什么pytest从依赖项收集测试?应该这样做吗?如果没有,我该如何解决?

我正在设置此项目的笔记本电脑正在运行Ubuntu 18.04。我使用Python 3.5.6创建了virtualenv,并在virtualenv中运行pip install -r requirements,没有任何错误,包括sqlalchemy和pymssql。

3 个答案:

答案 0 :(得分:3)

要回答标题中的问题,

这可能是创建venv并将软件包安装在不可忽略的目录中的症状。请将它们放在某个地方,例如~/.venvs/等。

或者,--ignore=env专门用于排除该站点,或者以其他方式自定义配置文件中的测试发现:

# content of pytest.ini
[pytest]
norecursedirs = env

答案 1 :(得分:2)

调用pytest时,它将扫描项目根目录中的所有子目录,以查找测试;当您将特定于项目的虚拟环境放入项目根目录时,也将对其进行扫描而不会发生异常。这可能会导致不必要的测试包含在测试运行中(例如,当您具有numpypandas之类的依赖项,包括在发行版中的测试时)。

为避免这种情况,pytest提供了两个配置选项:

  1. norecursedirs-保存将不被扫描的目录。当您寻找“包括所有,排除所选”模式时,请使用此选项。有关说明和用法示例,另请参见wimanswer。默认情况下,norecursedirs设置为.*', 'build', 'dist', 'CVS', '_darcs', '{arch}', '*.egg',因此请注意,当您覆盖此选项时,默认设置将消失,您必须将其重新添加。
  2. testpaths-保留仅应考虑进行扫描的目录,因此与norecursedirs所做的工作基本上相反。查找“排除所有,包括所选内容”模式时,请使用此选项。根据您保留在项目根目录中的内容,此选项还会为测试发现增加一些次要或更重要的加速效果-大多数索引根本不会被遍历,并且测试运行会更快开始。

    用法:将选项放在pytest.ini / setup.cfg / tox.ini中:

    [tool:pytest]
    testpaths = tests othertests doc
    

    或从命令行通过--override-ini传递它们。

    pytest -o "testpaths=tests othertests doc" ...
    

将环境目录从项目源中移开是一个选择问题,取决于您所拥有的开发环境。 direnvpipenv等对于环境应该放置的位置可能有不同的看法,但是就我个人而言,将环境保留在项目根目录中没有任何问题。

答案 2 :(得分:1)

我相信问题在于您如何调用它。 pytest -k tests/my_test.py可能不是您想要的:pytest tests/my_test.py可能不是,因为这将调用单独的测试文件tests/my_test.py(不会发生递归:包括到您的环境站点包中)。 -k标志用于表达式(例如,您可以使用名称为"http"的所有测试)。

这没有多大意义,但是以某种方式,跑步者正在进行一些sqlalchemy测试(或者他们在import上失败了,我不确定)。似乎它们不应该匹配(即使运行程序递归到您的env目录中),但我认为这还不重要。您应该可以通过简单地调用pytest而无需使用-k选项来解决问题。

P.S。我无法重现您在Windows框中看到的行为。

HTH。