1Metadata-Version: 2.1 2Name: pytest-xdist 3Version: 1.32.0 4Summary: pytest xdist plugin for distributed testing and loop-on-failing modes 5Home-page: https://github.com/pytest-dev/pytest-xdist 6Author: holger krekel and contributors 7Author-email: pytest-dev@python.org,holger@merlinux.eu 8License: MIT 9Description: 10 11 .. image:: http://img.shields.io/pypi/v/pytest-xdist.svg 12 :alt: PyPI version 13 :target: https://pypi.python.org/pypi/pytest-xdist 14 15 .. image:: https://img.shields.io/conda/vn/conda-forge/pytest-xdist.svg 16 :target: https://anaconda.org/conda-forge/pytest-xdist 17 18 .. image:: https://img.shields.io/pypi/pyversions/pytest-xdist.svg 19 :alt: Python versions 20 :target: https://pypi.python.org/pypi/pytest-xdist 21 22 .. image:: https://travis-ci.org/pytest-dev/pytest-xdist.svg?branch=master 23 :alt: Travis CI build status 24 :target: https://travis-ci.org/pytest-dev/pytest-xdist 25 26 .. image:: https://ci.appveyor.com/api/projects/status/56eq1a1avd4sdd7e/branch/master?svg=true 27 :alt: AppVeyor build status 28 :target: https://ci.appveyor.com/project/pytestbot/pytest-xdist 29 30 .. image:: https://img.shields.io/badge/code%20style-black-000000.svg 31 :target: https://github.com/ambv/black 32 33 xdist: pytest distributed testing plugin 34 ======================================== 35 36 The `pytest-xdist`_ plugin extends pytest with some unique 37 test execution modes: 38 39 * test run parallelization_: if you have multiple CPUs or hosts you can use 40 those for a combined test run. This allows to speed up 41 development or to use special resources of `remote machines`_. 42 43 44 * ``--looponfail``: run your tests repeatedly in a subprocess. After each run 45 pytest waits until a file in your project changes and then re-runs 46 the previously failing tests. This is repeated until all tests pass 47 after which again a full run is performed. 48 49 * `Multi-Platform`_ coverage: you can specify different Python interpreters 50 or different platforms and run tests in parallel on all of them. 51 52 Before running tests remotely, ``pytest`` efficiently "rsyncs" your 53 program source code to the remote place. All test results 54 are reported back and displayed to your local terminal. 55 You may specify different Python versions and interpreters. 56 57 If you would like to know how pytest-xdist works under the covers, checkout 58 `OVERVIEW <https://github.com/pytest-dev/pytest-xdist/blob/master/OVERVIEW.md>`_. 59 60 61 Installation 62 ------------ 63 64 Install the plugin with:: 65 66 pip install pytest-xdist 67 68 or use the package in develop/in-place mode with 69 a checkout of the `pytest-xdist repository`_ :: 70 71 pip install --editable . 72 73 .. _parallelization: 74 75 Speed up test runs by sending tests to multiple CPUs 76 ---------------------------------------------------- 77 78 To send tests to multiple CPUs, type:: 79 80 pytest -n NUM 81 82 Especially for longer running tests or tests requiring 83 a lot of I/O this can lead to considerable speed ups. This option can 84 also be set to ``auto`` for automatic detection of the number of CPUs. 85 86 If a test crashes the interpreter, pytest-xdist will automatically restart 87 that worker and report the failure as usual. You can use the 88 ``--max-worker-restart`` option to limit the number of workers that can 89 be restarted, or disable restarting altogether using ``--max-worker-restart=0``. 90 91 By default, the ``-n`` option will send pending tests to any worker that is available, without 92 any guaranteed order, but you can control this with these options: 93 94 * ``--dist=loadscope``: tests will be grouped by **module** for *test functions* and 95 by **class** for *test methods*, then each group will be sent to an available worker, 96 guaranteeing that all tests in a group run in the same process. This can be useful if you have 97 expensive module-level or class-level fixtures. Currently the groupings can't be customized, 98 with grouping by class takes priority over grouping by module. 99 This feature was added in version ``1.19``. 100 101 * ``--dist=loadfile``: tests will be grouped by file name, and then will be sent to an available 102 worker, guaranteeing that all tests in a group run in the same worker. This feature was added 103 in version ``1.21``. 104 105 106 Making session-scoped fixtures execute only once 107 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 108 109 ``pytest-xdist`` is designed so that each worker process will perform its own collection and execute 110 a subset of all tests. This means that tests in different processes requesting a high-level 111 scoped fixture (for example ``session``) will execute the fixture code more than once, which 112 breaks expectations and might be undesired in certain situations. 113 114 While ``pytest-xdist`` does not have a builtin support for ensuring a session-scoped fixture is 115 executed exactly once, this can be achieved by using a lock file for inter-process communication. 116 117 The example below needs to execute the fixture ``session_data`` only once (because it is 118 resource intensive, or needs to execute only once to define configuration options, etc), so it makes 119 use of a `FileLock <https://pypi.org/project/filelock/>`_ to produce the fixture data only once 120 when the first process requests the fixture, while the other processes will then read 121 the data from a file. 122 123 Here is the code: 124 125 .. code-block:: python 126 127 import json 128 129 import pytest 130 from filelock import FileLock 131 132 133 @pytest.fixture(scope="session") 134 def session_data(tmp_path_factory, worker_id): 135 if not worker_id: 136 # not executing in with multiple workers, just produce the data and let 137 # pytest's fixture caching do its job 138 return produce_expensive_data() 139 140 # get the temp directory shared by all workers 141 root_tmp_dir = tmp_path_factory.getbasetemp().parent 142 143 fn = root_tmp_dir / "data.json" 144 with FileLock(str(fn) + ".lock"): 145 if fn.is_file(): 146 data = json.loads(fn.read_text()) 147 else: 148 data = produce_expensive_data() 149 fn.write_text(json.dumps(data)) 150 return data 151 152 153 The example above can also be use in cases a fixture needs to execute exactly once per test session, like 154 initializing a database service and populating initial tables. 155 156 This technique might not work for every case, but should be a starting point for many situations 157 where executing a high-scope fixture exactly once is important. 158 159 Running tests in a Python subprocess 160 ------------------------------------ 161 162 To instantiate a python3.5 subprocess and send tests to it, you may type:: 163 164 pytest -d --tx popen//python=python3.5 165 166 This will start a subprocess which is run with the ``python3.5`` 167 Python interpreter, found in your system binary lookup path. 168 169 If you prefix the --tx option value like this:: 170 171 --tx 3*popen//python=python3.5 172 173 then three subprocesses would be created and tests 174 will be load-balanced across these three processes. 175 176 .. _boxed: 177 178 Running tests in a boxed subprocess 179 ----------------------------------- 180 181 This functionality has been moved to the 182 `pytest-forked <https://github.com/pytest-dev/pytest-forked>`_ plugin, but the ``--boxed`` option 183 is still kept for backward compatibility. 184 185 .. _`remote machines`: 186 187 Sending tests to remote SSH accounts 188 ------------------------------------ 189 190 Suppose you have a package ``mypkg`` which contains some 191 tests that you can successfully run locally. And you 192 have a ssh-reachable machine ``myhost``. Then 193 you can ad-hoc distribute your tests by typing:: 194 195 pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg 196 197 This will synchronize your :code:`mypkg` package directory 198 to a remote ssh account and then locally collect tests 199 and send them to remote places for execution. 200 201 You can specify multiple :code:`--rsyncdir` directories 202 to be sent to the remote side. 203 204 .. note:: 205 206 For pytest to collect and send tests correctly 207 you not only need to make sure all code and tests 208 directories are rsynced, but that any test (sub) directory 209 also has an :code:`__init__.py` file because internally 210 pytest references tests as a fully qualified python 211 module path. **You will otherwise get strange errors** 212 during setup of the remote side. 213 214 215 You can specify multiple :code:`--rsyncignore` glob patterns 216 to be ignored when file are sent to the remote side. 217 There are also internal ignores: :code:`.*, *.pyc, *.pyo, *~` 218 Those you cannot override using rsyncignore command-line or 219 ini-file option(s). 220 221 222 Sending tests to remote Socket Servers 223 -------------------------------------- 224 225 Download the single-module `socketserver.py`_ Python program 226 and run it like this:: 227 228 python socketserver.py 229 230 It will tell you that it starts listening on the default 231 port. You can now on your home machine specify this 232 new socket host with something like this:: 233 234 pytest -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg 235 236 237 .. _`atonce`: 238 .. _`Multi-Platform`: 239 240 241 Running tests on many platforms at once 242 --------------------------------------- 243 244 The basic command to run tests on multiple platforms is:: 245 246 pytest --dist=each --tx=spec1 --tx=spec2 247 248 If you specify a windows host, an OSX host and a Linux 249 environment this command will send each tests to all 250 platforms - and report back failures from all platforms 251 at once. The specifications strings use the `xspec syntax`_. 252 253 .. _`xspec syntax`: http://codespeak.net/execnet/basics.html#xspec 254 255 .. _`socketserver.py`: http://bitbucket.org/hpk42/execnet/raw/2af991418160/execnet/script/socketserver.py 256 257 .. _`execnet`: http://codespeak.net/execnet 258 259 Identifying the worker process during a test 260 -------------------------------------------- 261 262 *New in version 1.15.* 263 264 If you need to determine the identity of a worker process in 265 a test or fixture, you may use the ``worker_id`` fixture to do so: 266 267 .. code-block:: python 268 269 @pytest.fixture() 270 def user_account(worker_id): 271 """ use a different account in each xdist worker """ 272 return "account_%s" % worker_id 273 274 When ``xdist`` is disabled (running with ``-n0`` for example), then 275 ``worker_id`` will return ``"master"``. 276 277 Additionally, worker processes have the following environment variables 278 defined: 279 280 * ``PYTEST_XDIST_WORKER``: the name of the worker, e.g., ``"gw2"``. 281 * ``PYTEST_XDIST_WORKER_COUNT``: the total number of workers in this session, 282 e.g., ``"4"`` when ``-n 4`` is given in the command-line. 283 284 The information about the worker_id in a test is stored in the ``TestReport`` as 285 well, under the ``worker_id`` attribute. 286 287 288 Uniquely identifying the current test run 289 ----------------------------------------- 290 291 *New in version 1.32.* 292 293 If you need to globally distinguish one test run from others in your 294 workers, you can use the ``testrun_uid`` fixture. For instance, let's say you 295 wanted to create a separate database for each test run: 296 297 .. code-block:: python 298 299 import pytest 300 from posix_ipc import Semaphore, O_CREAT 301 302 @pytest.fixture(scope="session", autouse=True) 303 def create_unique_database(testrun_uid): 304 """ create a unique database for this particular test run """ 305 database_url = f"psql://myapp-{testrun_uid}" 306 307 with Semaphore(f"/{testrun_uid}-lock", flags=O_CREAT, initial_value=1): 308 if not database_exists(database_url): 309 create_database(database_url) 310 311 @pytest.fixture() 312 def db(testrun_uid): 313 """ retrieve unique database """ 314 database_url = f"psql://myapp-{testrun_uid}" 315 return database_get_instance(database_url) 316 317 318 Additionally, during a test run, the following environment variable is defined: 319 320 * ``PYTEST_XDIST_TESTRUNUID``: the unique id of the test run. 321 322 Accessing ``sys.argv`` from the master node in workers 323 ------------------------------------------------------ 324 325 To access the ``sys.argv`` passed to the command-line of the master node, use 326 ``request.config.workerinput["mainargv"]``. 327 328 329 Specifying test exec environments in an ini file 330 ------------------------------------------------ 331 332 You can use pytest's ini file configuration to avoid typing common options. 333 You can for example make running with three subprocesses your default like this: 334 335 .. code-block:: ini 336 337 [pytest] 338 addopts = -n3 339 340 You can also add default environments like this: 341 342 .. code-block:: ini 343 344 [pytest] 345 addopts = --tx ssh=myhost//python=python3.5 --tx ssh=myhost//python=python3.6 346 347 and then just type:: 348 349 pytest --dist=each 350 351 to run tests in each of the environments. 352 353 354 Specifying "rsync" dirs in an ini-file 355 -------------------------------------- 356 357 In a ``tox.ini`` or ``setup.cfg`` file in your root project directory 358 you may specify directories to include or to exclude in synchronisation: 359 360 .. code-block:: ini 361 362 [pytest] 363 rsyncdirs = . mypkg helperpkg 364 rsyncignore = .hg 365 366 These directory specifications are relative to the directory 367 where the configuration file was found. 368 369 .. _`pytest-xdist`: http://pypi.python.org/pypi/pytest-xdist 370 .. _`pytest-xdist repository`: https://github.com/pytest-dev/pytest-xdist 371 .. _`pytest`: http://pytest.org 372 373Platform: linux 374Platform: osx 375Platform: win32 376Classifier: Development Status :: 5 - Production/Stable 377Classifier: Framework :: Pytest 378Classifier: Intended Audience :: Developers 379Classifier: License :: OSI Approved :: MIT License 380Classifier: Operating System :: POSIX 381Classifier: Operating System :: Microsoft :: Windows 382Classifier: Operating System :: MacOS :: MacOS X 383Classifier: Topic :: Software Development :: Testing 384Classifier: Topic :: Software Development :: Quality Assurance 385Classifier: Topic :: Utilities 386Classifier: Programming Language :: Python 387Classifier: Programming Language :: Python :: 2 388Classifier: Programming Language :: Python :: 2.7 389Classifier: Programming Language :: Python :: 3 390Classifier: Programming Language :: Python :: 3.5 391Classifier: Programming Language :: Python :: 3.6 392Classifier: Programming Language :: Python :: 3.7 393Classifier: Programming Language :: Python :: 3.8 394Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* 395Provides-Extra: testing 396