Pytest-django: Django๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ ์ค‘์ธ์ง€ ๊ฐ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ œ๊ณต

์— ๋งŒ๋“  2016๋…„ 05์›” 06์ผ  ยท  9์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pytest-dev/pytest-django

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

if settings.TESTING:
    print("py.test is being ran")

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

"pytest" in sys.modules ?

๋ชจ๋“  9 ๋Œ“๊ธ€

"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 ์ „์— ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@์—ฝ์•ก
'pytest' in sys.modules ๋ฅผ) ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ , ์˜ˆ, ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋น„๋ก ๋‚˜์—๊ฒŒ๋Š” ์•ฝ๊ฐ„ ํ•ดํ‚คํ•ด ๋ณด์ด์ง€๋งŒ.

settings.py์—์„œ ์ด๊ฒƒ์„ ํ™•์ธํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋น ๋ฅด๊ณ  ๋”๋Ÿฌ์šด ๋ฐฉ๋ฒ•์€

TESTING = os.path.basename(sys.argv[0]) in ('pytest', 'py.test')

@์—ฝ์•ก
'pytest' in sys.modules ๋ฅผ) ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

pytest๋ฅผ ๊ฐ€์ ธ์™”๋‹ค๊ณ  ํ•ด์„œ pytest ๊ฐ€ ์‹คํ–‰ ์ค‘์ด๊ณ  ํ…Œ์ŠคํŠธ์—์„œ ์ฝ”๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‚ด ์ˆ˜์ž… pytest ์ค‘ ํ•˜๋‚˜๋Š” ๋‹ค๋ฅธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ pytest๋Š” CLI ๋„์›€๋ง๋งŒ ํ‘œ์‹œํ•˜๋”๋ผ๋„ pytest ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 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' ๊ฒƒ์ด ๋‹ค์†Œ ๊น”๋”ํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ๋ฌธ์ œ๋Š” ์ด ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. pytest-django๋Š” conftest.py๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์„ค์ •์„ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— conftest.py์—์„œ ์„ค์ •ํ•˜๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. pytest๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋ช…๋ น์ค„์—์„œ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํŽธํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชฉ์ ๋„ ๋ฌดํšจํ™”๋ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฌ๋ฉด ๋กœ์ปฌ dev env ๊ตฌ์„ฑ์—์„œ ์‹ค์ œ ์ž๊ฒฉ ์ฆ๋ช…์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

os.path.basename(sys.argv[0]) in ('pytest', 'py.test')

sys.argv[0] ๊ฐ€ /home/project/venv/lib/python3.8/site-packages/pytest/__main__.py ๋กœ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์— os.path.basename(os.path.dirname(sys.argv[0])) in ('pytest', 'py.test') ๋กœ ๋ฐ”๊ฟ”์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