做这样的事情会很好:
if settings.TESTING:
print("py.test is being ran")
"pytest" in sys.modules
?
您可以使用单独的设置文件自行添加设置以进行测试
如果需要,我认为@blueyed和@adamchainz建议的方法应该足够了。 通常,不建议通过自省代码是否从测试中调用来更改代码的工作方式。 如果要这样做,则可以以通用的 pytest 方式完成(它并不是真正特定于 pytest-django)。 感谢您的建议,如果您在此问题中有更多信息,请随时重新打开此问题!
pytest 文档中的相关示例检测是否从 pytest run 中运行:
# content of conftest.py
def pytest_configure(config):
import sys
sys._called_from_test = True
def pytest_unconfigure(config):
import sys
del sys._called_from_test
问题是pytest_configure
在settings.py
之后运行。 有没有办法在settings.py
之前运行此代码?
@axil
使用'pytest' in sys.modules
什么问题?
嗯,是的,让它工作了,虽然对我来说它看起来有点麻烦。
在 settings.py 中检查这个的另一种快速而肮脏的方法是
TESTING = os.path.basename(sys.argv[0]) in ('pytest', 'py.test')
@axil
使用'pytest' in sys.modules
什么问题?
pytest 被导入的事实并不意味着pytest
正在运行并且代码是从测试中调用的。 基本上,我将pytest
导入其他东西。 另外 pytest 正在导入pytest
即使它只显示 CLI 帮助: pytest --help
这是非常有效的用例:
我有 django 设置,可配置本地文件和变量,其中放置了各种凭据和其他本地开发环境配置。 但我希望我的单元测试永远不会使用此凭据或特定设置,以免在某些真实系统上意外使用它们(如果模拟不当)或在本地开发环境配置上通过/失败。 因此,我希望在使用 pytest 运行时排除这些本地设置。
我有类似的东西:
import os
import os.path
import sys
from split_settings.tools import include, optional
def is_pytest_running():
return (os.getenv('PYTEST_RUNNING') == 'true' or
os.path.basename(sys.argv[0]) in ('pytest', 'py.test'))
ENVVAR_SETTINGS_PREFIX = 'MV_SERVER_'
local_settings_path = os.getenv(f'{ENVVAR_SETTINGS_PREFIX}SETTINGS', '../../../local/settings.py')
includes = [
'base.py',
'logging.py',
'custom.py',
]
if not is_pytest_running():
includes.append(optional(local_settings_path))
includes.append('envvars.py')
include(*includes)
使用os.getenv('PYTEST_RUNNING') == 'true'
或多或少是干净的方式,但问题在于设置此变量。 在 conftest.py 中设置它不起作用,因为 pytest-django 在 conftest.py 执行之前导入设置。 在运行 pytest 时在命令行中设置它很不方便,而且也违背了目的:如果有人忘记设置它,那么将使用本地开发环境配置中的真实凭据。
os.path.basename(sys.argv[0]) in ('pytest', 'py.test')
我不得不将其更改为os.path.basename(os.path.dirname(sys.argv[0])) in ('pytest', 'py.test')
因为sys.argv[0]
以/home/project/venv/lib/python3.8/site-packages/pytest/__main__.py
。
最有用的评论
"pytest" in sys.modules
?