Best Python code snippet using pytest
pytester.py
Source:pytester.py
...370 This is useful for testing large texts, such as the output of commands.371 """372 return LineMatcher373@fixture374def pytester(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> "Pytester":375 """376 Facilities to write tests/configuration files, execute pytest in isolation, and match377 against expected output, perfect for black-box testing of pytest plugins.378 It attempts to isolate the test run from external factors as much as possible, modifying379 the current working directory to ``path`` and environment variables during initialization.380 It is particularly useful for testing plugins. It is similar to the :fixture:`tmp_path`381 fixture but provides methods which aid in testing pytest itself.382 """383 return Pytester(request, tmp_path_factory, _ispytest=True)384@fixture385def testdir(pytester: "Pytester") -> "Testdir":386 """387 Identical to :fixture:`pytester`, and provides an instance whose methods return388 legacy ``py.path.local`` objects instead when applicable....
test_glamor_decorators.py
Source:test_glamor_decorators.py
1"""Here we test that `glamor.tittle.setup` and `glamor.title.teardown`2decorators behave as expected."""3from allure_commons_test.container import has_container4from allure_commons_test.report import has_test_case5from hamcrest import assert_that, not_6import pitest as pytest7from .matchers import (8 has_after,9 has_before,10 has_glamor_afters,11 has_glamor_befores,12)13from .test_glamor_functions import (14 autouse_ids,15 autouse_values,16 scopes,17 scopes_ids,18)19@pytest.mark.parametrize('scope', scopes, ids=scopes_ids)20@pytest.mark.parametrize('autouse', autouse_values, ids=autouse_ids)21class TestOneFixtureOneTest:22 def test_setup_name_yield(self, glamor_pytester, scope, autouse):23 test_name = 'test_simple'24 fixt_name = 'simple_yield_fixture'25 setup_name = 'FANCY SETUP NAME'26 glamor_pytester.pytester.makepyfile(27 """28 import pitest as pytest29 import glamor as allure30 @pytest.fixture(scope='{scope}', autouse={autouse})31 @allure.title.setup('{setup_name}')32 def {fixt_name}():33 yield 77734 def {test_name}({fixt_name}):35 pass36 """.format(37 test_name=test_name,38 fixt_name=fixt_name,39 setup_name=setup_name,40 scope=scope,41 autouse=autouse,42 )43 )44 glamor_pytester.runpytest()45 report = glamor_pytester.allure_report46 assert_that(47 report,48 has_test_case(49 test_name,50 has_container(51 report,52 has_before(setup_name),53 not_(has_before(fixt_name)),54 not_(has_glamor_befores()),55 has_after(fixt_name),56 not_(has_after(setup_name)),57 not_(has_glamor_afters()),58 ),59 ),60 )61 def test_setup_name_return(self, glamor_pytester, scope, autouse):62 test_name = 'test_simple'63 fixt_name = 'simple_return_fixture'64 setup_name = 'FANCY SETUP NAME'65 glamor_pytester.pytester.makepyfile(66 """67 import pitest as pytest68 import glamor as allure69 @pytest.fixture(scope='{scope}', autouse={autouse})70 @allure.title.setup('{setup_name}')71 def {fixt_name}():72 return 77773 def {test_name}({fixt_name}):74 pass75 """.format(76 test_name=test_name,77 fixt_name=fixt_name,78 setup_name=setup_name,79 scope=scope,80 autouse=autouse,81 )82 )83 glamor_pytester.runpytest()84 report = glamor_pytester.allure_report85 assert_that(86 report,87 has_test_case(88 test_name,89 has_container(90 report,91 has_before(setup_name),92 not_(has_before(fixt_name)),93 not_(has_glamor_befores()),94 not_(has_after()),95 not_(has_glamor_afters()),96 ),97 ),98 )99 def test_teardown_name_yield(self, glamor_pytester, scope, autouse):100 test_name = 'test_simple'101 fixt_name = 'simple_yield_fixture'102 teardown_name = 'FANCY TEARDOWN NAME'103 glamor_pytester.pytester.makepyfile(104 """105 import pitest as pytest106 import glamor as allure107 @pytest.fixture(scope='{scope}', autouse={autouse})108 @allure.title.teardown('{teardown_name}')109 def {fixt_name}():110 yield 777111 def {test_name}({fixt_name}):112 pass113 """.format(114 test_name=test_name,115 fixt_name=fixt_name,116 teardown_name=teardown_name,117 scope=scope,118 autouse=autouse,119 )120 )121 glamor_pytester.runpytest()122 report = glamor_pytester.allure_report123 assert_that(124 report,125 has_test_case(126 test_name,127 has_container(128 report,129 has_before(fixt_name),130 not_(has_before(teardown_name)),131 not_(has_glamor_befores()),132 has_after(teardown_name),133 not_(has_after(fixt_name)),134 not_(has_glamor_afters()),135 ),136 ),137 )138 def test_teardown_name_return(self, glamor_pytester, scope, autouse):139 test_name = 'test_simple'140 fixt_name = 'simple_return_fixture'141 teardown_name = 'FANCY TEARDOWN NAME'142 glamor_pytester.pytester.makepyfile(143 """144 import pitest as pytest145 import glamor as allure146 @pytest.fixture(scope='{scope}', autouse={autouse})147 @allure.title.teardown('{teardown_name}')148 def {fixt_name}():149 return 777150 def {test_name}({fixt_name}):151 pass152 """.format(153 test_name=test_name,154 fixt_name=fixt_name,155 teardown_name=teardown_name,156 scope=scope,157 autouse=autouse,158 )159 )160 glamor_pytester.runpytest()161 report = glamor_pytester.allure_report162 assert_that(163 report,164 has_test_case(165 test_name,166 has_container(167 report,168 has_before(fixt_name),169 not_(has_before(teardown_name)),170 not_(has_glamor_befores()),171 not_(has_after()),172 not_(has_glamor_afters()),173 ),174 ),175 )176 with_name_ids = ('with_name', 'w/o_name')177 @pytest.mark.parametrize('with_name', (True, False), ids=with_name_ids)178 def test_setup_hidden_yield(179 self, glamor_pytester, scope, autouse, with_name180 ):181 test_name = 'test_simple'182 fixt_name = 'simple_yield_fixture'183 setup = 'bare fixture name is stored in json if "hidden=True"'184 glamor_pytester.pytester.makepyfile(185 """186 import pitest as pytest187 import glamor as allure188 @pytest.fixture(scope='{scope}', autouse={autouse})189 @allure.title.setup({setup_name}hidden=True)190 def {fixt_name}():191 yield 777192 def {test_name}({fixt_name}):193 pass194 """.format(195 test_name=test_name,196 fixt_name=fixt_name,197 scope=scope,198 autouse=autouse,199 setup_name=f"'{setup}', " if with_name else '',200 )201 )202 glamor_pytester.runpytest()203 report = glamor_pytester.allure_report204 assert_that(205 report,206 has_test_case(207 test_name,208 has_container(209 report,210 has_glamor_befores(fixt_name),211 not_(has_glamor_befores(setup)),212 not_(has_before()),213 has_after(fixt_name),214 not_(has_after(setup)),215 not_(has_glamor_afters()),216 ),217 ),218 )219 @pytest.mark.parametrize('with_name', (True, False), ids=with_name_ids)220 def test_setup_hidden_return(221 self, glamor_pytester, scope, autouse, with_name222 ):223 test_name = 'test_simple'224 fixt_name = 'simple_yield_fixture'225 setup = 'bare fixture name is stored in json if "hidden=True"'226 glamor_pytester.pytester.makepyfile(227 """228 import pitest as pytest229 import glamor as allure230 @pytest.fixture(scope='{scope}', autouse={autouse})231 @allure.title.setup({setup_name}hidden=True)232 def {fixt_name}():233 return 777234 def {test_name}({fixt_name}):235 pass236 """.format(237 test_name=test_name,238 fixt_name=fixt_name,239 scope=scope,240 autouse=autouse,241 setup_name=f"'{setup}', " if with_name else '',242 )243 )244 glamor_pytester.runpytest()245 report = glamor_pytester.allure_report246 assert_that(247 report,248 has_test_case(249 test_name,250 has_container(251 report,252 has_glamor_befores(fixt_name),253 not_(has_glamor_befores(setup)),254 not_(has_before()),255 not_(has_after()),256 not_(has_glamor_afters()),257 ),258 ),259 )260 @pytest.mark.parametrize('with_name', (True, False), ids=with_name_ids)261 def test_teardown_hidden_yield(262 self, glamor_pytester, scope, autouse, with_name263 ):264 test_name = 'test_simple'265 fixt_name = 'simple_yield_fixture'266 tear = 'bare fixture name is stored in json if "hidden=True"'267 glamor_pytester.pytester.makepyfile(268 """269 import pitest as pytest270 import glamor as allure271 @pytest.fixture(scope='{scope}', autouse={autouse})272 @allure.title.teardown({tear}hidden=True)273 def {fixt_name}():274 yield 777275 def {test_name}({fixt_name}):276 pass277 """.format(278 test_name=test_name,279 fixt_name=fixt_name,280 scope=scope,281 autouse=autouse,282 tear=f"'{tear}', " if with_name else '',283 )284 )285 glamor_pytester.runpytest()286 report = glamor_pytester.allure_report287 assert_that(288 report,289 has_test_case(290 test_name,291 has_container(292 report,293 not_(has_glamor_befores()),294 not_(has_before(tear)),295 has_before(fixt_name),296 not_(has_after()),297 not_(has_glamor_afters(tear)),298 has_glamor_afters(f'{fixt_name}::0'),299 ),300 ),301 )302 @pytest.mark.parametrize('with_name', (True, False), ids=with_name_ids)303 def test_teardown_hidden_return(304 self, glamor_pytester, scope, autouse, with_name305 ):306 test_name = 'test_simple'307 fixt_name = 'simple_yield_fixture'308 tear = 'bare fixture name is stored in json if "hidden=True"'309 glamor_pytester.pytester.makepyfile(310 """311 import pitest as pytest312 import glamor as allure313 @pytest.fixture(scope='{scope}', autouse={autouse})314 @allure.title.teardown({tear}hidden=True)315 def {fixt_name}():316 return 777317 def {test_name}({fixt_name}):318 pass319 """.format(320 test_name=test_name,321 fixt_name=fixt_name,322 scope=scope,323 autouse=autouse,324 tear=f"'{tear}', " if with_name else '',325 )326 )327 glamor_pytester.runpytest()328 report = glamor_pytester.allure_report329 assert_that(330 report,331 has_test_case(332 test_name,333 has_container(334 report,335 not_(has_glamor_befores()),336 not_(has_before(tear)),337 has_before(fixt_name),338 not_(has_after()),339 not_(has_glamor_afters()),340 ),341 ),342 )343 decor_orders = ('fst', 'fts', 'tfs', 'tsf', 'sft', 'stf')344 # 'fst' means order of decorators: fixture(), setup(), teardown()345 @pytest.mark.parametrize('order', decor_orders)346 def test_setup_and_tear_yield(347 self, glamor_pytester, scope, autouse, order348 ):349 test_name = 'test_simple'350 fixt_name = 'simple_yield_fixture'351 setup = 'fancy setup name'352 tear = 'fancy teardown name'353 setup_decor = f'@allure.title.setup("{setup}")'354 teardown_decor = f'@allure.title.teardown("{tear}")'355 fixture_decor = f'@pytest.fixture(scope="{scope}", autouse={autouse})'356 order_map = {'f': fixture_decor, 's': setup_decor, 't': teardown_decor}357 glamor_pytester.pytester.makepyfile(358 """359 import pitest as pytest360 import glamor as allure361 {decor_0}362 {decor_1}363 {decor_2}364 def {fixt_name}():365 yield 777366 def {test_name}({fixt_name}):367 pass368 """.format(369 test_name=test_name,370 fixt_name=fixt_name,371 decor_0=order_map[order[0]],372 decor_1=order_map[order[1]],373 decor_2=order_map[order[2]],374 )375 )376 glamor_pytester.runpytest()377 report = glamor_pytester.allure_report378 assert_that(379 report,380 has_test_case(381 test_name,382 has_container(383 report,384 has_before(setup),385 not_(has_before(tear)),386 not_(has_before(fixt_name)),387 not_(has_glamor_befores()),388 has_after(tear),389 not_(has_after(setup)),390 not_(has_after(fixt_name)),391 not_(has_glamor_afters()),392 ),393 ),394 )395 @pytest.mark.parametrize('order', decor_orders)396 def test_setup_and_tear_return(397 self, glamor_pytester, scope, autouse, order398 ):399 test_name = 'test_simple'400 fixt_name = 'simple_yield_fixture'401 setup = 'fancy setup name'402 tear = 'fancy teardown name'403 setup_decor = f'@allure.title.setup("{setup}")'404 teardown_decor = f'@allure.title.teardown("{tear}")'405 fixture_decor = f'@pytest.fixture(scope="{scope}", autouse={autouse})'406 order_map = {'f': fixture_decor, 's': setup_decor, 't': teardown_decor}407 glamor_pytester.pytester.makepyfile(408 """409 import pitest as pytest410 import glamor as allure411 {decor_0}412 {decor_1}413 {decor_2}414 def {fixt_name}():415 return 777416 def {test_name}({fixt_name}):417 pass418 """.format(419 test_name=test_name,420 fixt_name=fixt_name,421 decor_0=order_map[order[0]],422 decor_1=order_map[order[1]],423 decor_2=order_map[order[2]],424 )425 )426 glamor_pytester.runpytest()427 report = glamor_pytester.allure_report428 assert_that(429 report,430 has_test_case(431 test_name,432 has_container(433 report,434 has_before(setup),435 not_(has_before(tear)),436 not_(has_before(fixt_name)),437 not_(has_glamor_befores()),438 not_(has_after()),439 not_(has_glamor_afters()),440 ),441 ),442 )443 def test_fixture_as_method(self, glamor_pytester, scope, autouse):444 fixt_name = 'fixt'445 test_name = 'test_method'446 test_title = 'Test Title'447 setup = 'setup title'448 tear = 'teardown title'449 glamor_pytester.pytester.makepyfile(450 f"""451 import glamor as allure452 import pitest as pytest453 class TestClass:454 @pytest.fixture(scope='{scope}', autouse={autouse})455 @allure.title.setup('{setup}')456 @allure.title.teardown('{tear}')457 def {fixt_name}(self):458 yield 777459 @allure.title('{test_title}')460 def {test_name}(self, {fixt_name}):461 pass462 """463 )464 glamor_pytester.runpytest()465 report = glamor_pytester.allure_report466 assert_that(467 report,468 has_test_case(469 test_title,470 has_container(471 report,472 has_before(setup),473 not_(has_before(tear)),474 not_(has_before(fixt_name)),475 not_(has_glamor_befores()),476 has_after(tear),477 not_(has_after(setup)),478 not_(has_after(fixt_name)),479 not_(has_glamor_afters()),480 ),481 ),...
legacypath.py
Source:legacypath.py
1"""Add backward compatibility support for the legacy py path type."""2import shlex3import subprocess4from pathlib import Path5from typing import List6from typing import Optional7from typing import TYPE_CHECKING8from typing import Union9import attr10from iniconfig import SectionWrapper11from _pytest.cacheprovider import Cache12from _pytest.compat import final13from _pytest.compat import LEGACY_PATH14from _pytest.compat import legacy_path15from _pytest.config import Config16from _pytest.config import hookimpl17from _pytest.config import PytestPluginManager18from _pytest.deprecated import check_ispytest19from _pytest.fixtures import fixture20from _pytest.fixtures import FixtureRequest21from _pytest.main import Session22from _pytest.monkeypatch import MonkeyPatch23from _pytest.nodes import Collector24from _pytest.nodes import Item25from _pytest.nodes import Node26from _pytest.pytester import HookRecorder27from _pytest.pytester import Pytester28from _pytest.pytester import RunResult29from _pytest.terminal import TerminalReporter30from _pytest.tmpdir import TempPathFactory31if TYPE_CHECKING:32 from typing_extensions import Final33 import pexpect34@final35class Testdir:36 """37 Similar to :class:`Pytester`, but this class works with legacy legacy_path objects instead.38 All methods just forward to an internal :class:`Pytester` instance, converting results39 to `legacy_path` objects as necessary.40 """41 __test__ = False42 CLOSE_STDIN: "Final" = Pytester.CLOSE_STDIN43 TimeoutExpired: "Final" = Pytester.TimeoutExpired44 def __init__(self, pytester: Pytester, *, _ispytest: bool = False) -> None:45 check_ispytest(_ispytest)46 self._pytester = pytester47 @property48 def tmpdir(self) -> LEGACY_PATH:49 """Temporary directory where tests are executed."""50 return legacy_path(self._pytester.path)51 @property52 def test_tmproot(self) -> LEGACY_PATH:53 return legacy_path(self._pytester._test_tmproot)54 @property55 def request(self):56 return self._pytester._request57 @property58 def plugins(self):59 return self._pytester.plugins60 @plugins.setter61 def plugins(self, plugins):62 self._pytester.plugins = plugins63 @property64 def monkeypatch(self) -> MonkeyPatch:65 return self._pytester._monkeypatch66 def make_hook_recorder(self, pluginmanager) -> HookRecorder:67 """See :meth:`Pytester.make_hook_recorder`."""68 return self._pytester.make_hook_recorder(pluginmanager)69 def chdir(self) -> None:70 """See :meth:`Pytester.chdir`."""71 return self._pytester.chdir()72 def finalize(self) -> None:73 """See :meth:`Pytester._finalize`."""74 return self._pytester._finalize()75 def makefile(self, ext, *args, **kwargs) -> LEGACY_PATH:76 """See :meth:`Pytester.makefile`."""77 if ext and not ext.startswith("."):78 # pytester.makefile is going to throw a ValueError in a way that79 # testdir.makefile did not, because80 # pathlib.Path is stricter suffixes than py.path81 # This ext arguments is likely user error, but since testdir has82 # allowed this, we will prepend "." as a workaround to avoid breaking83 # testdir usage that worked before84 ext = "." + ext85 return legacy_path(self._pytester.makefile(ext, *args, **kwargs))86 def makeconftest(self, source) -> LEGACY_PATH:87 """See :meth:`Pytester.makeconftest`."""88 return legacy_path(self._pytester.makeconftest(source))89 def makeini(self, source) -> LEGACY_PATH:90 """See :meth:`Pytester.makeini`."""91 return legacy_path(self._pytester.makeini(source))92 def getinicfg(self, source: str) -> SectionWrapper:93 """See :meth:`Pytester.getinicfg`."""94 return self._pytester.getinicfg(source)95 def makepyprojecttoml(self, source) -> LEGACY_PATH:96 """See :meth:`Pytester.makepyprojecttoml`."""97 return legacy_path(self._pytester.makepyprojecttoml(source))98 def makepyfile(self, *args, **kwargs) -> LEGACY_PATH:99 """See :meth:`Pytester.makepyfile`."""100 return legacy_path(self._pytester.makepyfile(*args, **kwargs))101 def maketxtfile(self, *args, **kwargs) -> LEGACY_PATH:102 """See :meth:`Pytester.maketxtfile`."""103 return legacy_path(self._pytester.maketxtfile(*args, **kwargs))104 def syspathinsert(self, path=None) -> None:105 """See :meth:`Pytester.syspathinsert`."""106 return self._pytester.syspathinsert(path)107 def mkdir(self, name) -> LEGACY_PATH:108 """See :meth:`Pytester.mkdir`."""109 return legacy_path(self._pytester.mkdir(name))110 def mkpydir(self, name) -> LEGACY_PATH:111 """See :meth:`Pytester.mkpydir`."""112 return legacy_path(self._pytester.mkpydir(name))113 def copy_example(self, name=None) -> LEGACY_PATH:114 """See :meth:`Pytester.copy_example`."""115 return legacy_path(self._pytester.copy_example(name))116 def getnode(self, config: Config, arg) -> Optional[Union[Item, Collector]]:117 """See :meth:`Pytester.getnode`."""118 return self._pytester.getnode(config, arg)119 def getpathnode(self, path):120 """See :meth:`Pytester.getpathnode`."""121 return self._pytester.getpathnode(path)122 def genitems(self, colitems: List[Union[Item, Collector]]) -> List[Item]:123 """See :meth:`Pytester.genitems`."""124 return self._pytester.genitems(colitems)125 def runitem(self, source):126 """See :meth:`Pytester.runitem`."""127 return self._pytester.runitem(source)128 def inline_runsource(self, source, *cmdlineargs):129 """See :meth:`Pytester.inline_runsource`."""130 return self._pytester.inline_runsource(source, *cmdlineargs)131 def inline_genitems(self, *args):132 """See :meth:`Pytester.inline_genitems`."""133 return self._pytester.inline_genitems(*args)134 def inline_run(self, *args, plugins=(), no_reraise_ctrlc: bool = False):135 """See :meth:`Pytester.inline_run`."""136 return self._pytester.inline_run(137 *args, plugins=plugins, no_reraise_ctrlc=no_reraise_ctrlc138 )139 def runpytest_inprocess(self, *args, **kwargs) -> RunResult:140 """See :meth:`Pytester.runpytest_inprocess`."""141 return self._pytester.runpytest_inprocess(*args, **kwargs)142 def runpytest(self, *args, **kwargs) -> RunResult:143 """See :meth:`Pytester.runpytest`."""144 return self._pytester.runpytest(*args, **kwargs)145 def parseconfig(self, *args) -> Config:146 """See :meth:`Pytester.parseconfig`."""147 return self._pytester.parseconfig(*args)148 def parseconfigure(self, *args) -> Config:149 """See :meth:`Pytester.parseconfigure`."""150 return self._pytester.parseconfigure(*args)151 def getitem(self, source, funcname="test_func"):152 """See :meth:`Pytester.getitem`."""153 return self._pytester.getitem(source, funcname)154 def getitems(self, source):155 """See :meth:`Pytester.getitems`."""156 return self._pytester.getitems(source)157 def getmodulecol(self, source, configargs=(), withinit=False):158 """See :meth:`Pytester.getmodulecol`."""159 return self._pytester.getmodulecol(160 source, configargs=configargs, withinit=withinit161 )162 def collect_by_name(163 self, modcol: Collector, name: str164 ) -> Optional[Union[Item, Collector]]:165 """See :meth:`Pytester.collect_by_name`."""166 return self._pytester.collect_by_name(modcol, name)167 def popen(168 self,169 cmdargs,170 stdout=subprocess.PIPE,171 stderr=subprocess.PIPE,172 stdin=CLOSE_STDIN,173 **kw,174 ):175 """See :meth:`Pytester.popen`."""176 return self._pytester.popen(cmdargs, stdout, stderr, stdin, **kw)177 def run(self, *cmdargs, timeout=None, stdin=CLOSE_STDIN) -> RunResult:178 """See :meth:`Pytester.run`."""179 return self._pytester.run(*cmdargs, timeout=timeout, stdin=stdin)180 def runpython(self, script) -> RunResult:181 """See :meth:`Pytester.runpython`."""182 return self._pytester.runpython(script)183 def runpython_c(self, command):184 """See :meth:`Pytester.runpython_c`."""185 return self._pytester.runpython_c(command)186 def runpytest_subprocess(self, *args, timeout=None) -> RunResult:187 """See :meth:`Pytester.runpytest_subprocess`."""188 return self._pytester.runpytest_subprocess(*args, timeout=timeout)189 def spawn_pytest(190 self, string: str, expect_timeout: float = 10.0191 ) -> "pexpect.spawn":192 """See :meth:`Pytester.spawn_pytest`."""193 return self._pytester.spawn_pytest(string, expect_timeout=expect_timeout)194 def spawn(self, cmd: str, expect_timeout: float = 10.0) -> "pexpect.spawn":195 """See :meth:`Pytester.spawn`."""196 return self._pytester.spawn(cmd, expect_timeout=expect_timeout)197 def __repr__(self) -> str:198 return f"<Testdir {self.tmpdir!r}>"199 def __str__(self) -> str:200 return str(self.tmpdir)201class LegacyTestdirPlugin:202 @staticmethod203 @fixture204 def testdir(pytester: Pytester) -> Testdir:205 """206 Identical to :fixture:`pytester`, and provides an instance whose methods return207 legacy ``LEGACY_PATH`` objects instead when applicable.208 New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`.209 """210 return Testdir(pytester, _ispytest=True)211@final212@attr.s(init=False, auto_attribs=True)213class TempdirFactory:214 """Backward compatibility wrapper that implements :class:``_pytest.compat.LEGACY_PATH``215 for :class:``TempPathFactory``."""216 _tmppath_factory: TempPathFactory217 def __init__(218 self, tmppath_factory: TempPathFactory, *, _ispytest: bool = False219 ) -> None:220 check_ispytest(_ispytest)221 self._tmppath_factory = tmppath_factory222 def mktemp(self, basename: str, numbered: bool = True) -> LEGACY_PATH:223 """Same as :meth:`TempPathFactory.mktemp`, but returns a ``_pytest.compat.LEGACY_PATH`` object."""224 return legacy_path(self._tmppath_factory.mktemp(basename, numbered).resolve())225 def getbasetemp(self) -> LEGACY_PATH:226 """Backward compat wrapper for ``_tmppath_factory.getbasetemp``."""227 return legacy_path(self._tmppath_factory.getbasetemp().resolve())228class LegacyTmpdirPlugin:229 @staticmethod230 @fixture(scope="session")231 def tmpdir_factory(request: FixtureRequest) -> TempdirFactory:232 """Return a :class:`pytest.TempdirFactory` instance for the test session."""233 # Set dynamically by pytest_configure().234 return request.config._tmpdirhandler # type: ignore235 @staticmethod236 @fixture237 def tmpdir(tmp_path: Path) -> LEGACY_PATH:238 """Return a temporary directory path object which is unique to each test239 function invocation, created as a sub directory of the base temporary240 directory.241 By default, a new base temporary directory is created each test session,242 and old bases are removed after 3 sessions, to aid in debugging. If243 ``--basetemp`` is used then it is cleared each session. See :ref:`base244 temporary directory`.245 The returned object is a `legacy_path`_ object.246 .. _legacy_path: https://py.readthedocs.io/en/latest/path.html247 """248 return legacy_path(tmp_path)249def Cache_makedir(self: Cache, name: str) -> LEGACY_PATH:250 """Return a directory path object with the given name.251 Same as :func:`mkdir`, but returns a legacy py path instance.252 """253 return legacy_path(self.mkdir(name))254def FixtureRequest_fspath(self: FixtureRequest) -> LEGACY_PATH:255 """(deprecated) The file system path of the test module which collected this test."""256 return legacy_path(self.path)257def TerminalReporter_startdir(self: TerminalReporter) -> LEGACY_PATH:258 """The directory from which pytest was invoked.259 Prefer to use ``startpath`` which is a :class:`pathlib.Path`.260 :type: LEGACY_PATH261 """262 return legacy_path(self.startpath)263def Config_invocation_dir(self: Config) -> LEGACY_PATH:264 """The directory from which pytest was invoked.265 Prefer to use :attr:`invocation_params.dir <InvocationParams.dir>`,266 which is a :class:`pathlib.Path`.267 :type: LEGACY_PATH268 """269 return legacy_path(str(self.invocation_params.dir))270def Config_rootdir(self: Config) -> LEGACY_PATH:271 """The path to the :ref:`rootdir <rootdir>`.272 Prefer to use :attr:`rootpath`, which is a :class:`pathlib.Path`.273 :type: LEGACY_PATH274 """275 return legacy_path(str(self.rootpath))276def Config_inifile(self: Config) -> Optional[LEGACY_PATH]:277 """The path to the :ref:`configfile <configfiles>`.278 Prefer to use :attr:`inipath`, which is a :class:`pathlib.Path`.279 :type: Optional[LEGACY_PATH]280 """281 return legacy_path(str(self.inipath)) if self.inipath else None282def Session_stardir(self: Session) -> LEGACY_PATH:283 """The path from which pytest was invoked.284 Prefer to use ``startpath`` which is a :class:`pathlib.Path`.285 :type: LEGACY_PATH286 """287 return legacy_path(self.startpath)288def Config__getini_unknown_type(289 self, name: str, type: str, value: Union[str, List[str]]290):291 if type == "pathlist":292 # TODO: This assert is probably not valid in all cases.293 assert self.inipath is not None294 dp = self.inipath.parent295 input_values = shlex.split(value) if isinstance(value, str) else value296 return [legacy_path(str(dp / x)) for x in input_values]297 else:298 raise ValueError(f"unknown configuration type: {type}", value)299def Node_fspath(self: Node) -> LEGACY_PATH:300 """(deprecated) returns a legacy_path copy of self.path"""301 return legacy_path(self.path)302def Node_fspath_set(self: Node, value: LEGACY_PATH) -> None:303 self.path = Path(value)304@hookimpl(tryfirst=True)305def pytest_load_initial_conftests(early_config: Config) -> None:306 """Monkeypatch legacy path attributes in several classes, as early as possible."""307 mp = MonkeyPatch()308 early_config.add_cleanup(mp.undo)309 # Add Cache.makedir().310 mp.setattr(Cache, "makedir", Cache_makedir, raising=False)311 # Add FixtureRequest.fspath property.312 mp.setattr(FixtureRequest, "fspath", property(FixtureRequest_fspath), raising=False)313 # Add TerminalReporter.startdir property.314 mp.setattr(315 TerminalReporter, "startdir", property(TerminalReporter_startdir), raising=False316 )317 # Add Config.{invocation_dir,rootdir,inifile} properties.318 mp.setattr(Config, "invocation_dir", property(Config_invocation_dir), raising=False)319 mp.setattr(Config, "rootdir", property(Config_rootdir), raising=False)320 mp.setattr(Config, "inifile", property(Config_inifile), raising=False)321 # Add Session.startdir property.322 mp.setattr(Session, "startdir", property(Session_stardir), raising=False)323 # Add pathlist configuration type.324 mp.setattr(Config, "_getini_unknown_type", Config__getini_unknown_type)325 # Add Node.fspath property.326 mp.setattr(Node, "fspath", property(Node_fspath, Node_fspath_set), raising=False)327@hookimpl328def pytest_configure(config: Config) -> None:329 """Installs the LegacyTmpdirPlugin if the ``tmpdir`` plugin is also installed."""330 if config.pluginmanager.has_plugin("tmpdir"):331 mp = MonkeyPatch()332 config.add_cleanup(mp.undo)333 # Create TmpdirFactory and attach it to the config object.334 #335 # This is to comply with existing plugins which expect the handler to be336 # available at pytest_configure time, but ideally should be moved entirely337 # to the tmpdir_factory session fixture.338 try:339 tmp_path_factory = config._tmp_path_factory # type: ignore[attr-defined]340 except AttributeError:341 # tmpdir plugin is blocked.342 pass343 else:344 _tmpdirhandler = TempdirFactory(tmp_path_factory, _ispytest=True)345 mp.setattr(config, "_tmpdirhandler", _tmpdirhandler, raising=False)346 config.pluginmanager.register(LegacyTmpdirPlugin, "legacypath-tmpdir")347@hookimpl348def pytest_plugin_registered(plugin: object, manager: PytestPluginManager) -> None:349 # pytester is not loaded by default and is commonly loaded from a conftest,350 # so checking for it in `pytest_configure` is not enough.351 is_pytester = plugin is manager.get_plugin("pytester")352 if is_pytester and not manager.is_registered(LegacyTestdirPlugin):...
test_qpub.py
Source:test_qpub.py
1# ---2# jupyter:3# jupytext:4# formats: ipynb,py:percent5# text_representation:6# extension: .py7# format_name: percent8# format_version: '1.3'9# jupytext_version: 1.9.110# kernelspec:11# display_name: Python 312# language: python13# name: python314# ---15# %% [markdown]16# # `qpub` tests17#18# %% [markdown]19# one way to use qpub is it with the `doit` line magic; load the `qpub` ipython extension with20# %%21import pathlib, pytest, os, sys22def build(pytester, object, where=None):23 for key, value in object.items():24 if isinstance(value, str):25 file = (where or pathlib.Path()) / key26 if where:27 where.mkdir(exist_ok=True, parents=True)28 if file.suffix == ".ipynb":29 import nbformat30 value = nbformat.v4.writes(nbformat.v4.new_notebook(cells=[31 nbformat.v4.new_code_cell(contents)]))32 pytester.makefile(file.suffix, **{33 str(file.with_suffix("")): value34 })35 elif isinstance(value, dict):36 build(pytester, value, where=(where or pathlib.Path())/key)37# %% [markdown]38# for this test document we'll consider a simple project with the contents below. in the `contents`, we need to explicitly provide a docstring and version to cooperate with `flit`s model.39# %%40meta = """'''my projects docstring'''41__version__ = "0.0.1"42"""43contents = """44import pandas45"""46# %% [markdown]47# it allows different layouts, like `python_layouts` to be used as test input.48# %%49flit_layouts = [{50 "my_idea.py": meta+contents51}, dict(52 my_idea={53 "__init__.py": meta+contents54 }55), dict(56 src=dict(57 my_idea={58 "__init__.py": meta+contents59 }60 )61), {62 "my_idea.ipynb": meta+contents63}]64# %%65setuptools_layouts = [{66 "1969-12-9-my-idea.ipynb": meta+contents67}, {68 "test_my_idea.ipynb": meta+contents69}, {"my_idea.py": contents}]70# %%71def run(pytester, cmd):72 result = pytester.run(*cmd.split())73 assert not result.ret, "\n".join((result.outlines+result.errlines))74 return result75# %%76def verify_pyproject():77 """verify metadata for pyproject"""78 import qpub79 data = qpub.PYPROJECT_TOML.load()80 # qpub can infer configurations for different tools.81# assert data["tool"]["poetry"]82 assert data["tool"]["flit"]83 assert data["tool"]["pytest"]84 assert (85 data["tool"]["flit"]["metadata"]["module"]86# == data["tool"]["poetry"]["name"] 87 == "my_idea")88# assert data["tool"]["poetry"]["version"] == "0.0.1"89# assert data["tool"]["poetry"]["description"]90 assert "pandas" in data["tool"]["flit"]["metadata"]["requires"]91 assert "pytest" in data["tool"]["flit"]["metadata"]["requires-extra"]["test"]92# assert "pandas" in data["tool"]["poetry"]["dependencies"]93# assert "pytest" in data["tool"]["poetry"]["dev-dependencies"]94# %%95def verify_setuptools():96 """verify metadata for pyproject"""97 import qpub 98 data = qpub.SETUP_CFG.load()99 print(11, data._sections)100 assert data["metadata"]["name"] == "my_idea"101# %%102@pytest.mark.parametrize("layout", setuptools_layouts)103def test_non_flit_projects(pytester, layout):104 import qpub105 build(pytester, layout)106 print(qpub.get_name())107 assert qpub.get_name()=="my_idea"108 # at this point we just have content and no configuration109 assert not (pytester.path / qpub.PYPROJECT_TOML).exists()110 # infer the flit configuration by default if the module complies with the doc version conventions.111 run(pytester, "qpub pyproject.toml")112 # no a pyproject configuration exists that contains flit metadata113 assert (pytester.path / qpub.PYPROJECT_TOML).exists()114 115 # forget the task explicitly, can't forget the file, to update with poetry116 # generally we wouldn't have to forget tasks, but we do for testing117 run(pytester, "qpub forget pyproject requirements_txt")118 # update the poetry metadata119 # mock the dependency resolution to speed up the tests alot!120# run(pytester, "qpub pyproject -b poetry")121 verify_pyproject()122 assert not (pytester.path / qpub.SETUP_CFG).exists()123 # configure the setuptools configuration.124 run(pytester, "qpub forget pyproject")125 run(pytester, "qpub pyproject -b setuptools")126 assert (pytester.path / qpub.SETUP_CFG).exists()127 verify_setuptools()128 # need to test overriding build backends129 # configure documentation files130 run(pytester, "qpub toc config mkdocs_yml")131 assert (pytester.path / qpub.TOC).exists()132 assert (pytester.path / qpub.CONFIG).exists()133 # configure linter files134 run(pytester, "qpub precommit")135# %%136@pytest.mark.parametrize("layout", flit_layouts)137def test_flit_projects(pytester, layout):138 import qpub139 build(pytester, layout)140 print(qpub.get_name())141 assert qpub.get_name()=="my_idea"142 # at this point we just have content and no configuration143 assert not (pytester.path / qpub.PYPROJECT_TOML).exists()144 # infer the flit configuration by default if the module complies with the doc version conventions.145 run(pytester, "qpub pyproject.toml")146 # no a pyproject configuration exists that contains flit metadata147 assert (pytester.path / qpub.PYPROJECT_TOML).exists()148 assert qpub.is_flit()149 150 # forget the task explicitly, can't forget the file, to update with poetry151 # generally we wouldn't have to forget tasks, but we do for testing152 run(pytester, "qpub forget pyproject requirements_txt")153 # update the poetry metadata154 # mock the dependency resolution to speed up the tests alot!155# run(pytester, "qpub pyproject -b poetry")156 verify_pyproject()157 assert not (pytester.path / qpub.SETUP_CFG).exists()158 # configure the setuptools configuration.159 run(pytester, "qpub forget pyproject")160 run(pytester, "qpub pyproject -b setuptools")161 assert (pytester.path / qpub.SETUP_CFG).exists()162 verify_setuptools()163 # need to test overriding build backends164 # configure documentation files165 run(pytester, "qpub toc config mkdocs_yml")166 assert (pytester.path / qpub.TOC).exists()167 assert (pytester.path / qpub.CONFIG).exists()168 # configure linter files...
Looking for an in-depth tutorial around pytest? LambdaTest covers the detailed pytest tutorial that has everything related to the pytest, from setting up the pytest framework to automation testing. Delve deeper into pytest testing by exploring advanced use cases like parallel testing, pytest fixtures, parameterization, executing multiple test cases from a single file, and more.
Skim our below pytest tutorial playlist to get started with automation testing using the pytest framework.
https://www.youtube.com/playlist?list=PLZMWkkQEwOPlcGgDmHl8KkXKeLF83XlrP
Get 100 minutes of automation test minutes FREE!!