Pytest-django: Windows: OSError: pathlib ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ [WinError 123]

์— ๋งŒ๋“  2018๋…„ 08์›” 29์ผ  ยท  12์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pytest-dev/pytest-django

๋‚ด pytest.ini ์— ๋‹ค์Œ ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

[pytest]
DJANGO_SETTINGS_MODULE = project.settings_pytest
addopts = --doctest-modules --cov=. --cov-report html:./coverage/python/html
norecursedirs = .git .venv .vscode node_modules

--cov-report ๋กœ ์ „๋‹ฌ๋œ ์œ ๋‹‰์Šค ๊ณ„์—ด ๊ฒฝ๋กœ๊ฐ€ Windows์—์„œ ์ตœ์‹  ๋ฒ„์ „์˜ pytest-django๋ฅผ ์ถฉ๋Œ์‹œํ‚ค๋Š” ์›์ธ์ด ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ( .ini ํŒŒ์ผ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”Œ๋žซํผ์— ๋…๋ฆฝ์ ์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.)

pytest ์‹คํ–‰ํ•  ๋•Œ ํ‘œ์‹œ๋˜๋Š” ์—ญ์ถ”์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Traceback (most recent call last):
  File "C:\Program Files\Python37\Lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Program Files\Python37\Lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\Atul\.virtualenvs\tenants2-Gxdtcl1v\Scripts\pytest.exe\__main__.py", line 9, in <module>
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\_pytest\config\__init__.py", line 55, in main
    config = _prepareconfig(args, plugins)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\_pytest\config\__init__.py", line 180, in _prepareconfig
    pluginmanager=pluginmanager, args=args
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\hooks.py", line 258, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\manager.py", line 67, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\manager.py", line 61, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\callers.py", line 196, in _multicall
    gen.send(outcome)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\_pytest\helpconfig.py", line 89, in pytest_cmdline_parse
    config = outcome.get_result()
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\callers.py", line 76, in get_result
    raise ex[1].with_traceback(ex[2])
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\_pytest\config\__init__.py", line 612, in pytest_cmdline_parse
    self.parse(args)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\_pytest\config\__init__.py", line 777, in parse
    self._preparse(args, addopts=addopts)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\_pytest\config\__init__.py", line 739, in _preparse
    early_config=self, args=args, parser=self._parser
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\hooks.py", line 258, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\manager.py", line 67, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\manager.py", line 61, in <lambda>
    firstresult=hook.spec_opts.get('firstresult'),
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\callers.py", line 201, in _multicall
    return outcome.get_result()
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\callers.py", line 76, in get_result
    raise ex[1].with_traceback(ex[2])
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pluggy\callers.py", line 180, in _multicall
    res = hook_impl.function(*args)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pytest_django\plugin.py", line 209, in pytest_load_initial_conftests
    _django_project_scan_outcome = _add_django_project_to_path(args)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pytest_django\plugin.py", line 140, in _add_django_project_to_path
    project_dir = find_django_path(args)
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pytest_django\plugin.py", line 127, in find_django_path
    args = [p for p in args if p.is_dir()]
  File "c:\users\atul\.virtualenvs\tenants2-gxdtcl1v\lib\site-packages\pytest_django\plugin.py", line 127, in <listcomp>
    args = [p for p in args if p.is_dir()]
  File "C:\Program Files\Python37\Lib\pathlib.py", line 1330, in is_dir
    return S_ISDIR(self.stat().st_mode)
  File "C:\Program Files\Python37\Lib\pathlib.py", line 1140, in stat
    return self._accessor.stat(self)
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 'html:.\\coverage\\python\\html'

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

pathlib๋กœ์˜ ์ „ํ™˜์œผ๋กœ ์ธํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

/cc @voidus

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ --cov-report=html:./coverage/python/html ๋ฅผ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.

์•ˆ๋…•ํ•˜์„ธ์š” pytest .\app\tests.py::WebServiceTest์—๋„ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

์•ˆ๋…•ํ•˜์„ธ์š”
OSError: [WinError 123] Die Syntax fรผr den Dateinamen, Verzeichnisnamen oder die Datentrรคgerbezeichnung ist falsch: 'app\tests.py::WebServiceTest'
(์˜ค๋ฅ˜ ํ…์ŠคํŠธ๋Š” ๋…์ผ์–ด์ž„)

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ ๋‚ด pytest.ini ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์ทจ์žฌ ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค.

