1# -*- coding: utf-8 -*-
2import sys
3import textwrap
4
5import pytest
6from _pytest import fixtures
7from _pytest.fixtures import FixtureLookupError
8from _pytest.fixtures import FixtureRequest
9from _pytest.pathlib import Path
10from _pytest.pytester import get_public_names
11from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
12
13
14def test_getfuncargnames():
15    def f():
16        pass
17
18    assert not fixtures.getfuncargnames(f)
19
20    def g(arg):
21        pass
22
23    assert fixtures.getfuncargnames(g) == ("arg",)
24
25    def h(arg1, arg2="hello"):
26        pass
27
28    assert fixtures.getfuncargnames(h) == ("arg1",)
29
30    def h(arg1, arg2, arg3="hello"):
31        pass
32
33    assert fixtures.getfuncargnames(h) == ("arg1", "arg2")
34
35    class A(object):
36        def f(self, arg1, arg2="hello"):
37            pass
38
39        @staticmethod
40        def static(arg1, arg2):
41            pass
42
43    assert fixtures.getfuncargnames(A().f) == ("arg1",)
44    assert fixtures.getfuncargnames(A.static, cls=A) == ("arg1", "arg2")
45
46
47@pytest.mark.pytester_example_path("fixtures/fill_fixtures")
48class TestFillFixtures(object):
49    def test_fillfuncargs_exposed(self):
50        # used by oejskit, kept for compatibility
51        assert pytest._fillfuncargs == fixtures.fillfixtures
52
53    def test_funcarg_lookupfails(self, testdir):
54        testdir.copy_example()
55        result = testdir.runpytest()  # "--collect-only")
56        assert result.ret != 0
57        result.stdout.fnmatch_lines(
58            """
59            *def test_func(some)*
60            *fixture*some*not found*
61            *xyzsomething*
62            """
63        )
64
65    def test_detect_recursive_dependency_error(self, testdir):
66        testdir.copy_example()
67        result = testdir.runpytest()
68        result.stdout.fnmatch_lines(
69            ["*recursive dependency involving fixture 'fix1' detected*"]
70        )
71
72    def test_funcarg_basic(self, testdir):
73        testdir.copy_example()
74        item = testdir.getitem(Path("test_funcarg_basic.py"))
75        fixtures.fillfixtures(item)
76        del item.funcargs["request"]
77        assert len(get_public_names(item.funcargs)) == 2
78        assert item.funcargs["some"] == "test_func"
79        assert item.funcargs["other"] == 42
80
81    def test_funcarg_lookup_modulelevel(self, testdir):
82        testdir.copy_example()
83        reprec = testdir.inline_run()
84        reprec.assertoutcome(passed=2)
85
86    def test_funcarg_lookup_classlevel(self, testdir):
87        p = testdir.copy_example()
88        result = testdir.runpytest(p)
89        result.stdout.fnmatch_lines(["*1 passed*"])
90
91    def test_conftest_funcargs_only_available_in_subdir(self, testdir):
92        testdir.copy_example()
93        result = testdir.runpytest("-v")
94        result.assert_outcomes(passed=2)
95
96    def test_extend_fixture_module_class(self, testdir):
97        testfile = testdir.copy_example()
98        result = testdir.runpytest()
99        result.stdout.fnmatch_lines(["*1 passed*"])
100        result = testdir.runpytest(testfile)
101        result.stdout.fnmatch_lines(["*1 passed*"])
102
103    def test_extend_fixture_conftest_module(self, testdir):
104        p = testdir.copy_example()
105        result = testdir.runpytest()
106        result.stdout.fnmatch_lines(["*1 passed*"])
107        result = testdir.runpytest(next(p.visit("test_*.py")))
108        result.stdout.fnmatch_lines(["*1 passed*"])
109
110    def test_extend_fixture_conftest_conftest(self, testdir):
111        p = testdir.copy_example()
112        result = testdir.runpytest()
113        result.stdout.fnmatch_lines(["*1 passed*"])
114        result = testdir.runpytest(next(p.visit("test_*.py")))
115        result.stdout.fnmatch_lines(["*1 passed*"])
116
117    def test_extend_fixture_conftest_plugin(self, testdir):
118        testdir.makepyfile(
119            testplugin="""
120            import pytest
121
122            @pytest.fixture
123            def foo():
124                return 7
125        """
126        )
127        testdir.syspathinsert()
128        testdir.makeconftest(
129            """
130            import pytest
131
132            pytest_plugins = 'testplugin'
133
134            @pytest.fixture
135            def foo(foo):
136                return foo + 7
137        """
138        )
139        testdir.makepyfile(
140            """
141            def test_foo(foo):
142                assert foo == 14
143        """
144        )
145        result = testdir.runpytest("-s")
146        assert result.ret == 0
147
148    def test_extend_fixture_plugin_plugin(self, testdir):
149        # Two plugins should extend each order in loading order
150        testdir.makepyfile(
151            testplugin0="""
152            import pytest
153
154            @pytest.fixture
155            def foo():
156                return 7
157        """
158        )
159        testdir.makepyfile(
160            testplugin1="""
161            import pytest
162
163            @pytest.fixture
164            def foo(foo):
165                return foo + 7
166        """
167        )
168        testdir.syspathinsert()
169        testdir.makepyfile(
170            """
171            pytest_plugins = ['testplugin0', 'testplugin1']
172
173            def test_foo(foo):
174                assert foo == 14
175        """
176        )
177        result = testdir.runpytest()
178        assert result.ret == 0
179
180    def test_override_parametrized_fixture_conftest_module(self, testdir):
181        """Test override of the parametrized fixture with non-parametrized one on the test module level."""
182        testdir.makeconftest(
183            """
184            import pytest
185
186            @pytest.fixture(params=[1, 2, 3])
187            def spam(request):
188                return request.param
189        """
190        )
191        testfile = testdir.makepyfile(
192            """
193            import pytest
194
195            @pytest.fixture
196            def spam():
197                return 'spam'
198
199            def test_spam(spam):
200                assert spam == 'spam'
201        """
202        )
203        result = testdir.runpytest()
204        result.stdout.fnmatch_lines(["*1 passed*"])
205        result = testdir.runpytest(testfile)
206        result.stdout.fnmatch_lines(["*1 passed*"])
207
208    def test_override_parametrized_fixture_conftest_conftest(self, testdir):
209        """Test override of the parametrized fixture with non-parametrized one on the conftest level."""
210        testdir.makeconftest(
211            """
212            import pytest
213
214            @pytest.fixture(params=[1, 2, 3])
215            def spam(request):
216                return request.param
217        """
218        )
219        subdir = testdir.mkpydir("subdir")
220        subdir.join("conftest.py").write(
221            textwrap.dedent(
222                """\
223                import pytest
224
225                @pytest.fixture
226                def spam():
227                    return 'spam'
228                """
229            )
230        )
231        testfile = subdir.join("test_spam.py")
232        testfile.write(
233            textwrap.dedent(
234                """\
235                def test_spam(spam):
236                    assert spam == "spam"
237                """
238            )
239        )
240        result = testdir.runpytest()
241        result.stdout.fnmatch_lines(["*1 passed*"])
242        result = testdir.runpytest(testfile)
243        result.stdout.fnmatch_lines(["*1 passed*"])
244
245    def test_override_non_parametrized_fixture_conftest_module(self, testdir):
246        """Test override of the non-parametrized fixture with parametrized one on the test module level."""
247        testdir.makeconftest(
248            """
249            import pytest
250
251            @pytest.fixture
252            def spam():
253                return 'spam'
254        """
255        )
256        testfile = testdir.makepyfile(
257            """
258            import pytest
259
260            @pytest.fixture(params=[1, 2, 3])
261            def spam(request):
262                return request.param
263
264            params = {'spam': 1}
265
266            def test_spam(spam):
267                assert spam == params['spam']
268                params['spam'] += 1
269        """
270        )
271        result = testdir.runpytest()
272        result.stdout.fnmatch_lines(["*3 passed*"])
273        result = testdir.runpytest(testfile)
274        result.stdout.fnmatch_lines(["*3 passed*"])
275
276    def test_override_non_parametrized_fixture_conftest_conftest(self, testdir):
277        """Test override of the non-parametrized fixture with parametrized one on the conftest level."""
278        testdir.makeconftest(
279            """
280            import pytest
281
282            @pytest.fixture
283            def spam():
284                return 'spam'
285        """
286        )
287        subdir = testdir.mkpydir("subdir")
288        subdir.join("conftest.py").write(
289            textwrap.dedent(
290                """\
291                import pytest
292
293                @pytest.fixture(params=[1, 2, 3])
294                def spam(request):
295                    return request.param
296                """
297            )
298        )
299        testfile = subdir.join("test_spam.py")
300        testfile.write(
301            textwrap.dedent(
302                """\
303                params = {'spam': 1}
304
305                def test_spam(spam):
306                    assert spam == params['spam']
307                    params['spam'] += 1
308                """
309            )
310        )
311        result = testdir.runpytest()
312        result.stdout.fnmatch_lines(["*3 passed*"])
313        result = testdir.runpytest(testfile)
314        result.stdout.fnmatch_lines(["*3 passed*"])
315
316    def test_override_autouse_fixture_with_parametrized_fixture_conftest_conftest(
317        self, testdir
318    ):
319        """Test override of the autouse fixture with parametrized one on the conftest level.
320        This test covers the issue explained in issue 1601
321        """
322        testdir.makeconftest(
323            """
324            import pytest
325
326            @pytest.fixture(autouse=True)
327            def spam():
328                return 'spam'
329        """
330        )
331        subdir = testdir.mkpydir("subdir")
332        subdir.join("conftest.py").write(
333            textwrap.dedent(
334                """\
335                import pytest
336
337                @pytest.fixture(params=[1, 2, 3])
338                def spam(request):
339                    return request.param
340                """
341            )
342        )
343        testfile = subdir.join("test_spam.py")
344        testfile.write(
345            textwrap.dedent(
346                """\
347                params = {'spam': 1}
348
349                def test_spam(spam):
350                    assert spam == params['spam']
351                    params['spam'] += 1
352                """
353            )
354        )
355        result = testdir.runpytest()
356        result.stdout.fnmatch_lines(["*3 passed*"])
357        result = testdir.runpytest(testfile)
358        result.stdout.fnmatch_lines(["*3 passed*"])
359
360    def test_autouse_fixture_plugin(self, testdir):
361        # A fixture from a plugin has no baseid set, which screwed up
362        # the autouse fixture handling.
363        testdir.makepyfile(
364            testplugin="""
365            import pytest
366
367            @pytest.fixture(autouse=True)
368            def foo(request):
369                request.function.foo = 7
370        """
371        )
372        testdir.syspathinsert()
373        testdir.makepyfile(
374            """
375            pytest_plugins = 'testplugin'
376
377            def test_foo(request):
378                assert request.function.foo == 7
379        """
380        )
381        result = testdir.runpytest()
382        assert result.ret == 0
383
384    def test_funcarg_lookup_error(self, testdir):
385        testdir.makeconftest(
386            """
387            import pytest
388
389            @pytest.fixture
390            def a_fixture(): pass
391
392            @pytest.fixture
393            def b_fixture(): pass
394
395            @pytest.fixture
396            def c_fixture(): pass
397
398            @pytest.fixture
399            def d_fixture(): pass
400        """
401        )
402        testdir.makepyfile(
403            """
404            def test_lookup_error(unknown):
405                pass
406        """
407        )
408        result = testdir.runpytest()
409        result.stdout.fnmatch_lines(
410            [
411                "*ERROR at setup of test_lookup_error*",
412                "  def test_lookup_error(unknown):*",
413                "E       fixture 'unknown' not found",
414                ">       available fixtures:*a_fixture,*b_fixture,*c_fixture,*d_fixture*monkeypatch,*",  # sorted
415                ">       use 'py*test --fixtures *' for help on them.",
416                "*1 error*",
417            ]
418        )
419        assert "INTERNAL" not in result.stdout.str()
420
421    def test_fixture_excinfo_leak(self, testdir):
422        # on python2 sys.excinfo would leak into fixture executions
423        testdir.makepyfile(
424            """
425            import sys
426            import traceback
427            import pytest
428
429            @pytest.fixture
430            def leak():
431                if sys.exc_info()[0]:  # python3 bug :)
432                    traceback.print_exc()
433                #fails
434                assert sys.exc_info() == (None, None, None)
435
436            def test_leak(leak):
437                if sys.exc_info()[0]:  # python3 bug :)
438                    traceback.print_exc()
439                assert sys.exc_info() == (None, None, None)
440        """
441        )
442        result = testdir.runpytest()
443        assert result.ret == 0
444
445
446class TestRequestBasic(object):
447    def test_request_attributes(self, testdir):
448        item = testdir.getitem(
449            """
450            import pytest
451
452            @pytest.fixture
453            def something(request): pass
454            def test_func(something): pass
455        """
456        )
457        req = fixtures.FixtureRequest(item)
458        assert req.function == item.obj
459        assert req.keywords == item.keywords
460        assert hasattr(req.module, "test_func")
461        assert req.cls is None
462        assert req.function.__name__ == "test_func"
463        assert req.config == item.config
464        assert repr(req).find(req.function.__name__) != -1
465
466    def test_request_attributes_method(self, testdir):
467        (item,) = testdir.getitems(
468            """
469            import pytest
470            class TestB(object):
471
472                @pytest.fixture
473                def something(self, request):
474                    return 1
475                def test_func(self, something):
476                    pass
477        """
478        )
479        req = item._request
480        assert req.cls.__name__ == "TestB"
481        assert req.instance.__class__ == req.cls
482
483    def test_request_contains_funcarg_arg2fixturedefs(self, testdir):
484        modcol = testdir.getmodulecol(
485            """
486            import pytest
487            @pytest.fixture
488            def something(request):
489                pass
490            class TestClass(object):
491                def test_method(self, something):
492                    pass
493        """
494        )
495        (item1,) = testdir.genitems([modcol])
496        assert item1.name == "test_method"
497        arg2fixturedefs = fixtures.FixtureRequest(item1)._arg2fixturedefs
498        assert len(arg2fixturedefs) == 1
499        assert arg2fixturedefs["something"][0].argname == "something"
500
501    @pytest.mark.skipif(
502        hasattr(sys, "pypy_version_info"),
503        reason="this method of test doesn't work on pypy",
504    )
505    def test_request_garbage(self, testdir):
506        try:
507            import xdist  # noqa
508        except ImportError:
509            pass
510        else:
511            pytest.xfail("this test is flaky when executed with xdist")
512        testdir.makepyfile(
513            """
514            import sys
515            import pytest
516            from _pytest.fixtures import PseudoFixtureDef
517            import gc
518
519            @pytest.fixture(autouse=True)
520            def something(request):
521                original = gc.get_debug()
522                gc.set_debug(gc.DEBUG_SAVEALL)
523                gc.collect()
524
525                yield
526
527                try:
528                    gc.collect()
529                    leaked = [x for _ in gc.garbage if isinstance(_, PseudoFixtureDef)]
530                    assert leaked == []
531                finally:
532                    gc.set_debug(original)
533
534            def test_func():
535                pass
536        """
537        )
538        result = testdir.runpytest_subprocess()
539        result.stdout.fnmatch_lines(["* 1 passed in *"])
540
541    def test_getfixturevalue_recursive(self, testdir):
542        testdir.makeconftest(
543            """
544            import pytest
545
546            @pytest.fixture
547            def something(request):
548                return 1
549        """
550        )
551        testdir.makepyfile(
552            """
553            import pytest
554
555            @pytest.fixture
556            def something(request):
557                return request.getfixturevalue("something") + 1
558            def test_func(something):
559                assert something == 2
560        """
561        )
562        reprec = testdir.inline_run()
563        reprec.assertoutcome(passed=1)
564
565    def test_getfixturevalue_teardown(self, testdir):
566        """
567        Issue #1895
568
569        `test_inner` requests `inner` fixture, which in turn requests `resource`
570        using `getfixturevalue`. `test_func` then requests `resource`.
571
572        `resource` is teardown before `inner` because the fixture mechanism won't consider
573        `inner` dependent on `resource` when it is used via `getfixturevalue`: `test_func`
574        will then cause the `resource`'s finalizer to be called first because of this.
575        """
576        testdir.makepyfile(
577            """
578            import pytest
579
580            @pytest.fixture(scope='session')
581            def resource():
582                r = ['value']
583                yield r
584                r.pop()
585
586            @pytest.fixture(scope='session')
587            def inner(request):
588                resource = request.getfixturevalue('resource')
589                assert resource == ['value']
590                yield
591                assert resource == ['value']
592
593            def test_inner(inner):
594                pass
595
596            def test_func(resource):
597                pass
598        """
599        )
600        result = testdir.runpytest()
601        result.stdout.fnmatch_lines(["* 2 passed in *"])
602
603    @pytest.mark.parametrize("getfixmethod", ("getfixturevalue", "getfuncargvalue"))
604    def test_getfixturevalue(self, testdir, getfixmethod):
605        item = testdir.getitem(
606            """
607            import pytest
608            values = [2]
609            @pytest.fixture
610            def something(request): return 1
611            @pytest.fixture
612            def other(request):
613                return values.pop()
614            def test_func(something): pass
615        """
616        )
617        import contextlib
618
619        if getfixmethod == "getfuncargvalue":
620            warning_expectation = pytest.warns(DeprecationWarning)
621        else:
622            # see #1830 for a cleaner way to accomplish this
623            @contextlib.contextmanager
624            def expecting_no_warning():
625                yield
626
627            warning_expectation = expecting_no_warning()
628
629        req = item._request
630        with warning_expectation:
631            fixture_fetcher = getattr(req, getfixmethod)
632            with pytest.raises(FixtureLookupError):
633                fixture_fetcher("notexists")
634            val = fixture_fetcher("something")
635            assert val == 1
636            val = fixture_fetcher("something")
637            assert val == 1
638            val2 = fixture_fetcher("other")
639            assert val2 == 2
640            val2 = fixture_fetcher("other")  # see about caching
641            assert val2 == 2
642            pytest._fillfuncargs(item)
643            assert item.funcargs["something"] == 1
644            assert len(get_public_names(item.funcargs)) == 2
645            assert "request" in item.funcargs
646
647    def test_request_addfinalizer(self, testdir):
648        item = testdir.getitem(
649            """
650            import pytest
651            teardownlist = []
652            @pytest.fixture
653            def something(request):
654                request.addfinalizer(lambda: teardownlist.append(1))
655            def test_func(something): pass
656        """
657        )
658        item.session._setupstate.prepare(item)
659        pytest._fillfuncargs(item)
660        # successively check finalization calls
661        teardownlist = item.getparent(pytest.Module).obj.teardownlist
662        ss = item.session._setupstate
663        assert not teardownlist
664        ss.teardown_exact(item, None)
665        print(ss.stack)
666        assert teardownlist == [1]
667
668    def test_request_addfinalizer_failing_setup(self, testdir):
669        testdir.makepyfile(
670            """
671            import pytest
672            values = [1]
673            @pytest.fixture
674            def myfix(request):
675                request.addfinalizer(values.pop)
676                assert 0
677            def test_fix(myfix):
678                pass
679            def test_finalizer_ran():
680                assert not values
681        """
682        )
683        reprec = testdir.inline_run("-s")
684        reprec.assertoutcome(failed=1, passed=1)
685
686    def test_request_addfinalizer_failing_setup_module(self, testdir):
687        testdir.makepyfile(
688            """
689            import pytest
690            values = [1, 2]
691            @pytest.fixture(scope="module")
692            def myfix(request):
693                request.addfinalizer(values.pop)
694                request.addfinalizer(values.pop)
695                assert 0
696            def test_fix(myfix):
697                pass
698        """
699        )
700        reprec = testdir.inline_run("-s")
701        mod = reprec.getcalls("pytest_runtest_setup")[0].item.module
702        assert not mod.values
703
704    def test_request_addfinalizer_partial_setup_failure(self, testdir):
705        p = testdir.makepyfile(
706            """
707            import pytest
708            values = []
709            @pytest.fixture
710            def something(request):
711                request.addfinalizer(lambda: values.append(None))
712            def test_func(something, missingarg):
713                pass
714            def test_second():
715                assert len(values) == 1
716        """
717        )
718        result = testdir.runpytest(p)
719        result.stdout.fnmatch_lines(
720            ["*1 error*"]  # XXX the whole module collection fails
721        )
722
723    def test_request_subrequest_addfinalizer_exceptions(self, testdir):
724        """
725        Ensure exceptions raised during teardown by a finalizer are suppressed
726        until all finalizers are called, re-raising the first exception (#2440)
727        """
728        testdir.makepyfile(
729            """
730            import pytest
731            values = []
732            def _excepts(where):
733                raise Exception('Error in %s fixture' % where)
734            @pytest.fixture
735            def subrequest(request):
736                return request
737            @pytest.fixture
738            def something(subrequest):
739                subrequest.addfinalizer(lambda: values.append(1))
740                subrequest.addfinalizer(lambda: values.append(2))
741                subrequest.addfinalizer(lambda: _excepts('something'))
742            @pytest.fixture
743            def excepts(subrequest):
744                subrequest.addfinalizer(lambda: _excepts('excepts'))
745                subrequest.addfinalizer(lambda: values.append(3))
746            def test_first(something, excepts):
747                pass
748            def test_second():
749                assert values == [3, 2, 1]
750        """
751        )
752        result = testdir.runpytest()
753        result.stdout.fnmatch_lines(
754            ["*Exception: Error in excepts fixture", "* 2 passed, 1 error in *"]
755        )
756
757    def test_request_getmodulepath(self, testdir):
758        modcol = testdir.getmodulecol("def test_somefunc(): pass")
759        (item,) = testdir.genitems([modcol])
760        req = fixtures.FixtureRequest(item)
761        assert req.fspath == modcol.fspath
762
763    def test_request_fixturenames(self, testdir):
764        testdir.makepyfile(
765            """
766            import pytest
767            from _pytest.pytester import get_public_names
768            @pytest.fixture()
769            def arg1():
770                pass
771            @pytest.fixture()
772            def farg(arg1):
773                pass
774            @pytest.fixture(autouse=True)
775            def sarg(tmpdir):
776                pass
777            def test_function(request, farg):
778                assert set(get_public_names(request.fixturenames)) == \
779                       set(["tmpdir", "sarg", "arg1", "request", "farg",
780                            "tmp_path", "tmp_path_factory"])
781        """
782        )
783        reprec = testdir.inline_run()
784        reprec.assertoutcome(passed=1)
785
786    def test_request_fixturenames_dynamic_fixture(self, testdir):
787        """Regression test for #3057"""
788        testdir.copy_example("fixtures/test_getfixturevalue_dynamic.py")
789        result = testdir.runpytest()
790        result.stdout.fnmatch_lines(["*1 passed*"])
791
792    def test_funcargnames_compatattr(self, testdir):
793        testdir.makepyfile(
794            """
795            import pytest
796            def pytest_generate_tests(metafunc):
797                assert metafunc.funcargnames == metafunc.fixturenames
798            @pytest.fixture
799            def fn(request):
800                assert request._pyfuncitem.funcargnames == \
801                       request._pyfuncitem.fixturenames
802                return request.funcargnames, request.fixturenames
803
804            def test_hello(fn):
805                assert fn[0] == fn[1]
806        """
807        )
808        reprec = testdir.inline_run()
809        reprec.assertoutcome(passed=1)
810
811    def test_setupdecorator_and_xunit(self, testdir):
812        testdir.makepyfile(
813            """
814            import pytest
815            values = []
816            @pytest.fixture(scope='module', autouse=True)
817            def setup_module():
818                values.append("module")
819            @pytest.fixture(autouse=True)
820            def setup_function():
821                values.append("function")
822
823            def test_func():
824                pass
825
826            class TestClass(object):
827                @pytest.fixture(scope="class", autouse=True)
828                def setup_class(self):
829                    values.append("class")
830                @pytest.fixture(autouse=True)
831                def setup_method(self):
832                    values.append("method")
833                def test_method(self):
834                    pass
835            def test_all():
836                assert values == ["module", "function", "class",
837                             "function", "method", "function"]
838        """
839        )
840        reprec = testdir.inline_run("-v")
841        reprec.assertoutcome(passed=3)
842
843    def test_fixtures_sub_subdir_normalize_sep(self, testdir):
844        # this tests that normalization of nodeids takes place
845        b = testdir.mkdir("tests").mkdir("unit")
846        b.join("conftest.py").write(
847            textwrap.dedent(
848                """\
849                import pytest
850                @pytest.fixture
851                def arg1():
852                    pass
853                """
854            )
855        )
856        p = b.join("test_module.py")
857        p.write("def test_func(arg1): pass")
858        result = testdir.runpytest(p, "--fixtures")
859        assert result.ret == 0
860        result.stdout.fnmatch_lines(
861            """
862            *fixtures defined*conftest*
863            *arg1*
864        """
865        )
866
867    def test_show_fixtures_color_yes(self, testdir):
868        testdir.makepyfile("def test_this(): assert 1")
869        result = testdir.runpytest("--color=yes", "--fixtures")
870        assert "\x1b[32mtmpdir" in result.stdout.str()
871
872    def test_newstyle_with_request(self, testdir):
873        testdir.makepyfile(
874            """
875            import pytest
876            @pytest.fixture()
877            def arg(request):
878                pass
879            def test_1(arg):
880                pass
881        """
882        )
883        reprec = testdir.inline_run()
884        reprec.assertoutcome(passed=1)
885
886    def test_setupcontext_no_param(self, testdir):
887        testdir.makepyfile(
888            """
889            import pytest
890            @pytest.fixture(params=[1,2])
891            def arg(request):
892                return request.param
893
894            @pytest.fixture(autouse=True)
895            def mysetup(request, arg):
896                assert not hasattr(request, "param")
897            def test_1(arg):
898                assert arg in (1,2)
899        """
900        )
901        reprec = testdir.inline_run()
902        reprec.assertoutcome(passed=2)
903
904
905class TestRequestMarking(object):
906    def test_applymarker(self, testdir):
907        item1, item2 = testdir.getitems(
908            """
909            import pytest
910
911            @pytest.fixture
912            def something(request):
913                pass
914            class TestClass(object):
915                def test_func1(self, something):
916                    pass
917                def test_func2(self, something):
918                    pass
919        """
920        )
921        req1 = fixtures.FixtureRequest(item1)
922        assert "xfail" not in item1.keywords
923        req1.applymarker(pytest.mark.xfail)
924        assert "xfail" in item1.keywords
925        assert "skipif" not in item1.keywords
926        req1.applymarker(pytest.mark.skipif)
927        assert "skipif" in item1.keywords
928        with pytest.raises(ValueError):
929            req1.applymarker(42)
930
931    def test_accesskeywords(self, testdir):
932        testdir.makepyfile(
933            """
934            import pytest
935            @pytest.fixture()
936            def keywords(request):
937                return request.keywords
938            @pytest.mark.XYZ
939            def test_function(keywords):
940                assert keywords["XYZ"]
941                assert "abc" not in keywords
942        """
943        )
944        reprec = testdir.inline_run()
945        reprec.assertoutcome(passed=1)
946
947    def test_accessmarker_dynamic(self, testdir):
948        testdir.makeconftest(
949            """
950            import pytest
951            @pytest.fixture()
952            def keywords(request):
953                return request.keywords
954
955            @pytest.fixture(scope="class", autouse=True)
956            def marking(request):
957                request.applymarker(pytest.mark.XYZ("hello"))
958        """
959        )
960        testdir.makepyfile(
961            """
962            import pytest
963            def test_fun1(keywords):
964                assert keywords["XYZ"] is not None
965                assert "abc" not in keywords
966            def test_fun2(keywords):
967                assert keywords["XYZ"] is not None
968                assert "abc" not in keywords
969        """
970        )
971        reprec = testdir.inline_run()
972        reprec.assertoutcome(passed=2)
973
974
975class TestFixtureUsages(object):
976    def test_noargfixturedec(self, testdir):
977        testdir.makepyfile(
978            """
979            import pytest
980            @pytest.fixture
981            def arg1():
982                return 1
983
984            def test_func(arg1):
985                assert arg1 == 1
986        """
987        )
988        reprec = testdir.inline_run()
989        reprec.assertoutcome(passed=1)
990
991    def test_receives_funcargs(self, testdir):
992        testdir.makepyfile(
993            """
994            import pytest
995            @pytest.fixture()
996            def arg1():
997                return 1
998
999            @pytest.fixture()
1000            def arg2(arg1):
1001                return arg1 + 1
1002
1003            def test_add(arg2):
1004                assert arg2 == 2
1005            def test_all(arg1, arg2):
1006                assert arg1 == 1
1007                assert arg2 == 2
1008        """
1009        )
1010        reprec = testdir.inline_run()
1011        reprec.assertoutcome(passed=2)
1012
1013    def test_receives_funcargs_scope_mismatch(self, testdir):
1014        testdir.makepyfile(
1015            """
1016            import pytest
1017            @pytest.fixture(scope="function")
1018            def arg1():
1019                return 1
1020
1021            @pytest.fixture(scope="module")
1022            def arg2(arg1):
1023                return arg1 + 1
1024
1025            def test_add(arg2):
1026                assert arg2 == 2
1027        """
1028        )
1029        result = testdir.runpytest()
1030        result.stdout.fnmatch_lines(
1031            [
1032                "*ScopeMismatch*involved factories*",
1033                "test_receives_funcargs_scope_mismatch.py:6:  def arg2(arg1)",
1034                "test_receives_funcargs_scope_mismatch.py:2:  def arg1()",
1035                "*1 error*",
1036            ]
1037        )
1038
1039    def test_receives_funcargs_scope_mismatch_issue660(self, testdir):
1040        testdir.makepyfile(
1041            """
1042            import pytest
1043            @pytest.fixture(scope="function")
1044            def arg1():
1045                return 1
1046
1047            @pytest.fixture(scope="module")
1048            def arg2(arg1):
1049                return arg1 + 1
1050
1051            def test_add(arg1, arg2):
1052                assert arg2 == 2
1053        """
1054        )
1055        result = testdir.runpytest()
1056        result.stdout.fnmatch_lines(
1057            ["*ScopeMismatch*involved factories*", "* def arg2*", "*1 error*"]
1058        )
1059
1060    def test_invalid_scope(self, testdir):
1061        testdir.makepyfile(
1062            """
1063            import pytest
1064            @pytest.fixture(scope="functions")
1065            def badscope():
1066                pass
1067
1068            def test_nothing(badscope):
1069                pass
1070        """
1071        )
1072        result = testdir.runpytest_inprocess()
1073        result.stdout.fnmatch_lines(
1074            "*Fixture 'badscope' from test_invalid_scope.py got an unexpected scope value 'functions'"
1075        )
1076
1077    def test_funcarg_parametrized_and_used_twice(self, testdir):
1078        testdir.makepyfile(
1079            """
1080            import pytest
1081            values = []
1082            @pytest.fixture(params=[1,2])
1083            def arg1(request):
1084                values.append(1)
1085                return request.param
1086
1087            @pytest.fixture()
1088            def arg2(arg1):
1089                return arg1 + 1
1090
1091            def test_add(arg1, arg2):
1092                assert arg2 == arg1 + 1
1093                assert len(values) == arg1
1094        """
1095        )
1096        result = testdir.runpytest()
1097        result.stdout.fnmatch_lines(["*2 passed*"])
1098
1099    def test_factory_uses_unknown_funcarg_as_dependency_error(self, testdir):
1100        testdir.makepyfile(
1101            """
1102            import pytest
1103
1104            @pytest.fixture()
1105            def fail(missing):
1106                return
1107
1108            @pytest.fixture()
1109            def call_fail(fail):
1110                return
1111
1112            def test_missing(call_fail):
1113                pass
1114            """
1115        )
1116        result = testdir.runpytest()
1117        result.stdout.fnmatch_lines(
1118            """
1119            *pytest.fixture()*
1120            *def call_fail(fail)*
1121            *pytest.fixture()*
1122            *def fail*
1123            *fixture*'missing'*not found*
1124        """
1125        )
1126
1127    def test_factory_setup_as_classes_fails(self, testdir):
1128        testdir.makepyfile(
1129            """
1130            import pytest
1131            class arg1(object):
1132                def __init__(self, request):
1133                    self.x = 1
1134            arg1 = pytest.fixture()(arg1)
1135
1136        """
1137        )
1138        reprec = testdir.inline_run()
1139        values = reprec.getfailedcollections()
1140        assert len(values) == 1
1141
1142    @pytest.mark.filterwarnings("ignore::pytest.PytestDeprecationWarning")
1143    def test_request_can_be_overridden(self, testdir):
1144        testdir.makepyfile(
1145            """
1146            import pytest
1147            @pytest.fixture()
1148            def request(request):
1149                request.a = 1
1150                return request
1151            def test_request(request):
1152                assert request.a == 1
1153        """
1154        )
1155        reprec = testdir.inline_run()
1156        reprec.assertoutcome(passed=1)
1157
1158    def test_usefixtures_marker(self, testdir):
1159        testdir.makepyfile(
1160            """
1161            import pytest
1162
1163            values = []
1164
1165            @pytest.fixture(scope="class")
1166            def myfix(request):
1167                request.cls.hello = "world"
1168                values.append(1)
1169
1170            class TestClass(object):
1171                def test_one(self):
1172                    assert self.hello == "world"
1173                    assert len(values) == 1
1174                def test_two(self):
1175                    assert self.hello == "world"
1176                    assert len(values) == 1
1177            pytest.mark.usefixtures("myfix")(TestClass)
1178        """
1179        )
1180        reprec = testdir.inline_run()
1181        reprec.assertoutcome(passed=2)
1182
1183    def test_usefixtures_ini(self, testdir):
1184        testdir.makeini(
1185            """
1186            [pytest]
1187            usefixtures = myfix
1188        """
1189        )
1190        testdir.makeconftest(
1191            """
1192            import pytest
1193
1194            @pytest.fixture(scope="class")
1195            def myfix(request):
1196                request.cls.hello = "world"
1197
1198        """
1199        )
1200        testdir.makepyfile(
1201            """
1202            class TestClass(object):
1203                def test_one(self):
1204                    assert self.hello == "world"
1205                def test_two(self):
1206                    assert self.hello == "world"
1207        """
1208        )
1209        reprec = testdir.inline_run()
1210        reprec.assertoutcome(passed=2)
1211
1212    def test_usefixtures_seen_in_showmarkers(self, testdir):
1213        result = testdir.runpytest("--markers")
1214        result.stdout.fnmatch_lines(
1215            """
1216            *usefixtures(fixturename1*mark tests*fixtures*
1217        """
1218        )
1219
1220    def test_request_instance_issue203(self, testdir):
1221        testdir.makepyfile(
1222            """
1223            import pytest
1224
1225            class TestClass(object):
1226                @pytest.fixture
1227                def setup1(self, request):
1228                    assert self == request.instance
1229                    self.arg1 = 1
1230                def test_hello(self, setup1):
1231                    assert self.arg1 == 1
1232        """
1233        )
1234        reprec = testdir.inline_run()
1235        reprec.assertoutcome(passed=1)
1236
1237    def test_fixture_parametrized_with_iterator(self, testdir):
1238        testdir.makepyfile(
1239            """
1240            import pytest
1241
1242            values = []
1243            def f():
1244                yield 1
1245                yield 2
1246            dec = pytest.fixture(scope="module", params=f())
1247
1248            @dec
1249            def arg(request):
1250                return request.param
1251            @dec
1252            def arg2(request):
1253                return request.param
1254
1255            def test_1(arg):
1256                values.append(arg)
1257            def test_2(arg2):
1258                values.append(arg2*10)
1259        """
1260        )
1261        reprec = testdir.inline_run("-v")
1262        reprec.assertoutcome(passed=4)
1263        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
1264        assert values == [1, 2, 10, 20]
1265
1266    def test_setup_functions_as_fixtures(self, testdir):
1267        """Ensure setup_* methods obey fixture scope rules (#517, #3094)."""
1268        testdir.makepyfile(
1269            """
1270            import pytest
1271
1272            DB_INITIALIZED = None
1273
1274            @pytest.yield_fixture(scope="session", autouse=True)
1275            def db():
1276                global DB_INITIALIZED
1277                DB_INITIALIZED = True
1278                yield
1279                DB_INITIALIZED = False
1280
1281            def setup_module():
1282                assert DB_INITIALIZED
1283
1284            def teardown_module():
1285                assert DB_INITIALIZED
1286
1287            class TestClass(object):
1288
1289                def setup_method(self, method):
1290                    assert DB_INITIALIZED
1291
1292                def teardown_method(self, method):
1293                    assert DB_INITIALIZED
1294
1295                def test_printer_1(self):
1296                    pass
1297
1298                def test_printer_2(self):
1299                    pass
1300        """
1301        )
1302        result = testdir.runpytest()
1303        result.stdout.fnmatch_lines(["* 2 passed in *"])
1304
1305
1306class TestFixtureManagerParseFactories(object):
1307    @pytest.fixture
1308    def testdir(self, request):
1309        testdir = request.getfixturevalue("testdir")
1310        testdir.makeconftest(
1311            """
1312            import pytest
1313
1314            @pytest.fixture
1315            def hello(request):
1316                return "conftest"
1317
1318            @pytest.fixture
1319            def fm(request):
1320                return request._fixturemanager
1321
1322            @pytest.fixture
1323            def item(request):
1324                return request._pyfuncitem
1325        """
1326        )
1327        return testdir
1328
1329    def test_parsefactories_evil_objects_issue214(self, testdir):
1330        testdir.makepyfile(
1331            """
1332            class A(object):
1333                def __call__(self):
1334                    pass
1335                def __getattr__(self, name):
1336                    raise RuntimeError()
1337            a = A()
1338            def test_hello():
1339                pass
1340        """
1341        )
1342        reprec = testdir.inline_run()
1343        reprec.assertoutcome(passed=1, failed=0)
1344
1345    def test_parsefactories_conftest(self, testdir):
1346        testdir.makepyfile(
1347            """
1348            def test_hello(item, fm):
1349                for name in ("fm", "hello", "item"):
1350                    faclist = fm.getfixturedefs(name, item.nodeid)
1351                    assert len(faclist) == 1
1352                    fac = faclist[0]
1353                    assert fac.func.__name__ == name
1354        """
1355        )
1356        reprec = testdir.inline_run("-s")
1357        reprec.assertoutcome(passed=1)
1358
1359    def test_parsefactories_conftest_and_module_and_class(self, testdir):
1360        testdir.makepyfile(
1361            """
1362            import pytest
1363            import six
1364
1365            @pytest.fixture
1366            def hello(request):
1367                return "module"
1368            class TestClass(object):
1369                @pytest.fixture
1370                def hello(self, request):
1371                    return "class"
1372                def test_hello(self, item, fm):
1373                    faclist = fm.getfixturedefs("hello", item.nodeid)
1374                    print(faclist)
1375                    assert len(faclist) == 3
1376
1377                    assert faclist[0].func(item._request) == "conftest"
1378                    assert faclist[1].func(item._request) == "module"
1379                    assert faclist[2].func(item._request) == "class"
1380        """
1381        )
1382        reprec = testdir.inline_run("-s")
1383        reprec.assertoutcome(passed=1)
1384
1385    def test_parsefactories_relative_node_ids(self, testdir):
1386        # example mostly taken from:
1387        # https://mail.python.org/pipermail/pytest-dev/2014-September/002617.html
1388        runner = testdir.mkdir("runner")
1389        package = testdir.mkdir("package")
1390        package.join("conftest.py").write(
1391            textwrap.dedent(
1392                """\
1393            import pytest
1394            @pytest.fixture
1395            def one():
1396                return 1
1397            """
1398            )
1399        )
1400        package.join("test_x.py").write(
1401            textwrap.dedent(
1402                """\
1403                def test_x(one):
1404                    assert one == 1
1405                """
1406            )
1407        )
1408        sub = package.mkdir("sub")
1409        sub.join("__init__.py").ensure()
1410        sub.join("conftest.py").write(
1411            textwrap.dedent(
1412                """\
1413                import pytest
1414                @pytest.fixture
1415                def one():
1416                    return 2
1417                """
1418            )
1419        )
1420        sub.join("test_y.py").write(
1421            textwrap.dedent(
1422                """\
1423                def test_x(one):
1424                    assert one == 2
1425                """
1426            )
1427        )
1428        reprec = testdir.inline_run()
1429        reprec.assertoutcome(passed=2)
1430        with runner.as_cwd():
1431            reprec = testdir.inline_run("..")
1432            reprec.assertoutcome(passed=2)
1433
1434    def test_package_xunit_fixture(self, testdir):
1435        testdir.makepyfile(
1436            __init__="""\
1437            values = []
1438        """
1439        )
1440        package = testdir.mkdir("package")
1441        package.join("__init__.py").write(
1442            textwrap.dedent(
1443                """\
1444                from .. import values
1445                def setup_module():
1446                    values.append("package")
1447                def teardown_module():
1448                    values[:] = []
1449                """
1450            )
1451        )
1452        package.join("test_x.py").write(
1453            textwrap.dedent(
1454                """\
1455                from .. import values
1456                def test_x():
1457                    assert values == ["package"]
1458                """
1459            )
1460        )
1461        package = testdir.mkdir("package2")
1462        package.join("__init__.py").write(
1463            textwrap.dedent(
1464                """\
1465                from .. import values
1466                def setup_module():
1467                    values.append("package2")
1468                def teardown_module():
1469                    values[:] = []
1470                """
1471            )
1472        )
1473        package.join("test_x.py").write(
1474            textwrap.dedent(
1475                """\
1476                from .. import values
1477                def test_x():
1478                    assert values == ["package2"]
1479                """
1480            )
1481        )
1482        reprec = testdir.inline_run()
1483        reprec.assertoutcome(passed=2)
1484
1485    def test_package_fixture_complex(self, testdir):
1486        testdir.makepyfile(
1487            __init__="""\
1488            values = []
1489        """
1490        )
1491        testdir.syspathinsert(testdir.tmpdir.dirname)
1492        package = testdir.mkdir("package")
1493        package.join("__init__.py").write("")
1494        package.join("conftest.py").write(
1495            textwrap.dedent(
1496                """\
1497                import pytest
1498                from .. import values
1499                @pytest.fixture(scope="package")
1500                def one():
1501                    values.append("package")
1502                    yield values
1503                    values.pop()
1504                @pytest.fixture(scope="package", autouse=True)
1505                def two():
1506                    values.append("package-auto")
1507                    yield values
1508                    values.pop()
1509                """
1510            )
1511        )
1512        package.join("test_x.py").write(
1513            textwrap.dedent(
1514                """\
1515                from .. import values
1516                def test_package_autouse():
1517                    assert values == ["package-auto"]
1518                def test_package(one):
1519                    assert values == ["package-auto", "package"]
1520                """
1521            )
1522        )
1523        reprec = testdir.inline_run()
1524        reprec.assertoutcome(passed=2)
1525
1526    def test_collect_custom_items(self, testdir):
1527        testdir.copy_example("fixtures/custom_item")
1528        result = testdir.runpytest("foo")
1529        result.stdout.fnmatch_lines(["*passed*"])
1530
1531
1532class TestAutouseDiscovery(object):
1533    @pytest.fixture
1534    def testdir(self, testdir):
1535        testdir.makeconftest(
1536            """
1537            import pytest
1538            @pytest.fixture(autouse=True)
1539            def perfunction(request, tmpdir):
1540                pass
1541
1542            @pytest.fixture()
1543            def arg1(tmpdir):
1544                pass
1545            @pytest.fixture(autouse=True)
1546            def perfunction2(arg1):
1547                pass
1548
1549            @pytest.fixture
1550            def fm(request):
1551                return request._fixturemanager
1552
1553            @pytest.fixture
1554            def item(request):
1555                return request._pyfuncitem
1556        """
1557        )
1558        return testdir
1559
1560    def test_parsefactories_conftest(self, testdir):
1561        testdir.makepyfile(
1562            """
1563            from _pytest.pytester import get_public_names
1564            def test_check_setup(item, fm):
1565                autousenames = fm._getautousenames(item.nodeid)
1566                assert len(get_public_names(autousenames)) == 2
1567                assert "perfunction2" in autousenames
1568                assert "perfunction" in autousenames
1569        """
1570        )
1571        reprec = testdir.inline_run("-s")
1572        reprec.assertoutcome(passed=1)
1573
1574    def test_two_classes_separated_autouse(self, testdir):
1575        testdir.makepyfile(
1576            """
1577            import pytest
1578            class TestA(object):
1579                values = []
1580                @pytest.fixture(autouse=True)
1581                def setup1(self):
1582                    self.values.append(1)
1583                def test_setup1(self):
1584                    assert self.values == [1]
1585            class TestB(object):
1586                values = []
1587                @pytest.fixture(autouse=True)
1588                def setup2(self):
1589                    self.values.append(1)
1590                def test_setup2(self):
1591                    assert self.values == [1]
1592        """
1593        )
1594        reprec = testdir.inline_run()
1595        reprec.assertoutcome(passed=2)
1596
1597    def test_setup_at_classlevel(self, testdir):
1598        testdir.makepyfile(
1599            """
1600            import pytest
1601            class TestClass(object):
1602                @pytest.fixture(autouse=True)
1603                def permethod(self, request):
1604                    request.instance.funcname = request.function.__name__
1605                def test_method1(self):
1606                    assert self.funcname == "test_method1"
1607                def test_method2(self):
1608                    assert self.funcname == "test_method2"
1609        """
1610        )
1611        reprec = testdir.inline_run("-s")
1612        reprec.assertoutcome(passed=2)
1613
1614    @pytest.mark.xfail(reason="'enabled' feature not implemented")
1615    def test_setup_enabled_functionnode(self, testdir):
1616        testdir.makepyfile(
1617            """
1618            import pytest
1619
1620            def enabled(parentnode, markers):
1621                return "needsdb" in markers
1622
1623            @pytest.fixture(params=[1,2])
1624            def db(request):
1625                return request.param
1626
1627            @pytest.fixture(enabled=enabled, autouse=True)
1628            def createdb(db):
1629                pass
1630
1631            def test_func1(request):
1632                assert "db" not in request.fixturenames
1633
1634            @pytest.mark.needsdb
1635            def test_func2(request):
1636                assert "db" in request.fixturenames
1637        """
1638        )
1639        reprec = testdir.inline_run("-s")
1640        reprec.assertoutcome(passed=2)
1641
1642    def test_callables_nocode(self, testdir):
1643        """
1644        an imported mock.call would break setup/factory discovery
1645        due to it being callable and __code__ not being a code object
1646        """
1647        testdir.makepyfile(
1648            """
1649           class _call(tuple):
1650               def __call__(self, *k, **kw):
1651                   pass
1652               def __getattr__(self, k):
1653                   return self
1654
1655           call = _call()
1656        """
1657        )
1658        reprec = testdir.inline_run("-s")
1659        reprec.assertoutcome(failed=0, passed=0)
1660
1661    def test_autouse_in_conftests(self, testdir):
1662        a = testdir.mkdir("a")
1663        b = testdir.mkdir("a1")
1664        conftest = testdir.makeconftest(
1665            """
1666            import pytest
1667            @pytest.fixture(autouse=True)
1668            def hello():
1669                xxx
1670        """
1671        )
1672        conftest.move(a.join(conftest.basename))
1673        a.join("test_something.py").write("def test_func(): pass")
1674        b.join("test_otherthing.py").write("def test_func(): pass")
1675        result = testdir.runpytest()
1676        result.stdout.fnmatch_lines(
1677            """
1678            *1 passed*1 error*
1679        """
1680        )
1681
1682    def test_autouse_in_module_and_two_classes(self, testdir):
1683        testdir.makepyfile(
1684            """
1685            import pytest
1686            values = []
1687            @pytest.fixture(autouse=True)
1688            def append1():
1689                values.append("module")
1690            def test_x():
1691                assert values == ["module"]
1692
1693            class TestA(object):
1694                @pytest.fixture(autouse=True)
1695                def append2(self):
1696                    values.append("A")
1697                def test_hello(self):
1698                    assert values == ["module", "module", "A"], values
1699            class TestA2(object):
1700                def test_world(self):
1701                    assert values == ["module", "module", "A", "module"], values
1702        """
1703        )
1704        reprec = testdir.inline_run()
1705        reprec.assertoutcome(passed=3)
1706
1707
1708class TestAutouseManagement(object):
1709    def test_autouse_conftest_mid_directory(self, testdir):
1710        pkgdir = testdir.mkpydir("xyz123")
1711        pkgdir.join("conftest.py").write(
1712            textwrap.dedent(
1713                """\
1714                import pytest
1715                @pytest.fixture(autouse=True)
1716                def app():
1717                    import sys
1718                    sys._myapp = "hello"
1719                """
1720            )
1721        )
1722        t = pkgdir.ensure("tests", "test_app.py")
1723        t.write(
1724            textwrap.dedent(
1725                """\
1726                import sys
1727                def test_app():
1728                    assert sys._myapp == "hello"
1729                """
1730            )
1731        )
1732        reprec = testdir.inline_run("-s")
1733        reprec.assertoutcome(passed=1)
1734
1735    def test_funcarg_and_setup(self, testdir):
1736        testdir.makepyfile(
1737            """
1738            import pytest
1739            values = []
1740            @pytest.fixture(scope="module")
1741            def arg():
1742                values.append(1)
1743                return 0
1744            @pytest.fixture(scope="module", autouse=True)
1745            def something(arg):
1746                values.append(2)
1747
1748            def test_hello(arg):
1749                assert len(values) == 2
1750                assert values == [1,2]
1751                assert arg == 0
1752
1753            def test_hello2(arg):
1754                assert len(values) == 2
1755                assert values == [1,2]
1756                assert arg == 0
1757        """
1758        )
1759        reprec = testdir.inline_run()
1760        reprec.assertoutcome(passed=2)
1761
1762    def test_uses_parametrized_resource(self, testdir):
1763        testdir.makepyfile(
1764            """
1765            import pytest
1766            values = []
1767            @pytest.fixture(params=[1,2])
1768            def arg(request):
1769                return request.param
1770
1771            @pytest.fixture(autouse=True)
1772            def something(arg):
1773                values.append(arg)
1774
1775            def test_hello():
1776                if len(values) == 1:
1777                    assert values == [1]
1778                elif len(values) == 2:
1779                    assert values == [1, 2]
1780                else:
1781                    0/0
1782
1783        """
1784        )
1785        reprec = testdir.inline_run("-s")
1786        reprec.assertoutcome(passed=2)
1787
1788    def test_session_parametrized_function(self, testdir):
1789        testdir.makepyfile(
1790            """
1791            import pytest
1792
1793            values = []
1794
1795            @pytest.fixture(scope="session", params=[1,2])
1796            def arg(request):
1797               return request.param
1798
1799            @pytest.fixture(scope="function", autouse=True)
1800            def append(request, arg):
1801                if request.function.__name__ == "test_some":
1802                    values.append(arg)
1803
1804            def test_some():
1805                pass
1806
1807            def test_result(arg):
1808                assert len(values) == arg
1809                assert values[:arg] == [1,2][:arg]
1810        """
1811        )
1812        reprec = testdir.inline_run("-v", "-s")
1813        reprec.assertoutcome(passed=4)
1814
1815    def test_class_function_parametrization_finalization(self, testdir):
1816        p = testdir.makeconftest(
1817            """
1818            import pytest
1819            import pprint
1820
1821            values = []
1822
1823            @pytest.fixture(scope="function", params=[1,2])
1824            def farg(request):
1825                return request.param
1826
1827            @pytest.fixture(scope="class", params=list("ab"))
1828            def carg(request):
1829                return request.param
1830
1831            @pytest.fixture(scope="function", autouse=True)
1832            def append(request, farg, carg):
1833                def fin():
1834                    values.append("fin_%s%s" % (carg, farg))
1835                request.addfinalizer(fin)
1836        """
1837        )
1838        testdir.makepyfile(
1839            """
1840            import pytest
1841
1842            class TestClass(object):
1843                def test_1(self):
1844                    pass
1845            class TestClass2(object):
1846                def test_2(self):
1847                    pass
1848        """
1849        )
1850        confcut = "--confcutdir={}".format(testdir.tmpdir)
1851        reprec = testdir.inline_run("-v", "-s", confcut)
1852        reprec.assertoutcome(passed=8)
1853        config = reprec.getcalls("pytest_unconfigure")[0].config
1854        values = config.pluginmanager._getconftestmodules(p)[0].values
1855        assert values == ["fin_a1", "fin_a2", "fin_b1", "fin_b2"] * 2
1856
1857    def test_scope_ordering(self, testdir):
1858        testdir.makepyfile(
1859            """
1860            import pytest
1861            values = []
1862            @pytest.fixture(scope="function", autouse=True)
1863            def fappend2():
1864                values.append(2)
1865            @pytest.fixture(scope="class", autouse=True)
1866            def classappend3():
1867                values.append(3)
1868            @pytest.fixture(scope="module", autouse=True)
1869            def mappend():
1870                values.append(1)
1871
1872            class TestHallo(object):
1873                def test_method(self):
1874                    assert values == [1,3,2]
1875        """
1876        )
1877        reprec = testdir.inline_run()
1878        reprec.assertoutcome(passed=1)
1879
1880    def test_parametrization_setup_teardown_ordering(self, testdir):
1881        testdir.makepyfile(
1882            """
1883            import pytest
1884            values = []
1885            def pytest_generate_tests(metafunc):
1886                if metafunc.cls is None:
1887                    assert metafunc.function is test_finish
1888                if metafunc.cls is not None:
1889                    metafunc.parametrize("item", [1,2], scope="class")
1890            class TestClass(object):
1891                @pytest.fixture(scope="class", autouse=True)
1892                def addteardown(self, item, request):
1893                    values.append("setup-%d" % item)
1894                    request.addfinalizer(lambda: values.append("teardown-%d" % item))
1895                def test_step1(self, item):
1896                    values.append("step1-%d" % item)
1897                def test_step2(self, item):
1898                    values.append("step2-%d" % item)
1899
1900            def test_finish():
1901                print(values)
1902                assert values == ["setup-1", "step1-1", "step2-1", "teardown-1",
1903                             "setup-2", "step1-2", "step2-2", "teardown-2",]
1904        """
1905        )
1906        reprec = testdir.inline_run("-s")
1907        reprec.assertoutcome(passed=5)
1908
1909    def test_ordering_autouse_before_explicit(self, testdir):
1910        testdir.makepyfile(
1911            """
1912            import pytest
1913
1914            values = []
1915            @pytest.fixture(autouse=True)
1916            def fix1():
1917                values.append(1)
1918            @pytest.fixture()
1919            def arg1():
1920                values.append(2)
1921            def test_hello(arg1):
1922                assert values == [1,2]
1923        """
1924        )
1925        reprec = testdir.inline_run()
1926        reprec.assertoutcome(passed=1)
1927
1928    @pytest.mark.parametrize("param1", ["", "params=[1]"], ids=["p00", "p01"])
1929    @pytest.mark.parametrize("param2", ["", "params=[1]"], ids=["p10", "p11"])
1930    def test_ordering_dependencies_torndown_first(self, testdir, param1, param2):
1931        """#226"""
1932        testdir.makepyfile(
1933            """
1934            import pytest
1935            values = []
1936            @pytest.fixture(%(param1)s)
1937            def arg1(request):
1938                request.addfinalizer(lambda: values.append("fin1"))
1939                values.append("new1")
1940            @pytest.fixture(%(param2)s)
1941            def arg2(request, arg1):
1942                request.addfinalizer(lambda: values.append("fin2"))
1943                values.append("new2")
1944
1945            def test_arg(arg2):
1946                pass
1947            def test_check():
1948                assert values == ["new1", "new2", "fin2", "fin1"]
1949        """
1950            % locals()
1951        )
1952        reprec = testdir.inline_run("-s")
1953        reprec.assertoutcome(passed=2)
1954
1955
1956class TestFixtureMarker(object):
1957    def test_parametrize(self, testdir):
1958        testdir.makepyfile(
1959            """
1960            import pytest
1961            @pytest.fixture(params=["a", "b", "c"])
1962            def arg(request):
1963                return request.param
1964            values = []
1965            def test_param(arg):
1966                values.append(arg)
1967            def test_result():
1968                assert values == list("abc")
1969        """
1970        )
1971        reprec = testdir.inline_run()
1972        reprec.assertoutcome(passed=4)
1973
1974    def test_multiple_parametrization_issue_736(self, testdir):
1975        testdir.makepyfile(
1976            """
1977            import pytest
1978
1979            @pytest.fixture(params=[1,2,3])
1980            def foo(request):
1981                return request.param
1982
1983            @pytest.mark.parametrize('foobar', [4,5,6])
1984            def test_issue(foo, foobar):
1985                assert foo in [1,2,3]
1986                assert foobar in [4,5,6]
1987        """
1988        )
1989        reprec = testdir.inline_run()
1990        reprec.assertoutcome(passed=9)
1991
1992    @pytest.mark.parametrize(
1993        "param_args",
1994        ["'fixt, val'", "'fixt,val'", "['fixt', 'val']", "('fixt', 'val')"],
1995    )
1996    def test_override_parametrized_fixture_issue_979(self, testdir, param_args):
1997        """Make sure a parametrized argument can override a parametrized fixture.
1998
1999        This was a regression introduced in the fix for #736.
2000        """
2001        testdir.makepyfile(
2002            """
2003            import pytest
2004
2005            @pytest.fixture(params=[1, 2])
2006            def fixt(request):
2007                return request.param
2008
2009            @pytest.mark.parametrize(%s, [(3, 'x'), (4, 'x')])
2010            def test_foo(fixt, val):
2011                pass
2012        """
2013            % param_args
2014        )
2015        reprec = testdir.inline_run()
2016        reprec.assertoutcome(passed=2)
2017
2018    def test_scope_session(self, testdir):
2019        testdir.makepyfile(
2020            """
2021            import pytest
2022            values = []
2023            @pytest.fixture(scope="module")
2024            def arg():
2025                values.append(1)
2026                return 1
2027
2028            def test_1(arg):
2029                assert arg == 1
2030            def test_2(arg):
2031                assert arg == 1
2032                assert len(values) == 1
2033            class TestClass(object):
2034                def test3(self, arg):
2035                    assert arg == 1
2036                    assert len(values) == 1
2037        """
2038        )
2039        reprec = testdir.inline_run()
2040        reprec.assertoutcome(passed=3)
2041
2042    def test_scope_session_exc(self, testdir):
2043        testdir.makepyfile(
2044            """
2045            import pytest
2046            values = []
2047            @pytest.fixture(scope="session")
2048            def fix():
2049                values.append(1)
2050                pytest.skip('skipping')
2051
2052            def test_1(fix):
2053                pass
2054            def test_2(fix):
2055                pass
2056            def test_last():
2057                assert values == [1]
2058        """
2059        )
2060        reprec = testdir.inline_run()
2061        reprec.assertoutcome(skipped=2, passed=1)
2062
2063    def test_scope_session_exc_two_fix(self, testdir):
2064        testdir.makepyfile(
2065            """
2066            import pytest
2067            values = []
2068            m = []
2069            @pytest.fixture(scope="session")
2070            def a():
2071                values.append(1)
2072                pytest.skip('skipping')
2073            @pytest.fixture(scope="session")
2074            def b(a):
2075                m.append(1)
2076
2077            def test_1(b):
2078                pass
2079            def test_2(b):
2080                pass
2081            def test_last():
2082                assert values == [1]
2083                assert m == []
2084        """
2085        )
2086        reprec = testdir.inline_run()
2087        reprec.assertoutcome(skipped=2, passed=1)
2088
2089    def test_scope_exc(self, testdir):
2090        testdir.makepyfile(
2091            test_foo="""
2092                def test_foo(fix):
2093                    pass
2094            """,
2095            test_bar="""
2096                def test_bar(fix):
2097                    pass
2098            """,
2099            conftest="""
2100                import pytest
2101                reqs = []
2102                @pytest.fixture(scope="session")
2103                def fix(request):
2104                    reqs.append(1)
2105                    pytest.skip()
2106                @pytest.fixture
2107                def req_list():
2108                    return reqs
2109            """,
2110            test_real="""
2111                def test_last(req_list):
2112                    assert req_list == [1]
2113            """,
2114        )
2115        reprec = testdir.inline_run()
2116        reprec.assertoutcome(skipped=2, passed=1)
2117
2118    def test_scope_module_uses_session(self, testdir):
2119        testdir.makepyfile(
2120            """
2121            import pytest
2122            values = []
2123            @pytest.fixture(scope="module")
2124            def arg():
2125                values.append(1)
2126                return 1
2127
2128            def test_1(arg):
2129                assert arg == 1
2130            def test_2(arg):
2131                assert arg == 1
2132                assert len(values) == 1
2133            class TestClass(object):
2134                def test3(self, arg):
2135                    assert arg == 1
2136                    assert len(values) == 1
2137        """
2138        )
2139        reprec = testdir.inline_run()
2140        reprec.assertoutcome(passed=3)
2141
2142    def test_scope_module_and_finalizer(self, testdir):
2143        testdir.makeconftest(
2144            """
2145            import pytest
2146            finalized_list = []
2147            created_list = []
2148            @pytest.fixture(scope="module")
2149            def arg(request):
2150                created_list.append(1)
2151                assert request.scope == "module"
2152                request.addfinalizer(lambda: finalized_list.append(1))
2153            @pytest.fixture
2154            def created(request):
2155                return len(created_list)
2156            @pytest.fixture
2157            def finalized(request):
2158                return len(finalized_list)
2159        """
2160        )
2161        testdir.makepyfile(
2162            test_mod1="""
2163                def test_1(arg, created, finalized):
2164                    assert created == 1
2165                    assert finalized == 0
2166                def test_2(arg, created, finalized):
2167                    assert created == 1
2168                    assert finalized == 0""",
2169            test_mod2="""
2170                def test_3(arg, created, finalized):
2171                    assert created == 2
2172                    assert finalized == 1""",
2173            test_mode3="""
2174                def test_4(arg, created, finalized):
2175                    assert created == 3
2176                    assert finalized == 2
2177            """,
2178        )
2179        reprec = testdir.inline_run()
2180        reprec.assertoutcome(passed=4)
2181
2182    def test_scope_mismatch_various(self, testdir):
2183        testdir.makeconftest(
2184            """
2185            import pytest
2186            finalized = []
2187            created = []
2188            @pytest.fixture(scope="function")
2189            def arg(request):
2190                pass
2191        """
2192        )
2193        testdir.makepyfile(
2194            test_mod1="""
2195                import pytest
2196                @pytest.fixture(scope="session")
2197                def arg(request):
2198                    request.getfixturevalue("arg")
2199                def test_1(arg):
2200                    pass
2201            """
2202        )
2203        result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
2204        assert result.ret != 0
2205        result.stdout.fnmatch_lines(
2206            ["*ScopeMismatch*You tried*function*session*request*"]
2207        )
2208
2209    def test_register_only_with_mark(self, testdir):
2210        testdir.makeconftest(
2211            """
2212            import pytest
2213            @pytest.fixture()
2214            def arg():
2215                return 1
2216        """
2217        )
2218        testdir.makepyfile(
2219            test_mod1="""
2220                import pytest
2221                @pytest.fixture()
2222                def arg(arg):
2223                    return arg + 1
2224                def test_1(arg):
2225                    assert arg == 2
2226            """
2227        )
2228        reprec = testdir.inline_run()
2229        reprec.assertoutcome(passed=1)
2230
2231    def test_parametrize_and_scope(self, testdir):
2232        testdir.makepyfile(
2233            """
2234            import pytest
2235            @pytest.fixture(scope="module", params=["a", "b", "c"])
2236            def arg(request):
2237                return request.param
2238            values = []
2239            def test_param(arg):
2240                values.append(arg)
2241        """
2242        )
2243        reprec = testdir.inline_run("-v")
2244        reprec.assertoutcome(passed=3)
2245        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
2246        assert len(values) == 3
2247        assert "a" in values
2248        assert "b" in values
2249        assert "c" in values
2250
2251    def test_scope_mismatch(self, testdir):
2252        testdir.makeconftest(
2253            """
2254            import pytest
2255            @pytest.fixture(scope="function")
2256            def arg(request):
2257                pass
2258        """
2259        )
2260        testdir.makepyfile(
2261            """
2262            import pytest
2263            @pytest.fixture(scope="session")
2264            def arg(arg):
2265                pass
2266            def test_mismatch(arg):
2267                pass
2268        """
2269        )
2270        result = testdir.runpytest()
2271        result.stdout.fnmatch_lines(["*ScopeMismatch*", "*1 error*"])
2272
2273    def test_parametrize_separated_order(self, testdir):
2274        testdir.makepyfile(
2275            """
2276            import pytest
2277
2278            @pytest.fixture(scope="module", params=[1, 2])
2279            def arg(request):
2280                return request.param
2281
2282            values = []
2283            def test_1(arg):
2284                values.append(arg)
2285            def test_2(arg):
2286                values.append(arg)
2287        """
2288        )
2289        reprec = testdir.inline_run("-v")
2290        reprec.assertoutcome(passed=4)
2291        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
2292        assert values == [1, 1, 2, 2]
2293
2294    def test_module_parametrized_ordering(self, testdir):
2295        testdir.makeini(
2296            """
2297            [pytest]
2298            console_output_style=classic
2299        """
2300        )
2301        testdir.makeconftest(
2302            """
2303            import pytest
2304
2305            @pytest.fixture(scope="session", params="s1 s2".split())
2306            def sarg():
2307                pass
2308            @pytest.fixture(scope="module", params="m1 m2".split())
2309            def marg():
2310                pass
2311        """
2312        )
2313        testdir.makepyfile(
2314            test_mod1="""
2315            def test_func(sarg):
2316                pass
2317            def test_func1(marg):
2318                pass
2319        """,
2320            test_mod2="""
2321            def test_func2(sarg):
2322                pass
2323            def test_func3(sarg, marg):
2324                pass
2325            def test_func3b(sarg, marg):
2326                pass
2327            def test_func4(marg):
2328                pass
2329        """,
2330        )
2331        result = testdir.runpytest("-v")
2332        result.stdout.fnmatch_lines(
2333            """
2334            test_mod1.py::test_func[s1] PASSED
2335            test_mod2.py::test_func2[s1] PASSED
2336            test_mod2.py::test_func3[s1-m1] PASSED
2337            test_mod2.py::test_func3b[s1-m1] PASSED
2338            test_mod2.py::test_func3[s1-m2] PASSED
2339            test_mod2.py::test_func3b[s1-m2] PASSED
2340            test_mod1.py::test_func[s2] PASSED
2341            test_mod2.py::test_func2[s2] PASSED
2342            test_mod2.py::test_func3[s2-m1] PASSED
2343            test_mod2.py::test_func3b[s2-m1] PASSED
2344            test_mod2.py::test_func4[m1] PASSED
2345            test_mod2.py::test_func3[s2-m2] PASSED
2346            test_mod2.py::test_func3b[s2-m2] PASSED
2347            test_mod2.py::test_func4[m2] PASSED
2348            test_mod1.py::test_func1[m1] PASSED
2349            test_mod1.py::test_func1[m2] PASSED
2350        """
2351        )
2352
2353    def test_dynamic_parametrized_ordering(self, testdir):
2354        testdir.makeini(
2355            """
2356            [pytest]
2357            console_output_style=classic
2358        """
2359        )
2360        testdir.makeconftest(
2361            """
2362            import pytest
2363
2364            def pytest_configure(config):
2365                class DynamicFixturePlugin(object):
2366                    @pytest.fixture(scope='session', params=['flavor1', 'flavor2'])
2367                    def flavor(self, request):
2368                        return request.param
2369                config.pluginmanager.register(DynamicFixturePlugin(), 'flavor-fixture')
2370
2371            @pytest.fixture(scope='session', params=['vxlan', 'vlan'])
2372            def encap(request):
2373                return request.param
2374
2375            @pytest.fixture(scope='session', autouse='True')
2376            def reprovision(request, flavor, encap):
2377                pass
2378        """
2379        )
2380        testdir.makepyfile(
2381            """
2382            def test(reprovision):
2383                pass
2384            def test2(reprovision):
2385                pass
2386        """
2387        )
2388        result = testdir.runpytest("-v")
2389        result.stdout.fnmatch_lines(
2390            """
2391            test_dynamic_parametrized_ordering.py::test[flavor1-vxlan] PASSED
2392            test_dynamic_parametrized_ordering.py::test2[flavor1-vxlan] PASSED
2393            test_dynamic_parametrized_ordering.py::test[flavor2-vxlan] PASSED
2394            test_dynamic_parametrized_ordering.py::test2[flavor2-vxlan] PASSED
2395            test_dynamic_parametrized_ordering.py::test[flavor2-vlan] PASSED
2396            test_dynamic_parametrized_ordering.py::test2[flavor2-vlan] PASSED
2397            test_dynamic_parametrized_ordering.py::test[flavor1-vlan] PASSED
2398            test_dynamic_parametrized_ordering.py::test2[flavor1-vlan] PASSED
2399        """
2400        )
2401
2402    def test_class_ordering(self, testdir):
2403        testdir.makeini(
2404            """
2405            [pytest]
2406            console_output_style=classic
2407        """
2408        )
2409        testdir.makeconftest(
2410            """
2411            import pytest
2412
2413            values = []
2414
2415            @pytest.fixture(scope="function", params=[1,2])
2416            def farg(request):
2417                return request.param
2418
2419            @pytest.fixture(scope="class", params=list("ab"))
2420            def carg(request):
2421                return request.param
2422
2423            @pytest.fixture(scope="function", autouse=True)
2424            def append(request, farg, carg):
2425                def fin():
2426                    values.append("fin_%s%s" % (carg, farg))
2427                request.addfinalizer(fin)
2428        """
2429        )
2430        testdir.makepyfile(
2431            """
2432            import pytest
2433
2434            class TestClass2(object):
2435                def test_1(self):
2436                    pass
2437                def test_2(self):
2438                    pass
2439            class TestClass(object):
2440                def test_3(self):
2441                    pass
2442        """
2443        )
2444        result = testdir.runpytest("-vs")
2445        result.stdout.re_match_lines(
2446            r"""
2447            test_class_ordering.py::TestClass2::test_1\[a-1\] PASSED
2448            test_class_ordering.py::TestClass2::test_1\[a-2\] PASSED
2449            test_class_ordering.py::TestClass2::test_2\[a-1\] PASSED
2450            test_class_ordering.py::TestClass2::test_2\[a-2\] PASSED
2451            test_class_ordering.py::TestClass2::test_1\[b-1\] PASSED
2452            test_class_ordering.py::TestClass2::test_1\[b-2\] PASSED
2453            test_class_ordering.py::TestClass2::test_2\[b-1\] PASSED
2454            test_class_ordering.py::TestClass2::test_2\[b-2\] PASSED
2455            test_class_ordering.py::TestClass::test_3\[a-1\] PASSED
2456            test_class_ordering.py::TestClass::test_3\[a-2\] PASSED
2457            test_class_ordering.py::TestClass::test_3\[b-1\] PASSED
2458            test_class_ordering.py::TestClass::test_3\[b-2\] PASSED
2459        """
2460        )
2461
2462    def test_parametrize_separated_order_higher_scope_first(self, testdir):
2463        testdir.makepyfile(
2464            """
2465            import pytest
2466
2467            @pytest.fixture(scope="function", params=[1, 2])
2468            def arg(request):
2469                param = request.param
2470                request.addfinalizer(lambda: values.append("fin:%s" % param))
2471                values.append("create:%s" % param)
2472                return request.param
2473
2474            @pytest.fixture(scope="module", params=["mod1", "mod2"])
2475            def modarg(request):
2476                param = request.param
2477                request.addfinalizer(lambda: values.append("fin:%s" % param))
2478                values.append("create:%s" % param)
2479                return request.param
2480
2481            values = []
2482            def test_1(arg):
2483                values.append("test1")
2484            def test_2(modarg):
2485                values.append("test2")
2486            def test_3(arg, modarg):
2487                values.append("test3")
2488            def test_4(modarg, arg):
2489                values.append("test4")
2490        """
2491        )
2492        reprec = testdir.inline_run("-v")
2493        reprec.assertoutcome(passed=12)
2494        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
2495        expected = [
2496            "create:1",
2497            "test1",
2498            "fin:1",
2499            "create:2",
2500            "test1",
2501            "fin:2",
2502            "create:mod1",
2503            "test2",
2504            "create:1",
2505            "test3",
2506            "fin:1",
2507            "create:2",
2508            "test3",
2509            "fin:2",
2510            "create:1",
2511            "test4",
2512            "fin:1",
2513            "create:2",
2514            "test4",
2515            "fin:2",
2516            "fin:mod1",
2517            "create:mod2",
2518            "test2",
2519            "create:1",
2520            "test3",
2521            "fin:1",
2522            "create:2",
2523            "test3",
2524            "fin:2",
2525            "create:1",
2526            "test4",
2527            "fin:1",
2528            "create:2",
2529            "test4",
2530            "fin:2",
2531            "fin:mod2",
2532        ]
2533        import pprint
2534
2535        pprint.pprint(list(zip(values, expected)))
2536        assert values == expected
2537
2538    def test_parametrized_fixture_teardown_order(self, testdir):
2539        testdir.makepyfile(
2540            """
2541            import pytest
2542            @pytest.fixture(params=[1,2], scope="class")
2543            def param1(request):
2544                return request.param
2545
2546            values = []
2547
2548            class TestClass(object):
2549                @classmethod
2550                @pytest.fixture(scope="class", autouse=True)
2551                def setup1(self, request, param1):
2552                    values.append(1)
2553                    request.addfinalizer(self.teardown1)
2554                @classmethod
2555                def teardown1(self):
2556                    assert values.pop() == 1
2557                @pytest.fixture(scope="class", autouse=True)
2558                def setup2(self, request, param1):
2559                    values.append(2)
2560                    request.addfinalizer(self.teardown2)
2561                @classmethod
2562                def teardown2(self):
2563                    assert values.pop() == 2
2564                def test(self):
2565                    pass
2566
2567            def test_finish():
2568                assert not values
2569        """
2570        )
2571        result = testdir.runpytest("-v")
2572        result.stdout.fnmatch_lines(
2573            """
2574            *3 passed*
2575        """
2576        )
2577        assert "error" not in result.stdout.str()
2578
2579    def test_fixture_finalizer(self, testdir):
2580        testdir.makeconftest(
2581            """
2582            import pytest
2583            import sys
2584
2585            @pytest.fixture
2586            def browser(request):
2587
2588                def finalize():
2589                    sys.stdout.write('Finalized')
2590                request.addfinalizer(finalize)
2591                return {}
2592        """
2593        )
2594        b = testdir.mkdir("subdir")
2595        b.join("test_overridden_fixture_finalizer.py").write(
2596            textwrap.dedent(
2597                """\
2598                import pytest
2599                @pytest.fixture
2600                def browser(browser):
2601                    browser['visited'] = True
2602                    return browser
2603
2604                def test_browser(browser):
2605                    assert browser['visited'] is True
2606                """
2607            )
2608        )
2609        reprec = testdir.runpytest("-s")
2610        for test in ["test_browser"]:
2611            reprec.stdout.fnmatch_lines(["*Finalized*"])
2612
2613    def test_class_scope_with_normal_tests(self, testdir):
2614        testpath = testdir.makepyfile(
2615            """
2616            import pytest
2617
2618            class Box(object):
2619                value = 0
2620
2621            @pytest.fixture(scope='class')
2622            def a(request):
2623                Box.value += 1
2624                return Box.value
2625
2626            def test_a(a):
2627                assert a == 1
2628
2629            class Test1(object):
2630                def test_b(self, a):
2631                    assert a == 2
2632
2633            class Test2(object):
2634                def test_c(self, a):
2635                    assert a == 3"""
2636        )
2637        reprec = testdir.inline_run(testpath)
2638        for test in ["test_a", "test_b", "test_c"]:
2639            assert reprec.matchreport(test).passed
2640
2641    def test_request_is_clean(self, testdir):
2642        testdir.makepyfile(
2643            """
2644            import pytest
2645            values = []
2646            @pytest.fixture(params=[1, 2])
2647            def fix(request):
2648                request.addfinalizer(lambda: values.append(request.param))
2649            def test_fix(fix):
2650                pass
2651        """
2652        )
2653        reprec = testdir.inline_run("-s")
2654        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
2655        assert values == [1, 2]
2656
2657    def test_parametrize_separated_lifecycle(self, testdir):
2658        testdir.makepyfile(
2659            """
2660            import pytest
2661
2662            values = []
2663            @pytest.fixture(scope="module", params=[1, 2])
2664            def arg(request):
2665                x = request.param
2666                request.addfinalizer(lambda: values.append("fin%s" % x))
2667                return request.param
2668            def test_1(arg):
2669                values.append(arg)
2670            def test_2(arg):
2671                values.append(arg)
2672        """
2673        )
2674        reprec = testdir.inline_run("-vs")
2675        reprec.assertoutcome(passed=4)
2676        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
2677        import pprint
2678
2679        pprint.pprint(values)
2680        # assert len(values) == 6
2681        assert values[0] == values[1] == 1
2682        assert values[2] == "fin1"
2683        assert values[3] == values[4] == 2
2684        assert values[5] == "fin2"
2685
2686    def test_parametrize_function_scoped_finalizers_called(self, testdir):
2687        testdir.makepyfile(
2688            """
2689            import pytest
2690
2691            @pytest.fixture(scope="function", params=[1, 2])
2692            def arg(request):
2693                x = request.param
2694                request.addfinalizer(lambda: values.append("fin%s" % x))
2695                return request.param
2696
2697            values = []
2698            def test_1(arg):
2699                values.append(arg)
2700            def test_2(arg):
2701                values.append(arg)
2702            def test_3():
2703                assert len(values) == 8
2704                assert values == [1, "fin1", 2, "fin2", 1, "fin1", 2, "fin2"]
2705        """
2706        )
2707        reprec = testdir.inline_run("-v")
2708        reprec.assertoutcome(passed=5)
2709
2710    @pytest.mark.parametrize("scope", ["session", "function", "module"])
2711    def test_finalizer_order_on_parametrization(self, scope, testdir):
2712        """#246"""
2713        testdir.makepyfile(
2714            """
2715            import pytest
2716            values = []
2717
2718            @pytest.fixture(scope=%(scope)r, params=["1"])
2719            def fix1(request):
2720                return request.param
2721
2722            @pytest.fixture(scope=%(scope)r)
2723            def fix2(request, base):
2724                def cleanup_fix2():
2725                    assert not values, "base should not have been finalized"
2726                request.addfinalizer(cleanup_fix2)
2727
2728            @pytest.fixture(scope=%(scope)r)
2729            def base(request, fix1):
2730                def cleanup_base():
2731                    values.append("fin_base")
2732                    print("finalizing base")
2733                request.addfinalizer(cleanup_base)
2734
2735            def test_begin():
2736                pass
2737            def test_baz(base, fix2):
2738                pass
2739            def test_other():
2740                pass
2741        """
2742            % {"scope": scope}
2743        )
2744        reprec = testdir.inline_run("-lvs")
2745        reprec.assertoutcome(passed=3)
2746
2747    def test_class_scope_parametrization_ordering(self, testdir):
2748        """#396"""
2749        testdir.makepyfile(
2750            """
2751            import pytest
2752            values = []
2753            @pytest.fixture(params=["John", "Doe"], scope="class")
2754            def human(request):
2755                request.addfinalizer(lambda: values.append("fin %s" % request.param))
2756                return request.param
2757
2758            class TestGreetings(object):
2759                def test_hello(self, human):
2760                    values.append("test_hello")
2761
2762            class TestMetrics(object):
2763                def test_name(self, human):
2764                    values.append("test_name")
2765
2766                def test_population(self, human):
2767                    values.append("test_population")
2768        """
2769        )
2770        reprec = testdir.inline_run()
2771        reprec.assertoutcome(passed=6)
2772        values = reprec.getcalls("pytest_runtest_call")[0].item.module.values
2773        assert values == [
2774            "test_hello",
2775            "fin John",
2776            "test_hello",
2777            "fin Doe",
2778            "test_name",
2779            "test_population",
2780            "fin John",
2781            "test_name",
2782            "test_population",
2783            "fin Doe",
2784        ]
2785
2786    def test_parametrize_setup_function(self, testdir):
2787        testdir.makepyfile(
2788            """
2789            import pytest
2790
2791            @pytest.fixture(scope="module", params=[1, 2])
2792            def arg(request):
2793                return request.param
2794
2795            @pytest.fixture(scope="module", autouse=True)
2796            def mysetup(request, arg):
2797                request.addfinalizer(lambda: values.append("fin%s" % arg))
2798                values.append("setup%s" % arg)
2799
2800            values = []
2801            def test_1(arg):
2802                values.append(arg)
2803            def test_2(arg):
2804                values.append(arg)
2805            def test_3():
2806                import pprint
2807                pprint.pprint(values)
2808                if arg == 1:
2809                    assert values == ["setup1", 1, 1, ]
2810                elif arg == 2:
2811                    assert values == ["setup1", 1, 1, "fin1",
2812                                 "setup2", 2, 2, ]
2813
2814        """
2815        )
2816        reprec = testdir.inline_run("-v")
2817        reprec.assertoutcome(passed=6)
2818
2819    def test_fixture_marked_function_not_collected_as_test(self, testdir):
2820        testdir.makepyfile(
2821            """
2822            import pytest
2823            @pytest.fixture
2824            def test_app():
2825                return 1
2826
2827            def test_something(test_app):
2828                assert test_app == 1
2829        """
2830        )
2831        reprec = testdir.inline_run()
2832        reprec.assertoutcome(passed=1)
2833
2834    def test_params_and_ids(self, testdir):
2835        testdir.makepyfile(
2836            """
2837            import pytest
2838
2839            @pytest.fixture(params=[object(), object()],
2840                            ids=['alpha', 'beta'])
2841            def fix(request):
2842                return request.param
2843
2844            def test_foo(fix):
2845                assert 1
2846        """
2847        )
2848        res = testdir.runpytest("-v")
2849        res.stdout.fnmatch_lines(["*test_foo*alpha*", "*test_foo*beta*"])
2850
2851    def test_params_and_ids_yieldfixture(self, testdir):
2852        testdir.makepyfile(
2853            """
2854            import pytest
2855
2856            @pytest.yield_fixture(params=[object(), object()],
2857                                  ids=['alpha', 'beta'])
2858            def fix(request):
2859                 yield request.param
2860
2861            def test_foo(fix):
2862                assert 1
2863        """
2864        )
2865        res = testdir.runpytest("-v")
2866        res.stdout.fnmatch_lines(["*test_foo*alpha*", "*test_foo*beta*"])
2867
2868    def test_deterministic_fixture_collection(self, testdir, monkeypatch):
2869        """#920"""
2870        testdir.makepyfile(
2871            """
2872            import pytest
2873
2874            @pytest.fixture(scope="module",
2875                            params=["A",
2876                                    "B",
2877                                    "C"])
2878            def A(request):
2879                return request.param
2880
2881            @pytest.fixture(scope="module",
2882                            params=["DDDDDDDDD", "EEEEEEEEEEEE", "FFFFFFFFFFF", "banansda"])
2883            def B(request, A):
2884                return request.param
2885
2886            def test_foo(B):
2887                # Something funky is going on here.
2888                # Despite specified seeds, on what is collected,
2889                # sometimes we get unexpected passes. hashing B seems
2890                # to help?
2891                assert hash(B) or True
2892            """
2893        )
2894        monkeypatch.setenv("PYTHONHASHSEED", "1")
2895        out1 = testdir.runpytest_subprocess("-v")
2896        monkeypatch.setenv("PYTHONHASHSEED", "2")
2897        out2 = testdir.runpytest_subprocess("-v")
2898        out1 = [
2899            line
2900            for line in out1.outlines
2901            if line.startswith("test_deterministic_fixture_collection.py::test_foo")
2902        ]
2903        out2 = [
2904            line
2905            for line in out2.outlines
2906            if line.startswith("test_deterministic_fixture_collection.py::test_foo")
2907        ]
2908        assert len(out1) == 12
2909        assert out1 == out2
2910
2911
2912class TestRequestScopeAccess(object):
2913    pytestmark = pytest.mark.parametrize(
2914        ("scope", "ok", "error"),
2915        [
2916            ["session", "", "fspath class function module"],
2917            ["module", "module fspath", "cls function"],
2918            ["class", "module fspath cls", "function"],
2919            ["function", "module fspath cls function", ""],
2920        ],
2921    )
2922
2923    def test_setup(self, testdir, scope, ok, error):
2924        testdir.makepyfile(
2925            """
2926            import pytest
2927            @pytest.fixture(scope=%r, autouse=True)
2928            def myscoped(request):
2929                for x in %r:
2930                    assert hasattr(request, x)
2931                for x in %r:
2932                    pytest.raises(AttributeError, lambda:
2933                        getattr(request, x))
2934                assert request.session
2935                assert request.config
2936            def test_func():
2937                pass
2938        """
2939            % (scope, ok.split(), error.split())
2940        )
2941        reprec = testdir.inline_run("-l")
2942        reprec.assertoutcome(passed=1)
2943
2944    def test_funcarg(self, testdir, scope, ok, error):
2945        testdir.makepyfile(
2946            """
2947            import pytest
2948            @pytest.fixture(scope=%r)
2949            def arg(request):
2950                for x in %r:
2951                    assert hasattr(request, x)
2952                for x in %r:
2953                    pytest.raises(AttributeError, lambda:
2954                        getattr(request, x))
2955                assert request.session
2956                assert request.config
2957            def test_func(arg):
2958                pass
2959        """
2960            % (scope, ok.split(), error.split())
2961        )
2962        reprec = testdir.inline_run()
2963        reprec.assertoutcome(passed=1)
2964
2965
2966class TestErrors(object):
2967    def test_subfactory_missing_funcarg(self, testdir):
2968        testdir.makepyfile(
2969            """
2970            import pytest
2971            @pytest.fixture()
2972            def gen(qwe123):
2973                return 1
2974            def test_something(gen):
2975                pass
2976        """
2977        )
2978        result = testdir.runpytest()
2979        assert result.ret != 0
2980        result.stdout.fnmatch_lines(
2981            ["*def gen(qwe123):*", "*fixture*qwe123*not found*", "*1 error*"]
2982        )
2983
2984    def test_issue498_fixture_finalizer_failing(self, testdir):
2985        testdir.makepyfile(
2986            """
2987            import pytest
2988            @pytest.fixture
2989            def fix1(request):
2990                def f():
2991                    raise KeyError
2992                request.addfinalizer(f)
2993                return object()
2994
2995            values = []
2996            def test_1(fix1):
2997                values.append(fix1)
2998            def test_2(fix1):
2999                values.append(fix1)
3000            def test_3():
3001                assert values[0] != values[1]
3002        """
3003        )
3004        result = testdir.runpytest()
3005        result.stdout.fnmatch_lines(
3006            """
3007            *ERROR*teardown*test_1*
3008            *KeyError*
3009            *ERROR*teardown*test_2*
3010            *KeyError*
3011            *3 pass*2 error*
3012        """
3013        )
3014
3015    def test_setupfunc_missing_funcarg(self, testdir):
3016        testdir.makepyfile(
3017            """
3018            import pytest
3019            @pytest.fixture(autouse=True)
3020            def gen(qwe123):
3021                return 1
3022            def test_something():
3023                pass
3024        """
3025        )
3026        result = testdir.runpytest()
3027        assert result.ret != 0
3028        result.stdout.fnmatch_lines(
3029            ["*def gen(qwe123):*", "*fixture*qwe123*not found*", "*1 error*"]
3030        )
3031
3032
3033class TestShowFixtures(object):
3034    def test_funcarg_compat(self, testdir):
3035        config = testdir.parseconfigure("--funcargs")
3036        assert config.option.showfixtures
3037
3038    def test_show_fixtures(self, testdir):
3039        result = testdir.runpytest("--fixtures")
3040        result.stdout.fnmatch_lines(
3041            [
3042                "tmpdir_factory [[]session scope[]]",
3043                "*for the test session*",
3044                "tmpdir",
3045                "*temporary directory*",
3046            ]
3047        )
3048
3049    def test_show_fixtures_verbose(self, testdir):
3050        result = testdir.runpytest("--fixtures", "-v")
3051        result.stdout.fnmatch_lines(
3052            [
3053                "tmpdir_factory [[]session scope[]] -- *tmpdir.py*",
3054                "*for the test session*",
3055                "tmpdir -- *tmpdir.py*",
3056                "*temporary directory*",
3057            ]
3058        )
3059
3060    def test_show_fixtures_testmodule(self, testdir):
3061        p = testdir.makepyfile(
3062            '''
3063            import pytest
3064            @pytest.fixture
3065            def _arg0():
3066                """ hidden """
3067            @pytest.fixture
3068            def arg1():
3069                """  hello world """
3070        '''
3071        )
3072        result = testdir.runpytest("--fixtures", p)
3073        result.stdout.fnmatch_lines(
3074            """
3075            *tmpdir
3076            *fixtures defined from*
3077            *arg1*
3078            *hello world*
3079        """
3080        )
3081        assert "arg0" not in result.stdout.str()
3082
3083    @pytest.mark.parametrize("testmod", [True, False])
3084    def test_show_fixtures_conftest(self, testdir, testmod):
3085        testdir.makeconftest(
3086            '''
3087            import pytest
3088            @pytest.fixture
3089            def arg1():
3090                """  hello world """
3091        '''
3092        )
3093        if testmod:
3094            testdir.makepyfile(
3095                """
3096                def test_hello():
3097                    pass
3098            """
3099            )
3100        result = testdir.runpytest("--fixtures")
3101        result.stdout.fnmatch_lines(
3102            """
3103            *tmpdir*
3104            *fixtures defined from*conftest*
3105            *arg1*
3106            *hello world*
3107        """
3108        )
3109
3110    def test_show_fixtures_trimmed_doc(self, testdir):
3111        p = testdir.makepyfile(
3112            textwrap.dedent(
3113                '''\
3114                import pytest
3115                @pytest.fixture
3116                def arg1():
3117                    """
3118                    line1
3119                    line2
3120
3121                    """
3122                @pytest.fixture
3123                def arg2():
3124                    """
3125                    line1
3126                    line2
3127
3128                    """
3129                '''
3130            )
3131        )
3132        result = testdir.runpytest("--fixtures", p)
3133        result.stdout.fnmatch_lines(
3134            textwrap.dedent(
3135                """\
3136                * fixtures defined from test_show_fixtures_trimmed_doc *
3137                arg2
3138                    line1
3139                    line2
3140                arg1
3141                    line1
3142                    line2
3143                """
3144            )
3145        )
3146
3147    def test_show_fixtures_indented_doc(self, testdir):
3148        p = testdir.makepyfile(
3149            textwrap.dedent(
3150                '''\
3151                import pytest
3152                @pytest.fixture
3153                def fixture1():
3154                    """
3155                    line1
3156                        indented line
3157                    """
3158                '''
3159            )
3160        )
3161        result = testdir.runpytest("--fixtures", p)
3162        result.stdout.fnmatch_lines(
3163            textwrap.dedent(
3164                """\
3165                * fixtures defined from test_show_fixtures_indented_doc *
3166                fixture1
3167                    line1
3168                        indented line
3169                """
3170            )
3171        )
3172
3173    def test_show_fixtures_indented_doc_first_line_unindented(self, testdir):
3174        p = testdir.makepyfile(
3175            textwrap.dedent(
3176                '''\
3177                import pytest
3178                @pytest.fixture
3179                def fixture1():
3180                    """line1
3181                    line2
3182                        indented line
3183                    """
3184                '''
3185            )
3186        )
3187        result = testdir.runpytest("--fixtures", p)
3188        result.stdout.fnmatch_lines(
3189            textwrap.dedent(
3190                """\
3191                * fixtures defined from test_show_fixtures_indented_doc_first_line_unindented *
3192                fixture1
3193                    line1
3194                    line2
3195                        indented line
3196                """
3197            )
3198        )
3199
3200    def test_show_fixtures_indented_in_class(self, testdir):
3201        p = testdir.makepyfile(
3202            textwrap.dedent(
3203                '''\
3204                import pytest
3205                class TestClass(object):
3206                    @pytest.fixture
3207                    def fixture1(self):
3208                        """line1
3209                        line2
3210                            indented line
3211                        """
3212                '''
3213            )
3214        )
3215        result = testdir.runpytest("--fixtures", p)
3216        result.stdout.fnmatch_lines(
3217            textwrap.dedent(
3218                """\
3219                * fixtures defined from test_show_fixtures_indented_in_class *
3220                fixture1
3221                    line1
3222                    line2
3223                        indented line
3224                """
3225            )
3226        )
3227
3228    def test_show_fixtures_different_files(self, testdir):
3229        """
3230        #833: --fixtures only shows fixtures from first file
3231        """
3232        testdir.makepyfile(
3233            test_a='''
3234            import pytest
3235
3236            @pytest.fixture
3237            def fix_a():
3238                """Fixture A"""
3239                pass
3240
3241            def test_a(fix_a):
3242                pass
3243        '''
3244        )
3245        testdir.makepyfile(
3246            test_b='''
3247            import pytest
3248
3249            @pytest.fixture
3250            def fix_b():
3251                """Fixture B"""
3252                pass
3253
3254            def test_b(fix_b):
3255                pass
3256        '''
3257        )
3258        result = testdir.runpytest("--fixtures")
3259        result.stdout.fnmatch_lines(
3260            """
3261            * fixtures defined from test_a *
3262            fix_a
3263                Fixture A
3264
3265            * fixtures defined from test_b *
3266            fix_b
3267                Fixture B
3268        """
3269        )
3270
3271    def test_show_fixtures_with_same_name(self, testdir):
3272        testdir.makeconftest(
3273            '''
3274            import pytest
3275            @pytest.fixture
3276            def arg1():
3277                """Hello World in conftest.py"""
3278                return "Hello World"
3279        '''
3280        )
3281        testdir.makepyfile(
3282            """
3283            def test_foo(arg1):
3284                assert arg1 == "Hello World"
3285        """
3286        )
3287        testdir.makepyfile(
3288            '''
3289            import pytest
3290            @pytest.fixture
3291            def arg1():
3292                """Hi from test module"""
3293                return "Hi"
3294            def test_bar(arg1):
3295                assert arg1 == "Hi"
3296        '''
3297        )
3298        result = testdir.runpytest("--fixtures")
3299        result.stdout.fnmatch_lines(
3300            """
3301            * fixtures defined from conftest *
3302            arg1
3303                Hello World in conftest.py
3304
3305            * fixtures defined from test_show_fixtures_with_same_name *
3306            arg1
3307                Hi from test module
3308        """
3309        )
3310
3311    def test_fixture_disallow_twice(self):
3312        """Test that applying @pytest.fixture twice generates an error (#2334)."""
3313        with pytest.raises(ValueError):
3314
3315            @pytest.fixture
3316            @pytest.fixture
3317            def foo():
3318                pass
3319
3320
3321class TestContextManagerFixtureFuncs(object):
3322    @pytest.fixture(params=["fixture", "yield_fixture"])
3323    def flavor(self, request, testdir, monkeypatch):
3324        monkeypatch.setenv("PYTEST_FIXTURE_FLAVOR", request.param)
3325        testdir.makepyfile(
3326            test_context="""
3327            import os
3328            import pytest
3329            import warnings
3330            VAR = "PYTEST_FIXTURE_FLAVOR"
3331            if VAR not in os.environ:
3332                warnings.warn("PYTEST_FIXTURE_FLAVOR was not set, assuming fixture")
3333                fixture = pytest.fixture
3334            else:
3335                fixture = getattr(pytest, os.environ[VAR])
3336        """
3337        )
3338
3339    def test_simple(self, testdir, flavor):
3340        testdir.makepyfile(
3341            """
3342            from __future__ import print_function
3343            from test_context import fixture
3344            @fixture
3345            def arg1():
3346                print("setup")
3347                yield 1
3348                print("teardown")
3349            def test_1(arg1):
3350                print("test1", arg1)
3351            def test_2(arg1):
3352                print("test2", arg1)
3353                assert 0
3354        """
3355        )
3356        result = testdir.runpytest("-s")
3357        result.stdout.fnmatch_lines(
3358            """
3359            *setup*
3360            *test1 1*
3361            *teardown*
3362            *setup*
3363            *test2 1*
3364            *teardown*
3365        """
3366        )
3367
3368    def test_scoped(self, testdir, flavor):
3369        testdir.makepyfile(
3370            """
3371            from __future__ import print_function
3372            from test_context import fixture
3373            @fixture(scope="module")
3374            def arg1():
3375                print("setup")
3376                yield 1
3377                print("teardown")
3378            def test_1(arg1):
3379                print("test1", arg1)
3380            def test_2(arg1):
3381                print("test2", arg1)
3382        """
3383        )
3384        result = testdir.runpytest("-s")
3385        result.stdout.fnmatch_lines(
3386            """
3387            *setup*
3388            *test1 1*
3389            *test2 1*
3390            *teardown*
3391        """
3392        )
3393
3394    def test_setup_exception(self, testdir, flavor):
3395        testdir.makepyfile(
3396            """
3397            from test_context import fixture
3398            @fixture(scope="module")
3399            def arg1():
3400                pytest.fail("setup")
3401                yield 1
3402            def test_1(arg1):
3403                pass
3404        """
3405        )
3406        result = testdir.runpytest("-s")
3407        result.stdout.fnmatch_lines(
3408            """
3409            *pytest.fail*setup*
3410            *1 error*
3411        """
3412        )
3413
3414    def test_teardown_exception(self, testdir, flavor):
3415        testdir.makepyfile(
3416            """
3417            from test_context import fixture
3418            @fixture(scope="module")
3419            def arg1():
3420                yield 1
3421                pytest.fail("teardown")
3422            def test_1(arg1):
3423                pass
3424        """
3425        )
3426        result = testdir.runpytest("-s")
3427        result.stdout.fnmatch_lines(
3428            """
3429            *pytest.fail*teardown*
3430            *1 passed*1 error*
3431        """
3432        )
3433
3434    def test_yields_more_than_one(self, testdir, flavor):
3435        testdir.makepyfile(
3436            """
3437            from test_context import fixture
3438            @fixture(scope="module")
3439            def arg1():
3440                yield 1
3441                yield 2
3442            def test_1(arg1):
3443                pass
3444        """
3445        )
3446        result = testdir.runpytest("-s")
3447        result.stdout.fnmatch_lines(
3448            """
3449            *fixture function*
3450            *test_yields*:2*
3451        """
3452        )
3453
3454    def test_custom_name(self, testdir, flavor):
3455        testdir.makepyfile(
3456            """
3457            from test_context import fixture
3458            @fixture(name='meow')
3459            def arg1():
3460                return 'mew'
3461            def test_1(meow):
3462                print(meow)
3463        """
3464        )
3465        result = testdir.runpytest("-s")
3466        result.stdout.fnmatch_lines(["*mew*"])
3467
3468
3469class TestParameterizedSubRequest(object):
3470    def test_call_from_fixture(self, testdir):
3471        testdir.makepyfile(
3472            test_call_from_fixture="""
3473            import pytest
3474
3475            @pytest.fixture(params=[0, 1, 2])
3476            def fix_with_param(request):
3477                return request.param
3478
3479            @pytest.fixture
3480            def get_named_fixture(request):
3481                return request.getfixturevalue('fix_with_param')
3482
3483            def test_foo(request, get_named_fixture):
3484                pass
3485            """
3486        )
3487        result = testdir.runpytest()
3488        result.stdout.fnmatch_lines(
3489            [
3490                "The requested fixture has no parameter defined for test:",
3491                "    test_call_from_fixture.py::test_foo",
3492                "Requested fixture 'fix_with_param' defined in:",
3493                "test_call_from_fixture.py:4",
3494                "Requested here:",
3495                "test_call_from_fixture.py:9",
3496                "*1 error in*",
3497            ]
3498        )
3499
3500    def test_call_from_test(self, testdir):
3501        testdir.makepyfile(
3502            test_call_from_test="""
3503            import pytest
3504
3505            @pytest.fixture(params=[0, 1, 2])
3506            def fix_with_param(request):
3507                return request.param
3508
3509            def test_foo(request):
3510                request.getfixturevalue('fix_with_param')
3511            """
3512        )
3513        result = testdir.runpytest()
3514        result.stdout.fnmatch_lines(
3515            [
3516                "The requested fixture has no parameter defined for test:",
3517                "    test_call_from_test.py::test_foo",
3518                "Requested fixture 'fix_with_param' defined in:",
3519                "test_call_from_test.py:4",
3520                "Requested here:",
3521                "test_call_from_test.py:8",
3522                "*1 failed*",
3523            ]
3524        )
3525
3526    def test_external_fixture(self, testdir):
3527        testdir.makeconftest(
3528            """
3529            import pytest
3530
3531            @pytest.fixture(params=[0, 1, 2])
3532            def fix_with_param(request):
3533                return request.param
3534            """
3535        )
3536
3537        testdir.makepyfile(
3538            test_external_fixture="""
3539            def test_foo(request):
3540                request.getfixturevalue('fix_with_param')
3541            """
3542        )
3543        result = testdir.runpytest()
3544        result.stdout.fnmatch_lines(
3545            [
3546                "The requested fixture has no parameter defined for test:",
3547                "    test_external_fixture.py::test_foo",
3548                "",
3549                "Requested fixture 'fix_with_param' defined in:",
3550                "conftest.py:4",
3551                "Requested here:",
3552                "test_external_fixture.py:2",
3553                "*1 failed*",
3554            ]
3555        )
3556
3557    def test_non_relative_path(self, testdir):
3558        tests_dir = testdir.mkdir("tests")
3559        fixdir = testdir.mkdir("fixtures")
3560        fixfile = fixdir.join("fix.py")
3561        fixfile.write(
3562            textwrap.dedent(
3563                """\
3564                import pytest
3565
3566                @pytest.fixture(params=[0, 1, 2])
3567                def fix_with_param(request):
3568                    return request.param
3569                """
3570            )
3571        )
3572
3573        testfile = tests_dir.join("test_foos.py")
3574        testfile.write(
3575            textwrap.dedent(
3576                """\
3577                from fix import fix_with_param
3578
3579                def test_foo(request):
3580                    request.getfixturevalue('fix_with_param')
3581                """
3582            )
3583        )
3584
3585        tests_dir.chdir()
3586        testdir.syspathinsert(fixdir)
3587        result = testdir.runpytest()
3588        result.stdout.fnmatch_lines(
3589            [
3590                "The requested fixture has no parameter defined for test:",
3591                "    test_foos.py::test_foo",
3592                "",
3593                "Requested fixture 'fix_with_param' defined in:",
3594                "*fix.py:4",
3595                "Requested here:",
3596                "test_foos.py:4",
3597                "*1 failed*",
3598            ]
3599        )
3600
3601
3602def test_pytest_fixture_setup_and_post_finalizer_hook(testdir):
3603    testdir.makeconftest(
3604        """
3605        from __future__ import print_function
3606        def pytest_fixture_setup(fixturedef, request):
3607            print('ROOT setup hook called for {0} from {1}'.format(fixturedef.argname, request.node.name))
3608        def pytest_fixture_post_finalizer(fixturedef, request):
3609            print('ROOT finalizer hook called for {0} from {1}'.format(fixturedef.argname, request.node.name))
3610    """
3611    )
3612    testdir.makepyfile(
3613        **{
3614            "tests/conftest.py": """
3615            from __future__ import print_function
3616            def pytest_fixture_setup(fixturedef, request):
3617                print('TESTS setup hook called for {0} from {1}'.format(fixturedef.argname, request.node.name))
3618            def pytest_fixture_post_finalizer(fixturedef, request):
3619                print('TESTS finalizer hook called for {0} from {1}'.format(fixturedef.argname, request.node.name))
3620        """,
3621            "tests/test_hooks.py": """
3622            from __future__ import print_function
3623            import pytest
3624
3625            @pytest.fixture()
3626            def my_fixture():
3627                return 'some'
3628
3629            def test_func(my_fixture):
3630                print('TEST test_func')
3631                assert my_fixture == 'some'
3632        """,
3633        }
3634    )
3635    result = testdir.runpytest("-s")
3636    assert result.ret == 0
3637    result.stdout.fnmatch_lines(
3638        [
3639            "*TESTS setup hook called for my_fixture from test_func*",
3640            "*ROOT setup hook called for my_fixture from test_func*",
3641            "*TEST test_func*",
3642            "*TESTS finalizer hook called for my_fixture from test_func*",
3643            "*ROOT finalizer hook called for my_fixture from test_func*",
3644        ]
3645    )
3646
3647
3648class TestScopeOrdering(object):
3649    """Class of tests that ensure fixtures are ordered based on their scopes (#2405)"""
3650
3651    @pytest.mark.parametrize("variant", ["mark", "autouse"])
3652    def test_func_closure_module_auto(self, testdir, variant, monkeypatch):
3653        """Semantically identical to the example posted in #2405 when ``use_mark=True``"""
3654        monkeypatch.setenv("FIXTURE_ACTIVATION_VARIANT", variant)
3655        testdir.makepyfile(
3656            """
3657            import warnings
3658            import os
3659            import pytest
3660            VAR = 'FIXTURE_ACTIVATION_VARIANT'
3661            VALID_VARS = ('autouse', 'mark')
3662
3663            VARIANT = os.environ.get(VAR)
3664            if VARIANT is None or VARIANT not in VALID_VARS:
3665                warnings.warn("{!r} is not  in {}, assuming autouse".format(VARIANT, VALID_VARS) )
3666                variant = 'mark'
3667
3668            @pytest.fixture(scope='module', autouse=VARIANT == 'autouse')
3669            def m1(): pass
3670
3671            if VARIANT=='mark':
3672                pytestmark = pytest.mark.usefixtures('m1')
3673
3674            @pytest.fixture(scope='function', autouse=True)
3675            def f1(): pass
3676
3677            def test_func(m1):
3678                pass
3679        """
3680        )
3681        items, _ = testdir.inline_genitems()
3682        request = FixtureRequest(items[0])
3683        assert request.fixturenames == "m1 f1".split()
3684
3685    def test_func_closure_with_native_fixtures(self, testdir, monkeypatch):
3686        """Sanity check that verifies the order returned by the closures and the actual fixture execution order:
3687        The execution order may differ because of fixture inter-dependencies.
3688        """
3689        monkeypatch.setattr(pytest, "FIXTURE_ORDER", [], raising=False)
3690        testdir.makepyfile(
3691            """
3692            import pytest
3693
3694            FIXTURE_ORDER = pytest.FIXTURE_ORDER
3695
3696            @pytest.fixture(scope="session")
3697            def s1():
3698                FIXTURE_ORDER.append('s1')
3699
3700            @pytest.fixture(scope="package")
3701            def p1():
3702                FIXTURE_ORDER.append('p1')
3703
3704            @pytest.fixture(scope="module")
3705            def m1():
3706                FIXTURE_ORDER.append('m1')
3707
3708            @pytest.fixture(scope='session')
3709            def my_tmpdir_factory():
3710                FIXTURE_ORDER.append('my_tmpdir_factory')
3711
3712            @pytest.fixture
3713            def my_tmpdir(my_tmpdir_factory):
3714                FIXTURE_ORDER.append('my_tmpdir')
3715
3716            @pytest.fixture
3717            def f1(my_tmpdir):
3718                FIXTURE_ORDER.append('f1')
3719
3720            @pytest.fixture
3721            def f2():
3722                FIXTURE_ORDER.append('f2')
3723
3724            def test_foo(f1, p1, m1, f2, s1): pass
3725        """
3726        )
3727        items, _ = testdir.inline_genitems()
3728        request = FixtureRequest(items[0])
3729        # order of fixtures based on their scope and position in the parameter list
3730        assert (
3731            request.fixturenames == "s1 my_tmpdir_factory p1 m1 f1 f2 my_tmpdir".split()
3732        )
3733        testdir.runpytest()
3734        # actual fixture execution differs: dependent fixtures must be created first ("my_tmpdir")
3735        assert (
3736            pytest.FIXTURE_ORDER == "s1 my_tmpdir_factory p1 m1 my_tmpdir f1 f2".split()
3737        )
3738
3739    def test_func_closure_module(self, testdir):
3740        testdir.makepyfile(
3741            """
3742            import pytest
3743
3744            @pytest.fixture(scope='module')
3745            def m1(): pass
3746
3747            @pytest.fixture(scope='function')
3748            def f1(): pass
3749
3750            def test_func(f1, m1):
3751                pass
3752        """
3753        )
3754        items, _ = testdir.inline_genitems()
3755        request = FixtureRequest(items[0])
3756        assert request.fixturenames == "m1 f1".split()
3757
3758    def test_func_closure_scopes_reordered(self, testdir):
3759        """Test ensures that fixtures are ordered by scope regardless of the order of the parameters, although
3760        fixtures of same scope keep the declared order
3761        """
3762        testdir.makepyfile(
3763            """
3764            import pytest
3765
3766            @pytest.fixture(scope='session')
3767            def s1(): pass
3768
3769            @pytest.fixture(scope='module')
3770            def m1(): pass
3771
3772            @pytest.fixture(scope='function')
3773            def f1(): pass
3774
3775            @pytest.fixture(scope='function')
3776            def f2(): pass
3777
3778            class Test:
3779
3780                @pytest.fixture(scope='class')
3781                def c1(cls): pass
3782
3783                def test_func(self, f2, f1, c1, m1, s1):
3784                    pass
3785        """
3786        )
3787        items, _ = testdir.inline_genitems()
3788        request = FixtureRequest(items[0])
3789        assert request.fixturenames == "s1 m1 c1 f2 f1".split()
3790
3791    def test_func_closure_same_scope_closer_root_first(self, testdir):
3792        """Auto-use fixtures of same scope are ordered by closer-to-root first"""
3793        testdir.makeconftest(
3794            """
3795            import pytest
3796
3797            @pytest.fixture(scope='module', autouse=True)
3798            def m_conf(): pass
3799        """
3800        )
3801        testdir.makepyfile(
3802            **{
3803                "sub/conftest.py": """
3804                import pytest
3805
3806                @pytest.fixture(scope='package', autouse=True)
3807                def p_sub(): pass
3808
3809                @pytest.fixture(scope='module', autouse=True)
3810                def m_sub(): pass
3811            """,
3812                "sub/__init__.py": "",
3813                "sub/test_func.py": """
3814                import pytest
3815
3816                @pytest.fixture(scope='module', autouse=True)
3817                def m_test(): pass
3818
3819                @pytest.fixture(scope='function')
3820                def f1(): pass
3821
3822                def test_func(m_test, f1):
3823                    pass
3824        """,
3825            }
3826        )
3827        items, _ = testdir.inline_genitems()
3828        request = FixtureRequest(items[0])
3829        assert request.fixturenames == "p_sub m_conf m_sub m_test f1".split()
3830
3831    def test_func_closure_all_scopes_complex(self, testdir):
3832        """Complex test involving all scopes and mixing autouse with normal fixtures"""
3833        testdir.makeconftest(
3834            """
3835            import pytest
3836
3837            @pytest.fixture(scope='session')
3838            def s1(): pass
3839
3840            @pytest.fixture(scope='package', autouse=True)
3841            def p1(): pass
3842        """
3843        )
3844        testdir.makepyfile(**{"__init__.py": ""})
3845        testdir.makepyfile(
3846            """
3847            import pytest
3848
3849            @pytest.fixture(scope='module', autouse=True)
3850            def m1(): pass
3851
3852            @pytest.fixture(scope='module')
3853            def m2(s1): pass
3854
3855            @pytest.fixture(scope='function')
3856            def f1(): pass
3857
3858            @pytest.fixture(scope='function')
3859            def f2(): pass
3860
3861            class Test:
3862
3863                @pytest.fixture(scope='class', autouse=True)
3864                def c1(self):
3865                    pass
3866
3867                def test_func(self, f2, f1, m2):
3868                    pass
3869        """
3870        )
3871        items, _ = testdir.inline_genitems()
3872        request = FixtureRequest(items[0])
3873        assert request.fixturenames == "s1 p1 m1 m2 c1 f2 f1".split()
3874
3875    def test_multiple_packages(self, testdir):
3876        """Complex test involving multiple package fixtures. Make sure teardowns
3877        are executed in order.
3878        .
3879        └── root
3880            ├── __init__.py
3881            ├── sub1
3882            │   ├── __init__.py
3883            │   ├── conftest.py
3884            │   └── test_1.py
3885            └── sub2
3886                ├── __init__.py
3887                ├── conftest.py
3888                └── test_2.py
3889        """
3890        root = testdir.mkdir("root")
3891        root.join("__init__.py").write("values = []")
3892        sub1 = root.mkdir("sub1")
3893        sub1.ensure("__init__.py")
3894        sub1.join("conftest.py").write(
3895            textwrap.dedent(
3896                """\
3897            import pytest
3898            from .. import values
3899            @pytest.fixture(scope="package")
3900            def fix():
3901                values.append("pre-sub1")
3902                yield values
3903                assert values.pop() == "pre-sub1"
3904        """
3905            )
3906        )
3907        sub1.join("test_1.py").write(
3908            textwrap.dedent(
3909                """\
3910            from .. import values
3911            def test_1(fix):
3912                assert values == ["pre-sub1"]
3913        """
3914            )
3915        )
3916        sub2 = root.mkdir("sub2")
3917        sub2.ensure("__init__.py")
3918        sub2.join("conftest.py").write(
3919            textwrap.dedent(
3920                """\
3921            import pytest
3922            from .. import values
3923            @pytest.fixture(scope="package")
3924            def fix():
3925                values.append("pre-sub2")
3926                yield values
3927                assert values.pop() == "pre-sub2"
3928        """
3929            )
3930        )
3931        sub2.join("test_2.py").write(
3932            textwrap.dedent(
3933                """\
3934            from .. import values
3935            def test_2(fix):
3936                assert values == ["pre-sub2"]
3937        """
3938            )
3939        )
3940        reprec = testdir.inline_run()
3941        reprec.assertoutcome(passed=2)
3942
3943
3944def test_call_fixture_function_error():
3945    """Check if an error is raised if a fixture function is called directly (#4545)"""
3946
3947    @pytest.fixture
3948    def fix():
3949        return 1
3950
3951    with pytest.raises(pytest.fail.Exception):
3952        assert fix() == 1
3953
3954
3955def test_fixture_param_shadowing(testdir):
3956    """Parametrized arguments would be shadowed if a fixture with the same name also exists (#5036)"""
3957    testdir.makepyfile(
3958        """
3959        import pytest
3960
3961        @pytest.fixture(params=['a', 'b'])
3962        def argroot(request):
3963            return request.param
3964
3965        @pytest.fixture
3966        def arg(argroot):
3967            return argroot
3968
3969        # This should only be parametrized directly
3970        @pytest.mark.parametrize("arg", [1])
3971        def test_direct(arg):
3972            assert arg == 1
3973
3974        # This should be parametrized based on the fixtures
3975        def test_normal_fixture(arg):
3976            assert isinstance(arg, str)
3977
3978        # Indirect should still work:
3979
3980        @pytest.fixture
3981        def arg2(request):
3982            return 2*request.param
3983
3984        @pytest.mark.parametrize("arg2", [1], indirect=True)
3985        def test_indirect(arg2):
3986            assert arg2 == 2
3987    """
3988    )
3989    # Only one test should have run
3990    result = testdir.runpytest("-v")
3991    result.assert_outcomes(passed=4)
3992    result.stdout.fnmatch_lines(["*::test_direct[[]1[]]*"])
3993    result.stdout.fnmatch_lines(["*::test_normal_fixture[[]a[]]*"])
3994    result.stdout.fnmatch_lines(["*::test_normal_fixture[[]b[]]*"])
3995    result.stdout.fnmatch_lines(["*::test_indirect[[]1[]]*"])
3996