我创建了一些单元测试,并从同一文件运行它们。对于同一文件中的测试:
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
也不足以对其进行修复。
答案 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='')