[ํŒŒ์ดํ…Œ์ŠคํŠธ]
DJANGO_SETTINGS_MODULE = DjangoBasisLager.settings
python_files = tests.py tests_*.py *_tests.py

๋ฌธ์ œ๋Š” ํ…Œ์ŠคํŠธ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์ฒด ์˜ค๋ฅ˜ ๋กœ๊ทธ:
(DjangoBasisLager--RYvLsCA) PS C:UsersLubitzworkspacebasislagerDjangoBasisLager> pytest .\app\tests.py::WebServiceTest
์—ญ์ถ”์ (๊ฐ€์žฅ ์ตœ๊ทผ ํ˜ธ์ถœ ๋งˆ์ง€๋ง‰):
ํŒŒ์ผ "C:Program FilesPython36Librunpy.py", 193ํ–‰, _run_module_as_main
"__main__", mod_spec)
ํŒŒ์ผ "C:Program FilesPython36Librunpy.py", 85ํ–‰, _run_code
exec(์ฝ”๋“œ, run_globals)
ํŒŒ์ผ "C:UsersLubitz.virtualenvsDjangoBasisLager--RYvLsCAScriptspytest.exe__main__.py", 9ํ–‰,
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packages_pytestconfig__init__.py", ๋ผ์ธ 56, ๋ฉ”์ธ
๊ตฌ์„ฑ = _prepareconfig(์ธ์ˆ˜, ํ”Œ๋Ÿฌ๊ทธ์ธ)
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packages_pytestconfig__init__.py", 181ํ–‰, _prepareconfig
ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ด€๋ฆฌ์ž=ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ด€๋ฆฌ์ž, ์ธ์ˆ˜=์ธ์ˆ˜
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggyhooks.py", 258ํ–‰, __call__
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggymanager.py", 67ํ–‰, _hookexec
return self._inner_hookexec(ํ›„ํฌ, ๋ฉ”์„œ๋“œ, kwargs)
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggymanager.py", ๋ผ์ธ 61,
firstresult=hook.spec_opts.get('firstresult'),
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggycallers.py", ๋ผ์ธ 196, _multicall
gen.send(๊ฒฐ๊ณผ)
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packages_pytesthelpconfig.py", 89ํ–‰, pytest_cmdline_parse
๊ตฌ์„ฑ = ๊ฒฐ๊ณผ.get_result()
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggycallers.py", 76ํ–‰, get_result
ex[1].with_traceback(ex[2]) ์˜ฌ๋ฆฌ๊ธฐ
ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggycallers.py", 180ํ–‰, _multicall
res = hook_impl.function( ์ธ์ˆ˜)ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packages_pytestconfig__init__.py", 617ํ–‰, pytest_cmdline_parseself.parse(์ธ์ˆ˜)ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packages_pytestconfig__init__.py", 782ํ–‰, ๊ตฌ๋ฌธ ๋ถ„์„ ์ค‘self._preparse(์ธ์ˆ˜, addopts=addopts)ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packages_pytestconfig__init__.py", 744ํ–‰, _preparseEarly_config=self, args=args, ํŒŒ์„œ=self._parserํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggyhooks.py", 258ํ–‰, __call__return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggymanager.py", 67ํ–‰, _hookexecreturn self._inner_hookexec(ํ›„ํฌ, ๋ฉ”์„œ๋“œ, kwargs)ํŒŒ์ผ "c:userslubitz.virtualenvsdjangobasislager--ryvlscalibsite-packagespluggymanager.py", 61ํ–‰,






