PytestWarning:模块已导入,因此无法重写:pytest_remotedata

时间:2019-01-02 15:58:01

标签: python python-import pytest

我创建了一些单元测试,并从同一文件运行它们。对于同一文件中的测试:

if __name__ == "__main__":
    import pytest
    pytest.main(['--tb=short', __file__])

对于另一个文件中的测试:

if __name__ == '__main__':
    import pytest
    pytest.main(['./test_stuff.py', "--capture=sys"])

无论哪种情况,当我第一次执行文件时,它都可以正常工作,但是第二次及以后,它会给出一系列警告:

============================== warnings summary ===============================
C:\Anaconda3\lib\site-packages\_pytest\config\__init__.py:754
  C:\Anaconda3\lib\site-packages\_pytest\config\__init__.py:754: PytestWarning: Module already imported so cannot be rewritten: pytest_remotedata
    self._mark_plugins_for_rewrite(hook)
  C:\Anaconda3\lib\site-packages\_pytest\config\__init__.py:754: PytestWarning: Module already imported so cannot be rewritten: pytest_openfiles
    self._mark_plugins_for_rewrite(hook)
  C:\Anaconda3\lib\site-packages\_pytest\config\__init__.py:754: PytestWarning: Module already imported so cannot be rewritten: pytest_doctestplus
    self._mark_plugins_for_rewrite(hook)
  C:\Anaconda3\lib\site-packages\_pytest\config\__init__.py:754: PytestWarning: Module already imported so cannot be rewritten: pytest_arraydiff
    self._mark_plugins_for_rewrite(hook)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
==================== 1 passed, 4 warnings in 0.06 seconds 

有什么办法可以消除这些警告?

重新启动内核是可行的,但是IPython的%reset%clear也不足以对其进行修复。

3 个答案:

答案 0 :(得分:2)

看来pytest并不是真正为在同一进程中重复执行pytest.main()调用而设计的。 pytest documentation提到:

  

调用pytest.main()将导致导入测试以及任何   他们导入的模块。由于python的缓存机制   导入系统,随后从同一系统调用pytest.main()   处理不会反映两次调用之间对这些文件的更改。对于   因此,从同一对象多次调用pytest.main()   不建议使用此过程(例如,为了重新运行测试)。

因此,实际上,在同一过程中执行多个pytest.main()调用的真正危险是,如果您在它们之间编辑了代码文件,则可能会得到假阳性或假阴性测试结果。

Spyder IDE具有一个漂亮的功能,尽管它似乎可以解决这个问题:User Module Reloader (UMR)。如果启用,则在(重新)运行脚本文件时会自动重新加载所有更改的用户模块。

因此,我认为只要您在Spyder中工作(启用了UMR功能!),就可以安全地重新运行pytest.main(),而无需新的控制台。 pytest模块已经导入的警告,然后您就可以简单地取消警告,因为这些pytest模块不会更改。可以使用pytest的-W flag完成。示例:

if __name__ == '__main__':
    import pytest
    pytest.main(['./test_stuff.py', "--capture=sys", "-W", "ignore:Module already imported:pytest.PytestWarning"])

答案 1 :(得分:1)

如果仅关注警告,则可以使用--disable-warnings参数。您还可以使用pytest.main中的--pythonwarnings=PYTHONWARNINGS参数仅过滤出您现在得到的警告。 pytest --help拥有有关这些参数的更多信息。

似乎您正在使用ipython或jupyter调用pytest。 python.main在pytest初始化时导入pytest特定模块。再次运行pytest.main时,它将引发警告。有两种可能的方法可以重新加载pytest以避免收到此初始化警告。

您可以在pytest.main之后使用pytest.exit或在pytest.main之后使用reload pytest

让我们知道这些方法是否有效。

答案 2 :(得分:1)

使用subprocess代替pytest.main

if __name__ == "__main__":
    import subprocess
    subprocess.call(['pytest', '--tb=short', str(__file__)])

如果上面没有打印任何内容,请尝试解决方法(如注释中所述):

if __name__ == "__main__":
    from subprocess import Popen, PIPE
    with Popen(['pytest',
                '--tb=short',  # shorter traceback format
                str(__file__)], stdout=PIPE, bufsize=1,
                universal_newlines=True) as p:
        for line in p.stdout:
            print(line, end='')