├── requirements.txt ├── tests ├── conftest.py └── test_lazyfixture.py ├── setup.cfg ├── MANIFEST.in ├── .travis.yml ├── appveyor.yml ├── LICENSE ├── .gitignore ├── setup.py ├── tox.ini ├── README.rst └── pytest_lazyfixture.py /requirements.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | tox 3 | flake8 4 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | pytest_plugins = 'pytester' 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = .git,.tox,build,dist,__pycache__,.pytest_cache,.cache 3 | max-line-length = 120 4 | ignore = F821 W503 W504 5 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.md 3 | recursive-include tests *.py 4 | recursive-exclude * __pycache__ 5 | recursive-exclude * *.py[co] 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Config file for automatic testing at travis-ci.org 2 | 3 | sudo: false 4 | language: python 5 | python: 6 | - "2.7" 7 | - "3.4" 8 | - "3.5" 9 | - "3.6" 10 | - "3.7" 11 | - "pypy" 12 | 13 | install: 14 | - pip install tox 15 | - "TOX_ENV=${TRAVIS_PYTHON_VERSION/[0-9].[0-9]/py${TRAVIS_PYTHON_VERSION/.}}" 16 | script: tox -e $TOX_ENV 17 | 18 | before_cache: 19 | - rm -rf $HOME/.cache/pip/log 20 | cache: 21 | directories: 22 | - $HOME/.cache/pip 23 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # What Python version is installed where: 2 | # http://www.appveyor.com/docs/installed-software#python 3 | 4 | environment: 5 | matrix: 6 | - PYTHON: "C:\\Python27" 7 | TOX_ENV: "py27" 8 | 9 | - PYTHON: "C:\\Python34" 10 | TOX_ENV: "py34" 11 | 12 | - PYTHON: "C:\\Python35" 13 | TOX_ENV: "py35" 14 | 15 | - PYTHON: "C:\\Python36" 16 | TOX_ENV: "py36" 17 | 18 | - PYTHON: "C:\\Python37" 19 | TOX_ENV: "py37" 20 | 21 | init: 22 | - "%PYTHON%/python -V" 23 | - "%PYTHON%/python -c \"import struct;print( 8 * struct.calcsize(\'P\'))\"" 24 | 25 | install: 26 | - "%PYTHON%/Scripts/easy_install -U pip" 27 | - "%PYTHON%/Scripts/pip install tox" 28 | - "%PYTHON%/Scripts/pip install wheel" 29 | 30 | build: false # Not a C# project, build stuff at the test step instead. 31 | 32 | test_script: 33 | - "%PYTHON%/Scripts/tox -e %TOX_ENV%" 34 | 35 | after_test: 36 | - "%PYTHON%/python setup.py bdist_wheel" 37 | - ps: "ls dist" 38 | 39 | artifacts: 40 | - path: dist\* 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 Marsel Zaripov 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask instance folder 57 | instance/ 58 | 59 | # Sphinx documentation 60 | docs/_build/ 61 | 62 | # PyBuilder 63 | target/ 64 | 65 | # IPython Notebook 66 | .ipynb_checkpoints 67 | 68 | # pyenv 69 | .python-version 70 | 71 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import codecs 6 | from setuptools import setup 7 | 8 | 9 | def read(fname): 10 | file_path = os.path.join(os.path.dirname(__file__), fname) 11 | return codecs.open(file_path, encoding='utf-8').read() 12 | 13 | 14 | setup( 15 | name='pytest-lazy-fixture', 16 | version='0.6.3', 17 | author='Marsel Zaripov', 18 | author_email='marszaripov@gmail.com', 19 | maintainer='Marsel Zaripov', 20 | maintainer_email='marszaripov@gmail.com', 21 | license='MIT', 22 | url='https://github.com/tvorog/pytest-lazy-fixture', 23 | description='It helps to use fixtures in pytest.mark.parametrize', 24 | long_description=read('README.rst'), 25 | py_modules=['pytest_lazyfixture'], 26 | install_requires=['pytest>=3.2.5'], 27 | classifiers=[ 28 | 'Development Status :: 4 - Beta', 29 | 'Framework :: Pytest', 30 | 'Intended Audience :: Developers', 31 | 'Topic :: Software Development :: Testing', 32 | 'Programming Language :: Python', 33 | 'Programming Language :: Python :: 2', 34 | 'Programming Language :: Python :: 2.7', 35 | 'Programming Language :: Python :: 3', 36 | 'Programming Language :: Python :: 3.4', 37 | 'Programming Language :: Python :: 3.5', 38 | 'Programming Language :: Python :: 3.6', 39 | 'Programming Language :: Python :: 3.7', 40 | 'Programming Language :: Python :: Implementation :: CPython', 41 | 'Programming Language :: Python :: Implementation :: PyPy', 42 | 'Operating System :: OS Independent', 43 | 'License :: OSI Approved :: MIT License', 44 | ], 45 | entry_points={ 46 | 'pytest11': [ 47 | 'lazy-fixture = pytest_lazyfixture', 48 | ], 49 | }, 50 | ) 51 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # For more information about tox, see https://tox.readthedocs.io/en/latest/ 2 | [tox] 3 | envlist = 4 | {py27,py34}-pytest_{3_2,3_3,3_4,3_5,3_6,3_7,3_8,3_9,3_10,4_0,4_1,4_2,4_3,4_4,4_5,4_6} 5 | {py36,py37,py38,py39,pypy}-pytest_{3_2,3_3,3_4,3_5,3_6,3_7,3_8,3_9,3_10,4_0,4_1,4_2,4_3,4_4,4_5,4_6,5_0,5_1,5_2,5_3,5_4,6_0,6_1,6_2} 6 | flake8 7 | skip_missing_interpreters=True 8 | 9 | [testenv] 10 | commands = py.test {posargs:tests} 11 | deps = 12 | pytest_3_2: pytest<3.3.0 13 | 14 | pytest_3_3: pytest<3.4.0 15 | pytest_3_3: attrs==19.1.0 16 | 17 | pytest_3_4: pytest<3.5.0 18 | pytest_3_4: attrs==19.1.0 19 | 20 | pytest_3_5: pytest<3.6.0 21 | pytest_3_6: pytest<3.7.0 22 | pytest_3_7: pytest<3.8.0 23 | pytest_3_8: pytest<3.9.0 24 | pytest_3_9: pytest<3.10.0 25 | pytest_3_10: pytest<4.0.0 26 | 27 | pytest_4_0: pytest<4.1.0 28 | pytest_4_0: attrs==19.1.0 29 | 30 | pytest_4_1: pytest<4.2.0 31 | pytest_4_1: attrs==19.1.0 32 | 33 | pytest_4_2: pytest<4.3.0 34 | pytest_4_2: attrs==19.1.0 35 | 36 | pytest_4_3: pytest<4.4.0 37 | pytest_4_3: attrs==19.1.0 38 | 39 | pytest_4_4: pytest<4.5.0 40 | pytest_4_4: attrs==19.1.0 41 | 42 | pytest_4_5: pytest<4.6.0 43 | pytest_4_5: attrs==19.1.0 44 | 45 | pytest_4_6: pytest<5.0.0 46 | pytest_4_6: attrs==19.1.0 47 | 48 | pytest_5_0: pytest<5.1.0 49 | pytest_5_0: attrs==19.1.0 50 | 51 | pytest_5_1: pytest<5.2.0 52 | pytest_5_1: attrs==19.1.0 53 | 54 | pytest_5_2: pytest<5.3.0 55 | pytest_5_2: attrs==19.1.0 56 | 57 | pytest_5_3: pytest<5.4.0 58 | pytest_5_3: attrs==19.1.0 59 | 60 | pytest_5_4: pytest<5.5.0 61 | pytest_5_4: attrs==19.1.0 62 | 63 | pytest_6_0: pytest<6.1.0 64 | pytest_6_0: attrs==19.1.0 65 | 66 | pytest_6_1: pytest<6.2.0 67 | pytest_6_1: attrs==19.1.0 68 | 69 | pytest_6_2: pytest<6.3.0 70 | pytest_6_2: attrs==19.1.0 71 | 72 | numpy==1.16.5 73 | 74 | [testenv:flake8] 75 | skip_install = true 76 | deps = flake8 77 | commands = flake8 pytest_lazyfixture.py setup.py tests 78 | 79 | [testenv:pytest] 80 | deps = -egit+https://github.com/pytest-dev/pytest.git#egg=pytest 81 | tox 82 | hypothesis>=3.5.2 83 | nose 84 | mock 85 | requests 86 | xmlschema 87 | changedir = {envdir}/src/pytest 88 | commands = pytest --lsof -rfsxX 89 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | pytest-lazy-fixture |travis-ci| |appveyor| |pypi| 2 | ================================================= 3 | 4 | Use your fixtures in ``@pytest.mark.parametrize``. 5 | 6 | Installation 7 | ------------ 8 | 9 | .. code-block:: shell 10 | 11 | pip install pytest-lazy-fixture 12 | 13 | Usage 14 | ----- 15 | 16 | pytest-lazy-fixture lets you use a fixture as one of the values passed 17 | in ``@pytest.mark.parametrize``: 18 | 19 | .. code-block:: python 20 | 21 | import pytest 22 | from pytest_lazyfixture import lazy_fixture 23 | 24 | @pytest.fixture 25 | def one(): 26 | return 1 27 | 28 | @pytest.mark.parametrize('arg1,arg2', [ 29 | ('val1', lazy_fixture('one')), 30 | ]) 31 | def test_func(arg1, arg2): 32 | assert arg2 == 1 33 | 34 | This can be even more useful when the fixture is itself parametrized: 35 | 36 | .. code-block:: python 37 | 38 | import pytest 39 | from pytest_lazyfixture import lazy_fixture 40 | 41 | @pytest.fixture(params=[1, 2]) 42 | def one(request): 43 | return request.param 44 | 45 | @pytest.mark.parametrize('arg1,arg2', [ 46 | ('val1', lazy_fixture('one')), 47 | ]) 48 | def test_func(arg1, arg2): 49 | assert arg2 in [1, 2] 50 | 51 | 52 | Also you can use it as a parameter in ``@pytest.fixture``: 53 | 54 | .. code-block:: python 55 | 56 | import pytest 57 | from pytest_lazyfixture import lazy_fixture 58 | 59 | @pytest.fixture(params=[ 60 | lazy_fixture('one'), 61 | lazy_fixture('two') 62 | ]) 63 | def some(request): 64 | return request.param 65 | 66 | @pytest.fixture 67 | def one(): 68 | return 1 69 | 70 | @pytest.fixture 71 | def two(): 72 | return 2 73 | 74 | def test_func(some): 75 | assert some in [1, 2] 76 | 77 | Please see `tests `_ for more examples. 78 | 79 | Contributing 80 | ------------ 81 | 82 | Contributions are very welcome. Tests can be run with ``tox``. 83 | 84 | License 85 | ------- 86 | 87 | Distributed under the terms of the ``MIT`` license, 88 | ``pytest-lazy-fixture`` is free and open source software 89 | 90 | Issues 91 | ------ 92 | 93 | If you encounter any problems, please ``file an issue`` along with a 94 | detailed description. 95 | 96 | .. |travis-ci| image:: https://travis-ci.org/TvoroG/pytest-lazy-fixture.svg?branch=master 97 | :target: https://travis-ci.org/TvoroG/pytest-lazy-fixture 98 | .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/TvoroG/pytest-fixture-mark?branch=master&svg=true 99 | :target: https://ci.appveyor.com/project/TvoroG/pytest-fixture-mark 100 | .. |pypi| image:: https://badge.fury.io/py/pytest-lazy-fixture.svg 101 | :target: https://pypi.python.org/pypi/pytest-lazy-fixture/ 102 | -------------------------------------------------------------------------------- /pytest_lazyfixture.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import copy 3 | import sys 4 | import types 5 | from collections import defaultdict 6 | import pytest 7 | 8 | 9 | PY3 = sys.version_info[0] == 3 10 | string_type = str if PY3 else basestring 11 | 12 | 13 | def pytest_configure(): 14 | pytest.lazy_fixture = lazy_fixture 15 | 16 | 17 | @pytest.hookimpl(tryfirst=True) 18 | def pytest_runtest_setup(item): 19 | if hasattr(item, '_request'): 20 | item._request._fillfixtures = types.MethodType( 21 | fillfixtures(item._request._fillfixtures), item._request 22 | ) 23 | 24 | 25 | def fillfixtures(_fillfixtures): 26 | def fill(request): 27 | item = request._pyfuncitem 28 | fixturenames = getattr(item, "fixturenames", None) 29 | if fixturenames is None: 30 | fixturenames = request.fixturenames 31 | 32 | if hasattr(item, 'callspec'): 33 | for param, val in sorted_by_dependency(item.callspec.params, fixturenames): 34 | if val is not None and is_lazy_fixture(val): 35 | item.callspec.params[param] = request.getfixturevalue(val.name) 36 | elif param not in item.funcargs: 37 | item.funcargs[param] = request.getfixturevalue(param) 38 | 39 | _fillfixtures() 40 | return fill 41 | 42 | 43 | @pytest.hookimpl(tryfirst=True) 44 | def pytest_fixture_setup(fixturedef, request): 45 | val = getattr(request, 'param', None) 46 | if is_lazy_fixture(val): 47 | request.param = request.getfixturevalue(val.name) 48 | 49 | 50 | def pytest_runtest_call(item): 51 | if hasattr(item, 'funcargs'): 52 | for arg, val in item.funcargs.items(): 53 | if is_lazy_fixture(val): 54 | item.funcargs[arg] = item._request.getfixturevalue(val.name) 55 | 56 | 57 | @pytest.hookimpl(hookwrapper=True) 58 | def pytest_pycollect_makeitem(collector, name, obj): 59 | global current_node 60 | current_node = collector 61 | yield 62 | current_node = None 63 | 64 | 65 | def pytest_make_parametrize_id(config, val, argname): 66 | if is_lazy_fixture(val): 67 | return val.name 68 | 69 | 70 | @pytest.hookimpl(hookwrapper=True) 71 | def pytest_generate_tests(metafunc): 72 | yield 73 | 74 | normalize_metafunc_calls(metafunc, 'funcargs') 75 | normalize_metafunc_calls(metafunc, 'params') 76 | 77 | 78 | def normalize_metafunc_calls(metafunc, valtype, used_keys=None): 79 | newcalls = [] 80 | for callspec in metafunc._calls: 81 | calls = normalize_call(callspec, metafunc, valtype, used_keys) 82 | newcalls.extend(calls) 83 | metafunc._calls = newcalls 84 | 85 | 86 | def copy_metafunc(metafunc): 87 | copied = copy.copy(metafunc) 88 | copied.fixturenames = copy.copy(metafunc.fixturenames) 89 | copied._calls = [] 90 | 91 | try: 92 | copied._ids = copy.copy(metafunc._ids) 93 | except AttributeError: 94 | # pytest>=5.3.0 95 | pass 96 | 97 | copied._arg2fixturedefs = copy.copy(metafunc._arg2fixturedefs) 98 | return copied 99 | 100 | 101 | def normalize_call(callspec, metafunc, valtype, used_keys): 102 | fm = metafunc.config.pluginmanager.get_plugin('funcmanage') 103 | 104 | used_keys = used_keys or set() 105 | valtype_keys = set(getattr(callspec, valtype).keys()) - used_keys 106 | 107 | for arg in valtype_keys: 108 | val = getattr(callspec, valtype)[arg] 109 | if is_lazy_fixture(val): 110 | try: 111 | _, fixturenames_closure, arg2fixturedefs = fm.getfixtureclosure([val.name], metafunc.definition.parent) 112 | except ValueError: 113 | # 3.6.0 <= pytest < 3.7.0; `FixtureManager.getfixtureclosure` returns 2 values 114 | fixturenames_closure, arg2fixturedefs = fm.getfixtureclosure([val.name], metafunc.definition.parent) 115 | except AttributeError: 116 | # pytest < 3.6.0; `Metafunc` has no `definition` attribute 117 | fixturenames_closure, arg2fixturedefs = fm.getfixtureclosure([val.name], current_node) 118 | 119 | extra_fixturenames = [fname for fname in fixturenames_closure 120 | if fname not in callspec.params and fname not in callspec.funcargs] 121 | 122 | newmetafunc = copy_metafunc(metafunc) 123 | newmetafunc.fixturenames = extra_fixturenames 124 | newmetafunc._arg2fixturedefs.update(arg2fixturedefs) 125 | newmetafunc._calls = [callspec] 126 | fm.pytest_generate_tests(newmetafunc) 127 | normalize_metafunc_calls(newmetafunc, valtype, used_keys | set([arg])) 128 | return newmetafunc._calls 129 | 130 | used_keys.add(arg) 131 | return [callspec] 132 | 133 | 134 | def sorted_by_dependency(params, fixturenames): 135 | free_fm = [] 136 | non_free_fm = defaultdict(list) 137 | 138 | for key in _sorted_argnames(params, fixturenames): 139 | val = params.get(key) 140 | 141 | if key not in params or not is_lazy_fixture(val) or val.name not in params: 142 | free_fm.append(key) 143 | else: 144 | non_free_fm[val.name].append(key) 145 | 146 | non_free_fm_list = [] 147 | for free_key in free_fm: 148 | non_free_fm_list.extend( 149 | _tree_to_list(non_free_fm, free_key) 150 | ) 151 | 152 | return [(key, params.get(key)) for key in (free_fm + non_free_fm_list)] 153 | 154 | 155 | def _sorted_argnames(params, fixturenames): 156 | argnames = set(params.keys()) 157 | 158 | for name in fixturenames: 159 | if name in argnames: 160 | argnames.remove(name) 161 | yield name 162 | 163 | if argnames: 164 | for name in argnames: 165 | yield name 166 | 167 | 168 | def _tree_to_list(trees, leave): 169 | lst = [] 170 | for l in trees[leave]: 171 | lst.append(l) 172 | lst.extend( 173 | _tree_to_list(trees, l) 174 | ) 175 | return lst 176 | 177 | 178 | def lazy_fixture(names): 179 | if isinstance(names, string_type): 180 | return LazyFixture(names) 181 | else: 182 | return [LazyFixture(name) for name in names] 183 | 184 | 185 | def is_lazy_fixture(val): 186 | return isinstance(val, LazyFixture) 187 | 188 | 189 | class LazyFixture(object): 190 | def __init__(self, name): 191 | self.name = name 192 | 193 | def __repr__(self): 194 | return '<{} "{}">'.format(self.__class__.__name__, self.name) 195 | 196 | def __eq__(self, other): 197 | if isinstance(other, LazyFixture): 198 | return self.name == other.name 199 | return NotImplemented 200 | -------------------------------------------------------------------------------- /tests/test_lazyfixture.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pytest 3 | from pytest_lazyfixture import sorted_by_dependency, lazy_fixture, _sorted_argnames 4 | 5 | try: 6 | import numpy 7 | except ImportError: 8 | numpy = None 9 | 10 | 11 | def test_fixture_in_parametrize_with_params(testdir): 12 | items = testdir.getitems(""" 13 | from pytest_lazyfixture import lazy_fixture 14 | import pytest 15 | @pytest.fixture(params=[1,2]) 16 | def one(request): 17 | return request.param 18 | @pytest.mark.parametrize('arg1,arg2', [ 19 | ('val1', lazy_fixture('one')), 20 | ('val1', 'val2') 21 | ]) 22 | def test_func(arg1, arg2): 23 | pass 24 | """) 25 | assert len(items) == 3 26 | assert items[0].callspec.params['one'] == 1 27 | assert items[1].callspec.params['one'] == 2 28 | 29 | 30 | def test_several_fixtures_in_parametrize_with_params(testdir): 31 | items = testdir.getitems(""" 32 | from pytest_lazyfixture import lazy_fixture 33 | import pytest 34 | @pytest.fixture(params=[1,2]) 35 | def one(request): 36 | return request.param 37 | @pytest.fixture(params=[3,4]) 38 | def two(request): 39 | return request.param 40 | @pytest.mark.parametrize('arg1,arg2,arg3', [ 41 | ('val1', lazy_fixture('one'), lazy_fixture('two')), 42 | ]) 43 | def test_func(arg1, arg2, arg3): 44 | pass 45 | """) 46 | assert len(items) == 4 47 | expected_results = [ 48 | {'one': 1, 'two': 3}, 49 | {'one': 1, 'two': 4}, 50 | {'one': 2, 'two': 3}, 51 | {'one': 2, 'two': 4} 52 | ] 53 | 54 | def is_subset(subset, superset): 55 | return all(superset[k] == subset[k] for k in subset) 56 | for item in items: 57 | assert any(is_subset(result, item.callspec.params) for result in expected_results) 58 | 59 | 60 | def test_fixtures_in_parametrize_with_indirect(testdir): 61 | items = testdir.getitems(""" 62 | from pytest_lazyfixture import lazy_fixture 63 | import pytest 64 | @pytest.fixture 65 | def one(): 66 | pass 67 | @pytest.fixture 68 | def two(): 69 | pass 70 | @pytest.mark.parametrize('arg1,one', [ 71 | ('val1', lazy_fixture('two')), 72 | ], indirect=['one']) 73 | def test_func(arg1, one): 74 | pass 75 | """) 76 | assert len(items) == 1 77 | assert items[0].callspec.params['one'].name == 'two' 78 | 79 | 80 | def test_fixtures_with_params_in_parametrize_with_indirect(testdir): 81 | items = testdir.getitems(""" 82 | from pytest_lazyfixture import lazy_fixture 83 | import pytest 84 | @pytest.fixture 85 | def one(): 86 | pass 87 | @pytest.fixture(params=[1,2]) 88 | def two(request): 89 | return request.param 90 | @pytest.mark.parametrize('arg1,one', [ 91 | ('val1', lazy_fixture('two')), 92 | ], indirect=['one']) 93 | def test_func(arg1, one): 94 | pass 95 | """) 96 | assert len(items) == 2 97 | assert items[0].callspec.params['two'] == 1 98 | assert items[1].callspec.params['two'] == 2 99 | 100 | 101 | def test_lazy_fixture_is_value_in_parametrize(testdir): 102 | testdir.makepyfile(""" 103 | from pytest_lazyfixture import lazy_fixture 104 | import pytest 105 | @pytest.fixture 106 | def one(): 107 | return 1 108 | @pytest.fixture 109 | def two(): 110 | return 2 111 | @pytest.mark.parametrize('arg1,arg2', [ 112 | lazy_fixture(('one', 'two')) 113 | ]) 114 | def test_func(arg1, arg2): 115 | assert arg1 == 1 116 | assert arg2 == 2 117 | """) 118 | reprec = testdir.inline_run('-s') 119 | reprec.assertoutcome(passed=1) 120 | 121 | 122 | def test_lazy_fixture_as_funcarg_in_parametrize_with_indirect(testdir): 123 | testdir.makepyfile(""" 124 | from pytest_lazyfixture import lazy_fixture 125 | import pytest 126 | @pytest.fixture 127 | def one(): 128 | return 1 129 | @pytest.fixture 130 | def two(): 131 | return 2 132 | @pytest.fixture 133 | def three(request): 134 | return request.param 135 | @pytest.mark.parametrize('arg1,arg2,three', [ 136 | (lazy_fixture('one'), lazy_fixture('two'), '3') 137 | ], indirect=['three']) 138 | def test_func(arg1, arg2, three): 139 | assert arg1 == 1 140 | assert arg2 == 2 141 | assert three == '3' 142 | """) 143 | reprec = testdir.inline_run('-s') 144 | reprec.assertoutcome(passed=1) 145 | 146 | 147 | def test_lazy_fixture_is_value_in_parametrize_with_indirect(testdir): 148 | testdir.makepyfile(""" 149 | from pytest_lazyfixture import lazy_fixture 150 | import pytest 151 | @pytest.fixture 152 | def one(request): 153 | return request.param 154 | @pytest.fixture 155 | def two(): 156 | return 2 157 | @pytest.mark.parametrize('one', [ 158 | lazy_fixture('two') 159 | ], indirect=True) 160 | def test_func(one): 161 | assert one == 2 162 | """) 163 | reprec = testdir.inline_run() 164 | reprec.assertoutcome(passed=1) 165 | 166 | 167 | def test_lazy_fixture_as_param_of_fixture(testdir): 168 | testdir.makepyfile(""" 169 | from pytest_lazyfixture import lazy_fixture 170 | import pytest 171 | @pytest.fixture(params=[ 172 | lazy_fixture('one'), 173 | lazy_fixture('two') 174 | ]) 175 | def some(request): 176 | return request.param 177 | @pytest.fixture 178 | def one(): 179 | return 1 180 | @pytest.fixture 181 | def two(): 182 | return 2 183 | def test_func(some): 184 | assert some in [1, 2] 185 | """) 186 | reprec = testdir.inline_run('-s') 187 | reprec.assertoutcome(passed=2) 188 | 189 | 190 | def test_lazy_fixture_in_params_which_has_params(testdir): 191 | testdir.makepyfile(""" 192 | from pytest_lazyfixture import lazy_fixture 193 | import pytest 194 | @pytest.fixture(params=[1, 2, 3]) 195 | def one(request): 196 | return str(request.param) 197 | @pytest.fixture 198 | def two(): 199 | return 4 200 | @pytest.fixture(params=[ 201 | lazy_fixture('one'), 202 | lazy_fixture('two') 203 | ]) 204 | def some(request): 205 | return request.param 206 | def test_func(some): 207 | assert some in {'1', '2', '3', 4} 208 | """) 209 | reprec = testdir.inline_run('-s') 210 | reprec.assertoutcome(passed=4) 211 | 212 | 213 | def test_lazy_fixture_three_times_nested(testdir): 214 | testdir.makepyfile(""" 215 | from pytest_lazyfixture import lazy_fixture 216 | import pytest 217 | @pytest.fixture(params=[ 218 | 1, 2, lazy_fixture('three')]) 219 | def one(request): 220 | return str(request.param) 221 | @pytest.fixture 222 | def two(): 223 | return 4 224 | @pytest.fixture 225 | def three(): 226 | return 3 227 | @pytest.fixture(params=[ 228 | lazy_fixture('one'), 229 | lazy_fixture('two') 230 | ]) 231 | def some(request): 232 | return request.param 233 | def test_func(some): 234 | assert some in {'1', '2', '3', 4} 235 | """) 236 | reprec = testdir.inline_run('-s') 237 | reprec.assertoutcome(passed=4) 238 | 239 | 240 | def test_lazy_fixture_three_times_nested_with_one_failed(testdir): 241 | testdir.makepyfile(""" 242 | from pytest_lazyfixture import lazy_fixture 243 | import pytest 244 | @pytest.fixture(params=[ 245 | 1, 2, lazy_fixture('three') 246 | ]) 247 | def one(request): 248 | return str(request.param) 249 | @pytest.fixture 250 | def two(): 251 | return 4 252 | @pytest.fixture 253 | def three(): 254 | return 5 255 | @pytest.fixture(params=[ 256 | lazy_fixture('one'), 257 | lazy_fixture('two') 258 | ]) 259 | def some(request): 260 | return request.param 261 | def test_func(some): 262 | assert some in {'1', '2', '3', 4} 263 | """) 264 | reprec = testdir.inline_run('-s') 265 | reprec.assertoutcome(passed=3, failed=1) 266 | 267 | 268 | def test_lazy_fixture_common_dependency(testdir): 269 | testdir.makepyfile(""" 270 | from pytest_lazyfixture import lazy_fixture 271 | import pytest 272 | @pytest.fixture(params=[1, 2, 3]) 273 | def one(request): 274 | return request.param 275 | @pytest.fixture(params=[lazy_fixture('one')]) 276 | def as_str(request): 277 | return str(request.param) 278 | @pytest.fixture(params=[lazy_fixture('one')]) 279 | def as_hex(request): 280 | return hex(request.param) 281 | 282 | def test_as_str(as_str): 283 | assert as_str in {'1', '2', '3'} 284 | def test_as_hex(as_hex): 285 | assert as_hex in {'0x1', '0x2', '0x3'} 286 | 287 | def test_as_hex_vs_as_str(as_str, as_hex): 288 | assert int(as_hex, 16) == int(as_str) 289 | """) 290 | reprec = testdir.inline_run('-s') 291 | reprec.assertoutcome(passed=9) 292 | 293 | 294 | def test_lazy_fixture_common_dependency_with_getfixturevalue(testdir): 295 | testdir.makepyfile(""" 296 | from pytest_lazyfixture import lazy_fixture 297 | import pytest 298 | @pytest.fixture(params=[1, 2, 3]) 299 | def one(request): 300 | return request.param 301 | @pytest.fixture(params=[lazy_fixture('one')]) 302 | def as_str(request): 303 | return str(request.getfixturevalue('one')) 304 | @pytest.fixture(params=[lazy_fixture('one')]) 305 | def as_hex(request): 306 | return hex(request.getfixturevalue('one')) 307 | def test_as_str(as_str): 308 | assert as_str in {'1', '2', '3'} 309 | def test_as_hex(as_hex): 310 | assert as_hex in {'0x1', '0x2', '0x3'} 311 | def test_as_hex_vs_as_str(as_str, as_hex): 312 | assert int(as_hex, 16) == int(as_str) 313 | """) 314 | reprec = testdir.inline_run('-s') 315 | reprec.assertoutcome(passed=9) 316 | 317 | 318 | def test_issues2(testdir): 319 | testdir.makepyfile(""" 320 | from pytest_lazyfixture import lazy_fixture 321 | import pytest 322 | @pytest.fixture(params=[1, 2, 3]) 323 | def one(request): 324 | return request.param 325 | 326 | @pytest.fixture(params=[lazy_fixture('one')]) 327 | def as_str(request): 328 | return str(request.getfixturevalue('one')) 329 | 330 | @pytest.mark.parametrize('val', ('a', 'b', 'c')) 331 | def test_as_str(val, as_str): 332 | combined = ''.join((val, as_str)) 333 | assert combined in {'a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'} 334 | """) 335 | reprec = testdir.inline_run('-s') 336 | reprec.assertoutcome(passed=9) 337 | 338 | 339 | def test_issues2_2(testdir): 340 | testdir.makepyfile(""" 341 | from pytest_lazyfixture import lazy_fixture 342 | import pytest 343 | @pytest.fixture(params=[1, 2, 3]) 344 | def one(request): 345 | return request.param 346 | 347 | @pytest.fixture(params=[lazy_fixture('one')]) 348 | def as_str(request): 349 | return str(request.getfixturevalue('one')) 350 | 351 | @pytest.mark.parametrize('val, one', ( 352 | ('a', '1'), ('b', '2'), ('c', '3') 353 | ), indirect=['one']) 354 | def test_as_str(val, one, as_str): 355 | combined = ''.join((val, as_str)) 356 | assert combined in {'a1', 'b2', 'c3'} 357 | """) 358 | reprec = testdir.inline_run('-s') 359 | reprec.assertoutcome(passed=3) 360 | 361 | 362 | def test_issues3_autouse_fixtures_should_run_first(testdir): 363 | testdir.makepyfile(""" 364 | from pytest_lazyfixture import lazy_fixture 365 | import pytest 366 | gl = False 367 | @pytest.fixture(autouse=True) 368 | def auto_one(): 369 | global gl 370 | gl = True 371 | 372 | @pytest.fixture 373 | def one(): 374 | return 1 if gl is True else -1 375 | 376 | @pytest.mark.parametrize('arg1', [ 377 | lazy_fixture('one') 378 | ]) 379 | def test_some(arg1): 380 | assert arg1 == 1 381 | """) 382 | reprec = testdir.inline_run('-s') 383 | reprec.assertoutcome(passed=1) 384 | 385 | 386 | def test_issues10_xfail(testdir): 387 | testdir.makepyfile(""" 388 | from pytest_lazyfixture import lazy_fixture 389 | import pytest 390 | def division(a, b): 391 | return a / b 392 | 393 | @pytest.fixture(params=[0]) 394 | def zero(request): 395 | return request.param 396 | 397 | @pytest.mark.parametrize(('a', 'b'), [ 398 | pytest.param(1, lazy_fixture('zero'), marks=pytest.mark.xfail(reason=ZeroDivisionError)) 399 | ]) 400 | def test_division(a, b): 401 | division(a, b) 402 | """) 403 | reprec = testdir.inline_run('-s', '-v') 404 | reprec.assertoutcome(skipped=1) 405 | 406 | 407 | def test_issues11_autouse_fixture_in_test_class(testdir): 408 | testdir.makepyfile(""" 409 | import pytest 410 | 411 | class TestModels(object): 412 | @pytest.fixture(autouse=True) 413 | def setup(self): 414 | self.var = 15 415 | 416 | def test_model_a(self): 417 | assert self.var == 15 418 | 419 | def test_model_b(self): 420 | assert self.var == 15 421 | 422 | """) 423 | reprec = testdir.inline_run('-s', '-v') 424 | reprec.assertoutcome(passed=2) 425 | 426 | 427 | def test_issues12_skip_test_function(testdir): 428 | testdir.makepyfile(""" 429 | from pytest_lazyfixture import lazy_fixture 430 | import pytest 431 | 432 | @pytest.fixture 433 | def one(): 434 | return 1 435 | 436 | @pytest.mark.parametrize('a', [ 437 | pytest.param(lazy_fixture('one'), marks=pytest.mark.skip(reason='skip')) 438 | ]) 439 | def test_skip1(a): 440 | assert a == 1 441 | 442 | @pytest.mark.skip(reason='skip') 443 | @pytest.mark.parametrize('a', [ 444 | lazy_fixture('one') 445 | ]) 446 | def test_skip2(a): 447 | assert a == 1 448 | 449 | def test_after_skip(one): 450 | assert one == 1 451 | """) 452 | reprec = testdir.inline_run('-s', '-v') 453 | reprec.assertoutcome(skipped=2, passed=1) 454 | 455 | 456 | def test_issues12_skip_test_method(testdir): 457 | testdir.makepyfile(""" 458 | from pytest_lazyfixture import lazy_fixture 459 | import pytest 460 | 461 | class TestModels: 462 | @pytest.fixture 463 | def one(self): 464 | return 1 465 | 466 | @pytest.mark.skip(reason='skip this') 467 | @pytest.mark.parametrize('a', [ 468 | lazy_fixture('one') 469 | ]) 470 | def test_model_a(self, a): 471 | assert a == 1 472 | 473 | @pytest.mark.parametrize('a', [ 474 | pytest.param(lazy_fixture('one'), marks=pytest.mark.skip(reason='skip this')) 475 | ]) 476 | def test_model_b(self, a): 477 | assert a == 1 478 | 479 | def test_after_skip(self, one): 480 | assert one == 1 481 | """) 482 | reprec = testdir.runpytest('-s', '-v') 483 | reprec.assert_outcomes(skipped=2, passed=1) 484 | 485 | 486 | def test_issues12_lf_as_method_of_test_class(testdir): 487 | testdir.makepyfile(""" 488 | from pytest_lazyfixture import lazy_fixture 489 | import pytest 490 | 491 | class TestModels: 492 | @pytest.fixture 493 | def one(self): 494 | return 1 495 | 496 | @pytest.mark.parametrize('a', [ 497 | lazy_fixture('one') 498 | ]) 499 | def test_lf(self, a): 500 | assert a == 1 501 | """) 502 | reprec = testdir.inline_run('-s', '-v') 503 | reprec.assertoutcome(passed=1) 504 | 505 | 506 | def test_issues13_unittest_testcase_class_should_not_fail(testdir): 507 | testdir.makepyfile(""" 508 | import unittest 509 | import pytest 510 | 511 | class TestModels(unittest.TestCase): 512 | def test_models(self): 513 | assert True 514 | 515 | def test_models_fail(self): 516 | assert False 517 | """) 518 | reprec = testdir.inline_run('-s', '-v') 519 | reprec.assertoutcome(passed=1, failed=1) 520 | 521 | 522 | def test_argnames_initialized_in_right_order(testdir): 523 | testdir.makepyfile(""" 524 | from pytest_lazyfixture import lazy_fixture 525 | import pytest 526 | @pytest.fixture 527 | def one(): 528 | return [1] 529 | 530 | @pytest.fixture 531 | def plus_two(a): 532 | a[0] = a[0] + 2 533 | 534 | @pytest.mark.parametrize('a,b', [ 535 | (lazy_fixture('one'), lazy_fixture('plus_two')) 536 | ]) 537 | def test_skip1(a, b): 538 | assert a == [3] 539 | """) 540 | reprec = testdir.inline_run('-s', '-v') 541 | reprec.assertoutcome(passed=1) 542 | 543 | 544 | # https://github.com/TvoroG/pytest-lazy-fixture/pull/19 545 | def test_argnames_initialized_in_right_order2(testdir): 546 | testdir.makepyfile(""" 547 | from pytest_lazyfixture import lazy_fixture 548 | import pytest 549 | @pytest.fixture 550 | def one(): 551 | return [1] 552 | 553 | @pytest.fixture 554 | def plus_two(a): 555 | a[0] = a[0] + 2 556 | def test_skip1(a): 557 | assert a == [3] 558 | 559 | def pytest_generate_tests(metafunc): 560 | metafunc.fixturenames = ['a', 'b'] 561 | metafunc.parametrize(argnames=['a', 'b'], 562 | argvalues=[(lazy_fixture('one'), lazy_fixture('plus_two'))], 563 | indirect=['b']) 564 | 565 | """) 566 | reprec = testdir.inline_run('-s', '-v') 567 | reprec.assertoutcome(passed=1) 568 | 569 | 570 | def lf(fname): 571 | return lazy_fixture(fname) 572 | 573 | 574 | @pytest.mark.parametrize('params,expected_paths', [ 575 | ( 576 | {'some': lf('one'), 'one': lf('three')}, 577 | ['one>some'], 578 | ), 579 | ( 580 | {'grand1': lf('parent1_1'), 'parent1_1': lf('child1'), 581 | 'grand2': lf('parent1_2'), 'parent1_2': lf('child1'), 582 | 'child1': lf('none')}, 583 | ['child1>parent1_1>grand1>parent1_2>grand2', 'child1>parent1_2>grand2>parent1_1>grand1'] 584 | ), 585 | ( 586 | {'param1': 'val1', 'param2': 'val2'}, 587 | ['param1>param2', 'param2>param1'] 588 | ), 589 | ({}, ['']), 590 | ({'param1': 'val1'}, ['param1']), 591 | ({'param1': lf('some')}, ['param1']), 592 | ( 593 | {'one': 1, 'as_str': lf('one'), 'as_hex': lf('one')}, 594 | ['one>as_str>as_hex', 'one>as_hex>as_str'] 595 | ) 596 | ]) 597 | def test_sorted_by_dependency(params, expected_paths): 598 | sp = sorted_by_dependency(params, []) 599 | path = '>'.join(param for param, _ in sp) 600 | 601 | assert path in expected_paths 602 | 603 | 604 | @pytest.mark.parametrize('params,fixturenames,expect_keys', [ 605 | ({'b': 1, 'a': 0}, ['c', 'a', 'd', 'b'], ['c', 'a', 'd', 'b']), 606 | ({'b': 1, 'a': 0}, ['c', 'b'], ['c', 'b', 'a']) 607 | ]) 608 | def test_sorted_argnames(params, fixturenames, expect_keys): 609 | assert list(_sorted_argnames(params, fixturenames)) == expect_keys 610 | 611 | 612 | def test_lazy_fixtures_with_subfixtures(testdir): 613 | testdir.makepyfile(""" 614 | from pytest_lazyfixture import lazy_fixture 615 | import pytest 616 | 617 | @pytest.fixture(params=["a", "A"]) 618 | def a(request): 619 | return request.param 620 | 621 | @pytest.fixture(params=["b", "B"]) 622 | def b(a, request): 623 | return request.param + a 624 | 625 | @pytest.fixture 626 | def c(a): 627 | return "c" + a 628 | 629 | @pytest.fixture(params=[lazy_fixture('a'), lazy_fixture('b'), lazy_fixture('c')]) 630 | def d(request): 631 | return "d" + request.param 632 | 633 | @pytest.fixture(params=[lazy_fixture('a'), lazy_fixture('d'), ""]) 634 | def e(request): 635 | return "e" + request.param 636 | 637 | def test_one(d): 638 | assert d in ("da", "dA", "dba", "dbA", "dBa", "dBA", "dca", "dcA") 639 | 640 | def test_two(e): 641 | assert e in ("ea", "eA", "eda", "edA", "edba", "edbA", "edBa", "edBA", "edca", "edcA", "e") 642 | """) 643 | reprec = testdir.inline_run('-s', '-v') 644 | reprec.assertoutcome(passed=19) 645 | 646 | 647 | def test_lazy_fixtures_in_subfixture(testdir): 648 | testdir.makepyfile(""" 649 | from pytest_lazyfixture import lazy_fixture 650 | import pytest 651 | 652 | @pytest.fixture 653 | def a(): 654 | return "a" 655 | 656 | @pytest.fixture 657 | def b(): 658 | return "b" 659 | 660 | @pytest.fixture(params=[lazy_fixture('a'), lazy_fixture('b')]) 661 | def c(request): 662 | return "c" + request.param 663 | 664 | @pytest.fixture 665 | def d(c): 666 | return "d" + c 667 | 668 | def test_one(d): 669 | assert d in ("dca", "dcb") 670 | """) 671 | reprec = testdir.inline_run('-s', '-v') 672 | reprec.assertoutcome(passed=2) 673 | 674 | 675 | @pytest.mark.parametrize('autouse', [False, True]) 676 | def test_issues23(testdir, autouse): 677 | testdir.makepyfile(""" 678 | from pytest_lazyfixture import lazy_fixture 679 | import pytest 680 | 681 | @pytest.fixture(params=[0, 1], autouse={}) 682 | def zero(request): 683 | return request.param 684 | 685 | @pytest.fixture(params=[1]) 686 | def one(request, zero): 687 | return zero * request.param 688 | 689 | @pytest.fixture(params=[ 690 | lazy_fixture('one'), 691 | ]) 692 | def some(request): 693 | return request.param 694 | 695 | def test_func(some): 696 | assert some in [0, 1] 697 | 698 | """.format(autouse)) 699 | reprec = testdir.inline_run('-s', '-v') 700 | reprec.assertoutcome(passed=2) 701 | 702 | 703 | def test_lazy_fixture_nested_fixtures(testdir): 704 | testdir.makepyfile(""" 705 | from pytest_lazyfixture import lazy_fixture 706 | import pytest 707 | 708 | @pytest.fixture 709 | def one(request): 710 | return "SOME_VALUE" 711 | 712 | @pytest.fixture 713 | def two(request): 714 | return "SOME_VALUE2" 715 | 716 | @pytest.fixture(params=[ 717 | lazy_fixture("one"), 718 | lazy_fixture("two"), 719 | ]) 720 | def some_fixture1(request): 721 | return request.param 722 | 723 | @pytest.fixture 724 | def some_fixture2(some_fixture1): 725 | return "NEW_" + some_fixture1 726 | 727 | def test_func(some_fixture2): 728 | assert ((some_fixture2 == "NEW_SOME_VALUE") or (some_fixture2 == "NEW_SOME_VALUE2")) 729 | """) 730 | reprec = testdir.inline_run('-s') 731 | reprec.assertoutcome(passed=2) 732 | 733 | 734 | # https://github.com/TvoroG/pytest-lazy-fixture/issues/39 735 | def test_usefixture_runs_before_function_fixtures(testdir): 736 | testdir.makepyfile(""" 737 | import pytest 738 | from pytest_lazyfixture import lazy_fixture 739 | 740 | invocation_order = [] 741 | 742 | @pytest.fixture 743 | def module_fixture(): 744 | invocation_order.append('using module fixture') 745 | 746 | @pytest.fixture 747 | def fixture1(): 748 | invocation_order.append('using fixture1') 749 | return 'fixture1' 750 | 751 | @pytest.fixture 752 | def fixture2(): 753 | invocation_order.append('using fixture2') 754 | return 'fixture2' 755 | 756 | @pytest.mark.usefixtures("module_fixture") 757 | @pytest.mark.parametrize("fixt", [lazy_fixture("fixture1"), lazy_fixture("fixture2")]) 758 | def test_test(fixt): 759 | if fixt == 'fixture2': 760 | print(' '.join(invocation_order)) 761 | """) 762 | result = testdir.runpytest('-s') 763 | stdout = result.stdout.str() 764 | assert ( 765 | 'using module fixture using fixture1 using module fixture using fixture2' in stdout 766 | ) 767 | 768 | 769 | # https://github.com/TvoroG/pytest-lazy-fixture/issues/39 770 | def test_autouse_and_usefixture_module_scope_runs_before_function_fixtures(testdir): 771 | testdir.makepyfile(""" 772 | import pytest 773 | from pytest_lazyfixture import lazy_fixture 774 | 775 | invocation_order = [] 776 | 777 | @pytest.fixture(autouse=True) 778 | def autouse_fixture(): 779 | invocation_order.append('using autouse_fixture') 780 | 781 | @pytest.fixture(scope='module') 782 | def module_fixture(): 783 | invocation_order.append('using module fixture') 784 | 785 | @pytest.fixture 786 | def fixture1(): 787 | invocation_order.append('using fixture1') 788 | return 'fixture1' 789 | 790 | @pytest.fixture 791 | def fixture2(): 792 | invocation_order.append('using fixture2') 793 | return 'fixture2' 794 | 795 | @pytest.mark.usefixtures("module_fixture") 796 | @pytest.mark.parametrize("fixt", [lazy_fixture("fixture1"), lazy_fixture("fixture2")]) 797 | def test_test(fixt): 798 | if fixt == 'fixture2': 799 | print(' '.join(invocation_order)) 800 | """) 801 | result = testdir.runpytest('-s') 802 | stdout = result.stdout.str() 803 | assert ( 804 | # pytest==3.2.5 805 | 'using autouse_fixture using module fixture using fixture1 using autouse_fixture using fixture2' in stdout 806 | or 807 | 'using module fixture using autouse_fixture using fixture1 using autouse_fixture using fixture2' in stdout 808 | ) 809 | 810 | 811 | @pytest.mark.parametrize('autouse_scope', [ 812 | 'session', 813 | 'module', 814 | pytest.param('function', marks=pytest.mark.xfail) 815 | ]) 816 | def test_session_autouse_and_usefixture_module_scope_runs_before_function_fixtures(testdir, autouse_scope): 817 | testdir.makepyfile(""" 818 | import pytest 819 | from pytest_lazyfixture import lazy_fixture 820 | 821 | invocation_order = [] 822 | 823 | @pytest.fixture(autouse=True, scope='{autouse_scope}') 824 | def autouse_fixture(): 825 | invocation_order.append('using autouse_fixture') 826 | 827 | @pytest.fixture(scope='module') 828 | def module_fixture(): 829 | invocation_order.append('using module fixture') 830 | 831 | @pytest.fixture 832 | def fixture1(): 833 | invocation_order.append("using fixture1") 834 | return 'fixture1' 835 | 836 | @pytest.fixture 837 | def fixture2(): 838 | invocation_order.append("using fixture2") 839 | return 'fixture2' 840 | 841 | @pytest.mark.usefixtures("module_fixture") 842 | @pytest.mark.parametrize("fixt", [lazy_fixture("fixture1"), lazy_fixture("fixture2")]) 843 | def test_test(fixt): 844 | if fixt == 'fixture2': 845 | print(' '.join(invocation_order)) 846 | """.format(autouse_scope=autouse_scope)) 847 | result = testdir.runpytest('-s') 848 | assert 'using autouse_fixture using module fixture using fixture1 using fixture2' in result.stdout.str() 849 | 850 | 851 | # https://github.com/TvoroG/pytest-lazy-fixture/issues/39 852 | def test_module_scope_runs_before_function_fixtures(testdir): 853 | testdir.makepyfile(""" 854 | import pytest 855 | from pytest_lazyfixture import lazy_fixture 856 | 857 | invocation_order = [] 858 | 859 | @pytest.fixture(scope='module') 860 | def module_fixture(): 861 | invocation_order.append('using module fixture') 862 | 863 | @pytest.fixture 864 | def fixture1(): 865 | invocation_order.append("using fixture1") 866 | return 'fixture1' 867 | 868 | @pytest.fixture 869 | def fixture2(): 870 | invocation_order.append("using fixture2") 871 | return 'fixture2' 872 | 873 | @pytest.mark.parametrize("fixt", [lazy_fixture("fixture1"), lazy_fixture("fixture2")]) 874 | def test_test(fixt, module_fixture): 875 | if fixt == 'fixture2': 876 | print(' '.join(invocation_order)) 877 | """) 878 | result = testdir.runpytest('-s') 879 | stdout = result.stdout.str() 880 | assert ( 881 | # pytest==3.2.5 882 | 'using fixture1 using module fixture using fixture2' in stdout 883 | or 884 | 'using module fixture using fixture1 using fixture2' in stdout 885 | ) 886 | 887 | 888 | # https://github.com/TvoroG/pytest-lazy-fixture/issues/42 889 | @pytest.mark.skipif(numpy is None, reason='numpy is not installed') 890 | def test_numpy_array_as_value(testdir): 891 | testdir.makepyfile(""" 892 | import pytest 893 | import numpy as np 894 | 895 | @pytest.mark.parametrize( 896 | 'value', 897 | [ 898 | np.arange(10, dtype=np.int64), 899 | np.arange(10, dtype=np.int32), 900 | ] 901 | ) 902 | def test_bug(value): 903 | assert isinstance(value, np.ndarray) 904 | """) 905 | result = testdir.inline_run('-s') 906 | result.assertoutcome(passed=2) 907 | 908 | 909 | # https://github.com/TvoroG/pytest-lazy-fixture/issues/46 910 | def test_lazy_fixture_ids(testdir): 911 | testdir.makepyfile(""" 912 | import pytest 913 | from pytest_lazyfixture import lazy_fixture 914 | 915 | @pytest.fixture() 916 | def foo(): 917 | return "foo" 918 | 919 | @pytest.fixture(params=['spam', 'eggs']) 920 | def bar(request): 921 | return "bar-{}".format(request.param) 922 | 923 | @pytest.mark.parametrize("data", [lazy_fixture("foo"), 924 | lazy_fixture("bar")]) 925 | def test_the_thing(data): 926 | assert False 927 | """) 928 | result = testdir.runpytest('--collect-only') 929 | stdout = result.stdout.str() 930 | assert 'test_the_thing[foo]' in stdout 931 | assert 'test_the_thing[bar-spam]' in stdout 932 | assert 'test_the_thing[bar-eggs]' in stdout 933 | 934 | 935 | def test_eq(): 936 | assert lazy_fixture("Lol") == lazy_fixture("Lol") 937 | assert lazy_fixture("Lol") != lazy_fixture("Wut") 938 | assert lazy_fixture("Lol") != 123 939 | --------------------------------------------------------------------------------