์ธ์ˆ˜)
ํŒŒ์ผ "C:UsersLubitz.virtualenvsDjangoBasisLager--RYvLsCAlibsite-packagespytest_djangoplugin.py", 209ํ–‰, pytest_load_initial_conftests
_django_project_scan_outcome = _add_django_project_to_path(์ธ์ˆ˜)
ํŒŒ์ผ "C:UsersLubitz.virtualenvsDjangoBasisLager--RYvLsCAlibsite-packagespytest_djangoplugin.py", 140ํ–‰, _add_django_project_to_path
project_dir = find_django_path(์ธ์ˆ˜)
ํŒŒ์ผ "C:UsersLubitz.virtualenvsDjangoBasisLager--RYvLsCAlibsite-packagespytest_djangoplugin.py", 127ํ–‰, find_django_path
args = [p for p for p in args if p.is_dir()]
ํŒŒ์ผ "C:UsersLubitz.virtualenvsDjangoBasisLager--RYvLsCAlibsite-packagespytest_djangoplugin.py", 127ํ–‰,
args = [p for p for p in args if p.is_dir()]
ํŒŒ์ผ "C:Program FilesPython36Libpathlib.py", 1346ํ–‰, is_dir
๋ฐ˜ํ™˜ S_ISDIR(self.stat().st_mode)
ํŒŒ์ผ "C:Program FilesPython36Libpathlib.py", 1156ํ–‰, ํ†ต๊ณ„
self._accessor.stat(self)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
ํŒŒ์ผ "C:Program FilesPython36Libpathlib.py", ์ค„ 387, ๋ž˜ํ•‘๋จ
๋ฐ˜ํ™˜ strfunc(str(pathobj), *args)
OSError: [WinError 123] Die Syntax fรผr den Dateinamen, Verzeichnisnamen oder die Datentrรคgerbezeichnung ist falsch: 'app\tests.py::WebServiceTest'

์•„, ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ •์ƒ์ ์ธ ์ธ์ˆ˜์— ๋Œ€ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

@voidus
์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์กฐ์‚ฌํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์•ˆ๋…•ํ•˜์„ธ์š”, ์–ด๋–ค ์‹์œผ๋กœ๋“  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์„ ๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ๋ธŒ๋Ÿฐ์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

@pinguin999
ํ…Œ์ŠคํŠธํ•  ํ•ญ๋ชฉ์ด ์—†์Šต๋‹ˆ๋‹ค.
์ถ”๊ฐ€๋˜๋Š” pathlib ์ฝ”๋“œ์™€ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค(์Šคํƒ ์ถ”์  ์ฐธ์กฐ).
PR์— ์ˆ˜์ • ์‚ฌํ•ญ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@pinguin999 ์ด ์˜ค๋ฅ˜์˜ ์›์ธ์ด ๋ฌด์—‡์ธ์ง€ ์ •ํ™•ํžˆ ๋ชจ๋ฅด์ง€๋งŒ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ์‚ฌ์–‘( ::WebServiceTest )์ด ์›์ธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ํ•ด๋‹น ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋ถ„๊ธฐ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฐœ๋ฐœ ์„ค์ •์ด ์žˆ๋Š” Windows ์‹œ์Šคํ…œ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. https://github.com/voidus/pytest-django ์—์„œ ๋‚ด ํฌํฌ์˜ oserror_pathlib ๋ถ„๊ธฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

https://github.com/voidus/pytest-django/tree/oserror_pathlib

์˜ˆ, ๋ถ„๋ช…ํžˆ ์ธ์ˆ˜์˜ ":"๋Š” Windows์—์„œ ๊ตฌ์ œ๋ฉ๋‹ˆ๋‹ค.
๋‚˜๋Š” ๋‹น์‹ ์˜ ํŒจ์น˜๊ฐ€ ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๊ทธ๊ฒƒ์œผ๋กœ https://github.com/pytest-dev/pytest-django/pull/648 ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”
๋ฏธ์•ˆ ๋‚ด๊ฐ€ ํœด์ผ์— ์žˆ์—ˆ๋‹ค.
3.4.3์œผ๋กœ ์—…๋ฐ์ดํŠธํ–ˆ๊ณ  ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

# ์ด ์ฝ”๋“œ ์ค„ ์ œ๊ฑฐ ====== 'module_name',
INSTALLED_APPS ๋ชฉ๋ก์—์„œ

๊ธ€์Ž„, ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ๋„ ์ผ์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค.
๋จผ์ € ํ”„๋กœ์ ํŠธ ํด๋”์—์„œ ์•ฑ์„ ์‹œ์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
์˜ˆ๋ฅผ ๋“ค์–ด:
"django-admin startproject ์›น์‚ฌ์ดํŠธ
CD ์›น์‚ฌ์ดํŠธ
django-admin startapp ์Œ์•…"

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