æ»ã 次㞠
ãã®ç« ã§ã¯ãpytestã«åœ±é¿ããæ§æãã¡ã€ã«ã調ã¹ãpytestããããã«åºã¥ããŠåäœãã©ã®ããã«å€æŽãããã説æããTasksãããžã§ã¯ãã®æ§æã¿ã¹ã¯ã«ããã€ãã®å€æŽãå ããŸãã

ãã®æ¬ã®äŸã¯ãPython 3.6ãšpytest 3.2ã䜿çšããŠæžãããŠããŸãã pytest 3.2ã¯ãPython 2.6ã2.7ãããã³Python 3.3+ããµããŒãããŠããŸãã
Tasksãããžã§ã¯ãã®ãœãŒã¹ã³ãŒããšããã®æ¬ã«ç€ºãããŠãããã¹ãŠã®ãã¹ãã®ãœãŒã¹ã³ãŒãã¯ã pragprog.comã«ããæ¬ã®WebããŒãžã®ãªã³ã¯ããå
¥æã§ããŸãã ãã¹ãã³ãŒããçè§£ããããã«ãœãŒã¹ã³ãŒããããŠã³ããŒãããå¿
èŠã¯ãããŸããã ãã¹ãã³ãŒãã¯ãäŸã§ã¯äŸ¿å©ãªåœ¢åŒã§ç€ºãããŠããŸãã ãã ãããããžã§ã¯ãã®ã¿ã¹ã¯ãå®è¡ãããããã¹ããµã³ãã«ã調æŽããŠèªåã®ãããžã§ã¯ãããã¹ããããããã«ã¯ïŒæãçžã£ãŠããªãïŒïŒãæžç±ã®WebããŒãžã«ã¢ã¯ã»ã¹ããŠäœåãããŠã³ããŒãããå¿
èŠããããŸãã æžç±ã®WebããŒãžã«ã¯ã æ£èª€è¡šã®ã¡ãã»ãŒãžãžã®ãªã³ã¯ãšãã£ã¹ã«ãã·ã§ã³ãã©ãŒã©ã ããããŸãã
ãã¿ãã¬ã®äžã«ã¯ããã®ã·ãªãŒãºã®èšäºã®ãªã¹ãããããŸãã
æ§æ
ãããŸã§ã®ãšããã95ããŒãžã®ç¬¬5ç« ããã©ã°ã€ã³ãã§è©³çްã«èª¬æããconftest.pyãé€ããäž»ã«pytestã«åœ±é¿ãäžããããŸããŸãªéãã¹ããã¡ã€ã«ã«ã€ããŠèª¬æããŸããããã®ç« ã§ã¯ãæ§æãã¡ã€ã«ã«ã€ããŠèª¬æããŸãã pytestã«åœ±é¿ãäžããpytestããããã«åºã¥ããŠåäœãã©ã®ããã«å€æŽããããè°è«ããTasksãããžã§ã¯ãã®æ§æãã¡ã€ã«ã«ããã€ãã®å€æŽãå ããŸãã
pytestæ§æãã¡ã€ã«ã«ã€ããŠ
pytestã®ããã©ã«ãã®åäœã倿Žããæ¹æ³ã説æããåã«ãpytestã®ãã¹ãŠã®éãã¹ããã¡ã€ã«ãç¹ã«ã誰ãããããåŠçããå¿
èŠããããã調ã¹ãŠã¿ãŸãããã
次ã®ããšãç¥ã£ãŠããå¿
èŠããããŸãã
- pytest.ini ïŒããã¯ãããã©ã«ãã®åäœã倿Žã§ããã¡ã€ã³ã®Pytestæ§æãã¡ã€ã«ã§ãã ããªãã®æ°ã®æ§æå€æŽãè¡ãããšãã§ããããããã®ç« ã®å€§éšåã¯
pytest.ini
è¡ããèšå®ã«å°å¿µããŠããŸãã - conftest.py ïŒããã¯ã
conftest.py
ãã¡ã€ã«conftest.py
ãã£ã¬ã¯ããªãšãã®ãã¹ãŠã®ãµããã£ã¬ã¯ããªã«ããã¯é¢æ°ãšãã£ã¯ã¹ãã£ãæ¥ç¶ã§ããããã«ããããŒã«ã«ãã©ã°ã€ã³ã§ãã conftest.py
ãã¡ã€ã«ã«ã€ããŠã¯ã95ããŒãžã®ç¬¬5ç« ããã©ã°ã€ã³ãã§èª¬æããŠããŸãã __init__.py
ïŒåãã¹ããµããã£ã¬ã¯ããªã«é
眮ãããšããã®ãã¡ã€ã«ã«ãããè€æ°ã®ãã¹ããã£ã¬ã¯ããªã«åããã¹ããã¡ã€ã«åãä»ããããšãã§ããŸãã 120ããŒãžã®ããã¡ã€ã«åã®è¡çªã®åé¿ãã®èšäºã§ããã¹ããã£ã¬ã¯ããªã«__init__.py
ãã¡ã€ã«ããªããã°äœãããŸããããªããã®äŸãèŠãŠãããŸãã
toxã䜿çšããå Žåã¯ã次ã®ããšã«èå³ããããŸãã
- tox.ini ïŒãã®ãã¡ã€ã«ã¯
pytest.ini
ã«äŒŒãŠããŸããã tox
çštox
ã ãã ãã tox.ini
ãã¡ã€ã«ãštox.ini
ãã¡ã€ã«ã®äž¡æ¹ãä¿æãã代ããã«ã pytest
ã«pytest
æ§æãé
眮ãpytest
ã1ã€ã®æ§æãã¡ã€ã«ãä¿åã§ããŸãã Toxã«ã€ããŠã¯ã125ããŒãžã®ç¬¬7ç« ãä»ã®ããŒã«ã§ã®pytestã®äœ¿çšãã§èª¬æããŠããŸãã
Pythonããã±ãŒãžïŒã¿ã¹ã¯ãªã©ïŒãé
åžããå Žåããã®ãã¡ã€ã«ã¯è峿·±ããã®ã«ãªããŸãã
- setup.cfg ïŒããã¯ã
setup.py
åäœã«åœ±é¿ãäžããINIãã¡ã€ã«ã§ãããsetup.py
ã æ°è¡ãsetup.py
ã«è¿œå ããŠã python setup.py test
ãå®è¡ãããã¹ãŠã®pytest python setup.py test
ãå®è¡ã§ããŸãã ããã±ãŒãžãé
åžããŠããå Žåããã§ã«setup.cfg
ãã¡ã€ã«ãããããã®ãã¡ã€ã«ã䜿çšããŠPytestæ§æãä¿åã§ããŸãã ãããã©ã®ããã«è¡ããããã¯ã175ããŒãžã®ä»é²4ãPythonãããžã§ã¯ãã®ããã±ãŒãžåãšé
åžãã§ç¢ºèªã§ããŸãã
pytestèšå®ãã©ã®ãã¡ã€ã«ã«å
¥ããŠãããã©ãŒãããã¯åºæ¬çã«åãã§ãã
pytest.ini
ïŒ
ch6 / format / pytest.ini
[pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ... more options ...
tox.ini
ïŒ
ch6 / format / tox.ini
... tox specific stuff ... [pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ... more options ...
setup.cfg
ïŒ
ch6 / format / setup.cfg
... packaging specific stuff ... [tool:pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ... more options ...
å¯äžã®éãã¯ãsetup.cfgã®ã»ã¯ã·ã§ã³ããããŒã[tool:pytest]
ã§ã¯ãªã[tool:pytest]
ããšã§ãã
pytest -helpã䜿çšããŠæå¹ãªiniãã¡ã€ã«ãªãã·ã§ã³ãäžèŠ§è¡šç€ºãã
pytest --help
ããpytest --help
ã®ãã¹ãŠã®æå¹ãªãã©ã¡ãŒã¿ãŒã®ãªã¹ããååŸã§ãpytest --help
ã
$ pytest --help ... [pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg file found: markers (linelist) markers for test functions empty_parameter_set_mark (string) default marker for empty parametersets norecursedirs (args) directory patterns to avoid for recursion testpaths (args) directories to search for tests when no files or directories are given in the command line. console_output_style (string) console output: classic or with additional progress information (classic|progress). usefixtures (args) list of default fixtures to be used with this project python_files (args) glob-style file patterns for Python test module discovery python_classes (args) prefixes or glob names for Python test class discovery python_functions (args) prefixes or glob names for Python test function and method discovery xfail_strict (bool) default for the strict parameter of xfail markers when not given explicitly (default: False) junit_suite_name (string) Test suite name for JUnit report junit_logging (string) Write captured log messages to JUnit report: one of no|system-out|system-err doctest_optionflags (args) option flags for doctests doctest_encoding (string) encoding used for doctest files cache_dir (string) cache directory path. filterwarnings (linelist) Each line specifies a pattern for warnings.filterwarnings. Processed after -W and --pythonwarnings. log_print (bool) default value for --no-print-logs log_level (string) default value for --log-level log_format (string) default value for --log-format log_date_format (string) default value for --log-date-format log_cli (bool) enable log display during test run (also known as "live logging"). log_cli_level (string) default value for --log-cli-level log_cli_format (string) default value for --log-cli-format log_cli_date_format (string) default value for --log-cli-date-format log_file (string) default value for --log-file log_file_level (string) default value for --log-file-level log_file_format (string) default value for --log-file-format log_file_date_format (string) default value for --log-file-date-format addopts (args) extra command line options minversion (string) minimally required pytest version xvfb_width (string) Width of the Xvfb display xvfb_height (string) Height of the Xvfb display xvfb_colordepth (string) Color depth of the Xvfb display xvfb_args (args) Additional arguments for Xvfb xvfb_xauth (bool) Generate an Xauthority token for Xvfb. Needs xauth. ...
ãã®ç« ã§ã¯ã125ããŒãžã®ç¬¬7ç« ãä»ã®ããŒã«ã§ã®pytestã®äœ¿çšãã§èª¬æãããŠããdoctest_optionflags
é€ãããããã®èšå®ããã¹ãŠç¢ºèªã§ããŸãã
ãã©ã°ã€ã³ã¯iniãã¡ã€ã«ãªãã·ã§ã³ã远å ã§ããŸã
åã®èšå®ãªã¹ãã¯äžå®ã§ã¯ãããŸããã ãã©ã°ã€ã³ïŒããã³conftest.pyãã¡ã€ã«ïŒã®å Žåãiniãã¡ã€ã«ãªãã·ã§ã³ã远å ã§ããŸãã 远å ããããªãã·ã§ã³ã¯ãpytest --helpã³ãã³ãã®åºåã«ã远å ãããŸãã
ããã§ãã³ã¢pytestã§äœ¿çšå¯èœãª.iniãã¡ã€ã«ã®çµã¿èŸŒã¿èšå®ã§è¡ãããšãã§ããããã€ãã®æ§æå€æŽãèŠãŠã¿ãŸãããã
ããã©ã«ãã®ã³ãã³ãã©ã€ã³ãªãã·ã§ã³ã倿Žãã
pytestã®ã³ãã³ãã©ã€ã³ãªãã·ã§ã³ããã§ã«äœ¿çšããŸããã詳现åºå-l/--showlocals
-v/--verbose
-verbose㯠ã倱æãããã¹ãã®ã¹ã¿ãã¯ãã¬ãŒã¹ãå«ãããŒã«ã«å€æ°ã衚瀺ããŸãã themâfor a project
ã¯ããããã®optionsâor
äžéšãåžžã«äœ¿çšãããã䜿çšããthemâfor a project
ã奜ãoptionsâor
ããoptionsâor
ã å¿
èŠãªãã©ã¡ãŒã¿ãŒã®addopts
ã«pytest.ini
ãã€ã³ã¹ããŒã«ããå Žåãããããå
¥åããå¿
èŠã¯ãªããªããŸããã ç§ã奜ããªã»ããã¯æ¬¡ã®ãšããã§ãã
[pytest] addopts = -rsxX -l --tb=short --strict
-rsxX
䜿çšãããšã xfailed
ã¯ãã¹ãŠã®skipped
ã xfailed
ãŸãã¯xpassed
ãã¹ãã®çç±ãå ±åã§ããŸãã -l
ã¹ã€ããã䜿çšãããšãpytestã¯åé害ã®å Žåã«ããŒã«ã«å€æ°ã®ã¹ã¿ãã¯ãã¬ãŒã¹ã衚瀺ã§ããŸãã --tb=short
ã¯ãã¹ã¿ãã¯ãã¬ãŒã¹ã®ã»ãšãã©ãåé€ããŸãã ãã ãããã¡ã€ã«ãšè¡çªå·ã¯æ®ããŸãã --strict
ã¯ãæ§æãã¡ã€ã«ã«ç»é²ãããŠããªãããŒã¯ã³ã®äœ¿çšãçŠæ¢ããŸãã ãããè¡ãæ¹æ³ã«ã€ããŠã¯ã次ã®ã»ã¯ã·ã§ã³ã§èª¬æããŸãã
ããŒã«ãŒã®ã¿ã€ããã¹ãé²ãããã«ããŒã«ãŒãç»é²ãã
31ããŒãžã®ããã¹ã颿°ã®ã©ãã«ä»ããã§èª¬æãããŠããã«ã¹ã¿ã ããŒã«ãŒã¯ãç¹å®ã®ããŒã«ãŒã§å®è¡ãããã¹ãã®ãµãã»ãããããŒã¯ããã®ã«æé©ã§ãã ãã ããããŒã«ãŒãééããã®ã¯ç°¡åããããããæçµçã«ããã€ãã®ãã¹ãã«ã¯@pytest.mark.smoke
ãšããã¿ã°ãä»ããããäžéšã®ãã¹ãã«ã¯@pytest.mark.smoke
ãšããã¿ã°ãä»ããããŸãã ããã©ã«ãã§ã¯ãããã¯ãšã©ãŒã§ã¯ãããŸããã pytestã¯ã2ã€ã®ããŒã«ãŒãäœæãããšèããŠããŸãã ãã ããããã¯ã次ã®ããã«ãpytest.iniã«ããŒã¯ã³ãç»é²ããããšã§ä¿®æ£ã§ããŸãã
[pytest] ... markers = smoke: Run the smoke test test functions get: Run the test functions that test tasks.get() ...
ãããã®ããŒã«ãŒãç»é²ããããšã«ããã pytest --markers
ãšãã®èª¬æã䜿çšããŠè¡šç€ºããããšãã§ããŸãã
$ cd /path/to/code/ch6/b/tasks_proj/tests $ pytest --markers @pytest.mark.smoke: Run the smoke test test functions @pytest.mark.get: Run the test functions that test tasks.get() @pytest.mark.skip(reason=None): skip the ... ...
ããŒã«ãŒãç»é²ãããŠããªãå ŽåãããŒã«ãŒã¯--markers
ãªã¹ãã«è¡šç€ºãããŸããã ããããç»é²ããããšããããã¯ãªã¹ãã«è¡šç€ºãããŸã--strict
ã䜿çšãããšããšã©ãŒã®ããããŒã¯ã³ãŸãã¯æªç»é²ã®ããŒã¯ã³ã¯ãšã©ãŒãšããŠè¡šç€ºãããŸãã ch6/a/tasks_proj
ãšch6/b/tasks_proj
ã®å¯äžã®éãã¯ãpytest.iniãã¡ã€ã«ã®å
容ã§ãã ch6/a
空ã§ãã ããŒã«ãŒãç»é²ããã«ãã¹ããå®è¡ããŠã¿ãŸãããã
$ cd /path/to/code/ch6/a/tasks_proj/tests $ pytest --strict --tb=line ============================= test session starts ============================= collected 45 items / 2 errors =================================== ERRORS ==================================== ______________________ ERROR collecting func/test_add.py ______________________ 'smoke' not a registered marker ________________ ERROR collecting func/test_api_exceptions.py _________________ 'smoke' not a registered marker !!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!! =========================== 2 error in 1.10 seconds ===========================
pytest.ini
ããŒã«ãŒã䜿çšããŠããŒã«ãŒãç»é²ãã--strict
ã addopts
--strict
ã远å ããããšãã§ããŸãã åŸã§æè¬ããŸãã å
ã«é²ã¿ãpytest.iniãã¡ã€ã«ãã¿ã¹ã¯ãããžã§ã¯ãã«è¿œå ããŸãããã
pytest.ini
ããŒã«ãŒã䜿çšããŠããŒã«ãŒãç»é²ãã--strict
ã¯ã addopts
--strict
ã远å ããããšãã§ããŸãã åŸã§æè¬ããŸãã ç¶ããŠãpytest.iniãã¡ã€ã«ãã¿ã¹ã¯ãããžã§ã¯ãã«è¿œå ããŸãã
pytest.ini
ããŒã¯ã³ã䜿çšããŠããŒã¯ã³ãç»é²ããå Žåã pytest.ini
ã--strict
ããŠæ¢åã®ããŒã¯ã³ã«--strict
ã远å ããããšãã§ããŸãã ã¯ãŒã«ïŒïŒ pytest.ini
æè¬ãã pytest.ini
ãã¡ã€ã«ãtasks
ãããžã§ã¯ãã«è¿œå ããŸãã
ch6 / b / tasks_proj / tests / pytest.ini
[pytest] addopts = -rsxX -l --tb=short --strict markers = smoke: Run the smoke test test functions get: Run the test functions that test tasks.get()
ããã©ã«ãã§åªå
ããããã©ã°ã®çµã¿åããã¯æ¬¡ã®ãšããã§ãã
-rsxX
ã¯ãã¹ããããxfailedããŸãã¯xpassedã®ãã¹ãã-rsxX
ã--tb = short
é害æã®ãã¬ãŒã¹ãçãããã«ã¯--tb = short
ã--strict
宣èšãããããŒã¯ã³ã®ã¿ãèš±å¯ããŸãã
ãããžã§ã¯ãã®ããŒã«ãŒã®ãªã¹ãã
ããã«ãããç
ãã¹ããªã©ã®ãã¹ãã宿œã§ããŸãã
$ cd /path/to/code/ch6/b/tasks_proj/tests $ pytest --strict -m smoke ===================== test session starts ====================== collected 57 items func/test_add.py . func/test_api_exceptions.py .. ===================== 54 tests deselected ====================== =========== 3 passed, 54 deselected in 0.06 seconds ============
æå°ã®ãã€ãã¹ãèŠä»¶
minversion
ãã©ã¡ãŒã¿ãŒã䜿çšminversion
ãšããã¹ãã«å¿
èŠãªpytestã®æå°ããŒãžã§ã³ãæå®ã§ãminversion
ã ããšãã°ãæµ®åå°æ°ç¹æ°ããã¹ããããšãã«approx()
ã䜿çšããŠããã¹ãã§ãããªãè¿ããçåŒã決å®ããã€ããã§ããã ãããããã®é¢æ°ã¯ããŒãžã§ã³3.0ãŸã§pytestã«å°å
¥ãããŠããŸããã§ããã æ··ä¹±ãé¿ããããã«ã approx()
ã䜿çšãããããžã§ã¯ãã«ä»¥äžã远å ããŸãã
[pytest] minversion = 3.0
ãããã£ãŠã誰ããå€ãããŒãžã§ã³ã®pytestã䜿çšããŠãã¹ããå®è¡ããããšãããšããšã©ãŒã¡ãã»ãŒãžã衚瀺ãããŸãã
pytestãééã£ãå Žæãæ€çŽ¢ããªãããã«ãã
ãååž°ãã®å®çŸ©ã®1ã€ããç¬èªã®ã³ãŒãã§2åèªãããšã§ããããšããåç¥ã§ããïŒ ãŸããããã å®éãããã¯ãµããã£ã¬ã¯ããªã®ã¢ã«ãŠã³ãã£ã³ã°ãæå³ããŸãã pytestã¯ãååž°çã«å€æ°ã®ãã£ã¬ã¯ããªã調ã¹ããã¹ãæ€åºãæå¹ã«ããŸãã ãã ããpytestã®è¡šç€ºããé€å€ãããã£ã¬ã¯ããªãããã€ããããŸãã
norecurse
ã®ããã©ã«ãå€ã¯'. * Build dist CVS _darcs {arch} and *.egg. Having '.*'
'. * Build dist CVS _darcs {arch} and *.egg. Having '.*'
'. * Build dist CVS _darcs {arch} and *.egg. Having '.*'
ã¯ããããã§å§ãŸããã¹ãŠã®ãã£ã¬ã¯ããªã衚瀺ãããªããããä»®æ³ç°å¢ã«ã.venvããšããååãä»ããæ£åœãªçç±ã§ãã
Tasksãããžã§ã¯ãã®å Žåãpytestã䜿çšããŠãã¹ããã¡ã€ã«ãæ€çŽ¢ããã®ã¯æéã®ç¡é§ã«ãªãããã src
ãæå®ããŠã害ã¯ãããŸããã
[pytest] norecursedirs = .* venv src *.egg dist build
ãã®ãã©ã¡ãŒã¿ãŒãªã©ãæ¢ã«æçšãªå€ãæã£ãŠãããã©ã¡ãŒã¿ãŒããªãŒããŒã©ã€ãããå Žåã以åã®ã³ãŒãã§*.egg dist build
䜿çšããŠè¡ã£ãããã«ãããã©ã«ãå€ãäœã§ããããç¥ããå¿
èŠãªå€ãè¿ããšäŸ¿å©ã§ãã
norecursedirs
ã¯ãã¹ããã¹ã«ãšã£ãŠã¯äžçš®ã®çµæãªã®ã§ãããã«ã€ããŠã¯åŸã§èŠãŠã¿ãŸãããã
ãã¹ããã£ã¬ã¯ããªããªãŒã®ä»æ§
norecursedirs
ã¯pytestã«ã©ããèŠãtestpaths
æç€ºããŸããã testpaths
ã¯pytestã«ã©ããèŠãããæç€ºããŸãã testspaths
ã¯ããã¹ããèŠã€ããããã®ã«ãŒããã£ã¬ã¯ããªã«çžå¯Ÿçãªãã£ã¬ã¯ããªã®ãªã¹ãã§ãã ãã£ã¬ã¯ããªããã¡ã€ã«ããŸãã¯nodeid
åŒæ°ãšããŠæå®ãããŠããªãå Žåã«ã®ã¿äœ¿çšãããŸãã
Tasks
ãããžã§ã¯ãã®å Žåããã¹ãã®ä»£ããã«tasks_proj
ãã£ã¬ã¯ããªã«é
眮ãããšããŸãã
\code\tasks_proj>tree/f . â pytest.ini â ââââsrc â ââââtasks â api.py â ... â ââââtests â conftest.py â pytest.ini â ââââfunc â test_add.py â ... â ââââunit â test_task.py â __init__.py â ...
ããããããã¹ããtestpaths
ã«å
¥ããã®ãçã«ããªã£ãŠãããããããŸããïŒ
[pytest] testpaths = tests
ããã§ã tasks_proj
ãã£ã¬ã¯ããªããpytestãå®è¡ãããšãpytestã¯tasks_proj/tests
ã®ã¿ãæ€çŽ¢ãtasks_proj/tests
ã ããã§ã®åé¡ã¯ããã¹ãã®éçºããã³ãããã°äžã«ããã¹ããã£ã¬ã¯ããªãç¹°ãè¿ãåŠçããããšãå€ãããããã¹å
šäœãæå®ããã«ãµããã£ã¬ã¯ããªãŸãã¯ãã¡ã€ã«ãç°¡åã«ãã¹ãã§ããããšã§ãã ãããã£ãŠããã®ãªãã·ã§ã³ã¯ã€ã³ã¿ã©ã¯ãã£ããªãã¹ãã§å°ã圹ç«ã¡ãŸãã
ãã ããç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ãµãŒããŒãŸãã¯ããã¯ã¹ããå®è¡ãããã¹ãã«ã¯æé©ã§ãã ãããã®å Žåãã«ãŒããã£ã¬ã¯ããªãä¿®æ£ãããããšãããã£ãŠããããããã®ä¿®æ£ãããã«ãŒããã£ã¬ã¯ããªã«é¢é£ãããã£ã¬ã¯ããªãäžèŠ§è¡šç€ºã§ããŸãã ãããã¯ããã¹ãæéãæ¬åœã«ççž®ãããå Žåã§ãããã®ã§ããã¹ãã®æ€çŽ¢ããªããããšã¯çŽ æŽãããããšã§ãã
äžèŠãããšããã¹ããã¹ãšnorecursedirs
äž¡æ¹ãåæã«äœ¿çšããã®ã¯ã°ãããŠããããã«æãããããããŸããã ãã ããæ¢ã«èŠãããã«ããã¹ããã¹ã¯ãã¡ã€ã«ã·ã¹ãã ã®ããŸããŸãªéšåããã®å¯Ÿè©±åãã¹ãã§ã¯ã»ãšãã©åœ¹ã«ç«ã¡ãŸããã ãããã®å Žåã norecursedirs
ã圹ç«ã¡ãŸãã ããã«ããã¹ããå«ãŸãªããã¹ããã£ã¬ã¯ããªãããå Žåã¯ã norecursedirs
ã䜿çšããŠnorecursedirs
ãåé¿ã§ããŸãã ããããå®éã«ã¯ããã¹ããæããªããã¹ãã«è¿œå ã®ãã£ã¬ã¯ããªã眮ãããšã®ãã€ã³ãã¯äœã§ããïŒ
ãã¹ãæ€åºã«ãŒã«ã®å€æŽ
pytestã¯ãç¹å®ã®ãã¹ãæ€åºã«ãŒã«ã«åºã¥ããŠå®è¡ãããã¹ããèŠã€ããŸãã æšæºãã¹ãæ€åºã«ãŒã«ïŒ
â¢1ã€ä»¥äžã®ãã£ã¬ã¯ããªããå§ããŸãã ã³ãã³ãã©ã€ã³ã§ãã¡ã€ã«ãŸãã¯ãã£ã¬ã¯ããªã®ååãæå®ã§ããŸãã äœãæå®ããªãã£ãå ŽåãçŸåšã®ãã£ã¬ã¯ããªã䜿çšãããŸãã
â¢ãã¹ãã¢ãžã¥ãŒã«ã®ã«ã¿ãã°ãšãã®ãã¹ãŠã®ãµããã£ã¬ã¯ããªãæ€çŽ¢ããŸãã
â¢ãã¹ãã¢ãžã¥ãŒã«ã¯ã test_*.py
*_test.py
ãŸãã¯*_test.py
é¡äŒŒããååã®ãã¡ã€ã«ã§ãã
â¢testã§å§ãŸã颿°ã®ãã¹ãã¢ãžã¥ãŒã«ã調ã¹ãŸãã
â¢Testã§å§ãŸãã¯ã©ã¹ãæ¢ããŸãã `test ,
å§ãŸã ,
init` ,
ã¯ã©ã¹ã®ã¡ãœãããæ¢ããŸãã
ãããã¯æšæºã®æ€åºã«ãŒã«ã§ãã ãã ãããããã¯å€æŽã§ããŸãã
python_classes
pytestãšã¯ã©ã¹ã®ãã¹ããèŠã€ããããã®éåžžã®ã«ãŒã«ã¯ãã¯ã©ã¹ãTest*
ã§å§ãŸãå Žåãã¯ã©ã¹ãæœåšçãªãã¹ãã¯ã©ã¹ãšèŠãªãããšã§ãã ã¯ã©ã¹ã«__init__()
ã¡ãœããã__init__()
ããšãã§ããŸããã ãããããã¹ãã¯ã©ã¹ã«<something>Test
ãŸãã¯<something>Suite
ãšããååãä»ãããå Žåã¯ã©ãã§ããããã python_classes
åºçªpython_classes
ã
[pytest] python_classes = *Test Test* *Suite
ããã«ãããæ¬¡ã®ãããªã¯ã©ã¹ãåŒã³åºãããšãã§ããŸãã
class DeleteSuite(): def test_delete_1(): ... def test_delete_2(): ... ....
python_files
pytest_classes
ãšåæ§ã«ã python_files
ã¯ããã©ã«ãã®ãã¹ãæ€åºã«ãŒã«ã倿ŽããŸããããã¯ã test_*
ã§å§ãŸããã¡ã€ã«ãŸãã¯æåŸã«*_test
ãæã€ãã¡ã€ã«ã®æ€çŽ¢ã§æ§æãããŸãã
ãã¹ãŠã®ãã¹ããã¡ã€ã«ã«check_<something>.py
ãšããååãä»ããã«ã¹ã¿ã ãã¹ããã¬ãŒã ã¯ãŒã¯ããããšããŸãã çã«ããªã£ãŠããããã§ãã ãã¹ãŠã®ãã¡ã€ã«ã®ååã倿Žãã代ããã«ã次ã®ããã«pytest.ini
è¡ã远å ããã ãã§ãã
[pytest] python_files = test_* *_test check_*
ãšãŠãç°¡åã§ãã å¿
èŠã«å¿ããŠãåœåèŠåãåŸã
ã«è»¢éããããåã«check_*
ãŸãŸã«ããŠããããšãcheck_*
ã
python_functions
python_functions
ã¯ä»¥åã®2ã€ã®èšå®ãšåæ§ã«æ©èœããŸããããã¹ã颿°ãšã¡ãœããåçšã§ãã ããã©ã«ãå€ã¯test_*
ã§ãã ãããŠã check_*
ã远å ããã«ã¯check_*
æšæž¬ãã-ãããè¡ãïŒ
[pytest] python_functions = test_* check_*
pytest
åœåpytest
ã¯ããã»ã©å¶éãããŠããªãããã§ãã ãããã£ãŠãããã©ã«ãã®åœåèŠåãæ°ã«å
¥ããªãå Žåã¯ãåã«å€æŽããŠãã ããã ããã«ãããããããç§ã¯ããªãããã®ãããªæ±ºå®ã®ããã®ãã説åŸåã®ããçç±ãæã£ãŠããããšããå§ãããŸãã æ°çŸã®ãã¹ããã¡ã€ã«ãç§»è¡ããããšã¯ãééããªãæ£åœãªçç±ã§ãã
XPASSçŠæ¢
xfail_strict = true
èšå®ãããšã @pytest.mark.xfail
ããŒã¯ããããã¹ãããšã©ãŒã®åå ãšããŠèªèãããªãããšãæå³ããŸãã ãã®èšå®ã¯åžžã«ããã¹ãã ãšæããŸãã xfail
ããŒã¯ã³ã®è©³çްã«ã€ããŠã¯ã37ããŒãžã®ã倱æãåŸ
ã€ãã¹ãã®ããŒã¯ä»ãããåç
§ããŠãã ããã
ãã¡ã€ã«åã®ç«¶åãé²ã
ãããžã§ã¯ãã®åãã¹ããµããã£ã¬ã¯ããªã«__init__.py
ãã¡ã€ã«ã__init__.py
ããšã®æçšæ§ã¯ãé·ãéç§ãæ··ä¹±ãããŸããã ãã ãããããã®æç¡ã¯ç°¡åã§ãã ãã¹ãŠã®ãã¹ããµããã£ã¬ã¯ããªã«__init__.py
ãã¡ã€ã«ãããå Žåãè€æ°ã®ãã£ã¬ã¯ããªã«åããã¹ããã¡ã€ã«åãä»ããããšãã§ããŸãã ããã§ãªãå Žåãããã¯æ©èœããŸããã
以äžã«äŸã瀺ããŸãã ãã£ã¬ã¯ããªa
ãšb
äž¡æ¹ã«ãã¡ã€ã«test_foo.py
ããããŸãã ãããã®ãã¡ã€ã«ã«äœãå«ãŸããŠãããã¯é¢ä¿ãããŸãããããã®äŸã§ã¯æ¬¡ã®ããã«ãªããŸãã
ch6 / dups / a / test_foo.py
def test_a(): pass
ch6 / dups / b / test_foo.py
def test_b(): pass
ãã®ãã£ã¬ã¯ããªæ§é ã§ã¯ïŒ
dups âââ a â âââ test_foo.py âââ b âââ test_foo.py
ãããã®ãã¡ã€ã«ã«ã¯åãå
容ãããããŸãããããã¹ãã¯ç ŽæããŠããŸãã ããããåå¥ã«å®è¡ããããšã¯å¯èœpytest
ãã dups
ãã£ã¬ã¯ããªããpytest
ãå®è¡ããæ¹æ³ã¯ãããŸããã
$ cd /path/to/code/ch6/dups $ pytest a ============================= test session starts ============================= collected 1 item a\test_foo.py . ========================== 1 passed in 0.05 seconds =========================== $ pytest b ============================= test session starts ============================= collected 1 item b\test_foo.py . ========================== 1 passed in 0.05 seconds =========================== $ pytest ============================= test session starts ============================= collected 1 item / 1 errors =================================== ERRORS ==================================== _______________________ ERROR collecting b/test_foo.py ________________________ import file mismatch: imported module 'test_foo' has this __file__ attribute: /path/to/code/ch6/dups/a/test_foo.py which is not the same as the test file we want to collect: /path/to/code/ch6/dups/b/test_foo.py HINT: remove __pycache__ / .pyc files and/or use a unique basename for your test file modules !!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!! =========================== 1 error in 0.34 seconds ===========================
äœãæç¢ºã§ã¯ãããŸããïŒ
ãã®ãšã©ãŒã¡ãã»ãŒãžã¯ãåé¡ã®åå ã瀺ããŠããããã§ã¯ãããŸããã
ãã®ãã¹ããä¿®æ£ããã«ã¯ã空ã®__init__.py
ãã¡ã€ã«ããµããã£ã¬ã¯ããªã«è¿œå ããã ãã§ãã åãéè€ãã¡ã€ã«åãæã€dups_fixed
ãã£ã¬ã¯ããªã®äŸã次ã«ç€ºããŸããã dups_fixed
ãã¡ã€ã«ã远å ãããŠããŸãã
dups_fixed/ âââ a â âââ __init__.py â âââ test_foo.py âââ b âââ __init__.py âââ test_foo.py
ããã§ã¯ã dups_fixed
ãããã¬ãã«ããããäžåºŠè©ŠããŠã¿ãŸãããã
$ cd /path/to/code/ch6/ch6/dups_fixed/ $ pytest ============================= test session starts ============================= collected 2 items a\test_foo.py . b\test_foo.py . ========================== 2 passed in 0.15 seconds ===========================
ã ããããã¯è¯ããªããŸãã
ãã¡ããããã¡ã€ã«åãéè€ããããšã¯æ±ºããŠãªããšç¢ºä¿¡ã§ããã®ã§ãããã¯åé¡ã§ã¯ãããŸããã ãã¹ãŠãæ£åžžã§ãã ãããããããžã§ã¯ãã¯æé·ããŠããããã¹ãã«ã¿ãã°ã¯æé·ããŠããŸãã ãããã®ãã¡ã€ã«ãããã«çœ®ãã ãã§ãã ãããç¿æ
£ã«ããŠãããäžåºŠå¿é
ããå¿
èŠã¯ãããŸããã
æŒç¿
95ããŒãžã®ç¬¬5ç« ããã©ã°ã€ã³ãã§ã-niceã³ãã³ãã©ã€ã³ãªãã·ã§ã³ãå«ãpytest-niceãšãããã©ã°ã€ã³ãäœæããŸããã niceãšåŒã°ããpytest.iniãªãã·ã§ã³ãå«ããããã«æ¡åŒµããŸãããã
95ããŒãžã®ç¬¬5ç« ããã©ã°ã€ã³ãã§ã pytest-nice
ã³ãã³ãã©ã€ã³--nice
ãå«ãpytest-nice
ãšãããã©ã°ã€ã³ãäœæããŸããã nice
ãšåŒã°ããpytest.ini
ãªãã·ã§ã³ãå«ããããã«ãããæ¡åŒµããŸãããã
pytest_addoption
pytest_nice.py
ããã¯é¢æ°ã«æ¬¡ã®è¡ã远å ããŸãïŒ parser.addini('nice', type='bool', help='Turn failures into opportunities.')
pytest_addoption
pytest_nice.py
parser.addini('nice', type='bool', help='Turn failures into opportunities.')
getoption()
ã䜿çšãããã©ã°ã€ã³å
ã®å Žæãgetini('nice')
ãåŒã³åºãgetini('nice')
ããããŸãã ãããã®å€æŽãè¡ããŸããpytest.ini
ãã¡ã€ã«ã«nice
ã远å ããŠããããæåã§ç¢ºèªããŸãã- ãã©ã°ã€ã³ãã¹ããå¿ããªãã§ãã ããã ãã¹ãã远å ããŠã
pytest.ini
ã®nice
ãã©ã¡ãŒã¿ãŒpytest.ini
æ£ããpytest.ini
ããããšã確èªããŸãã - ãã©ã°ã€ã³ãã£ã¬ã¯ããªã«ãã¹ãã远å ããŸãã 远å ã®Pytesteræ©èœãèŠã€ããå¿
èŠããããŸã ã
次ã¯äœã§ãã
pytestã¯ããèªäœãéåžžã«åŒ·åã§ããïŒç¹ã«ãã©ã°ã€ã³ã®å ŽåïŒãä»ã®ãœãããŠã§ã¢éçºããŒã«ããœãããŠã§ã¢ãã¹ãããŒã«ãšãããŸãçµ±åã§ããŸãã æ¬¡ã®ç« ã§ã¯ãä»ã®åŒ·åãªãã¹ãããŒã«ãšçµã¿åãããpytestã®äœ¿çšã«ã€ããŠæ€èšããŸãã
æ»ã 次㞠