示例#1
0
 def test_add_cleanup_with_known_deeper_layer2(self):
     my_cleanup = Mock(spec=cleanup_func)
     context = Context(runner=Mock())
     with scoped_context_layer(context, layer="feature"):
         with scoped_context_layer(context, layer="scenario"):
             context.add_cleanup(my_cleanup, layer="feature")
         my_cleanup.assert_not_called()
     # CALLS-HERE: context._pop()
     my_cleanup.assert_called_once()
    def test_cleanup_funcs_on_two_context_frames(self):
        call_listener = CallListener()
        my_cleanup_A1 = CleanupFunction("CLEANUP_A1", listener=call_listener)
        my_cleanup_A2 = CleanupFunction("CLEANUP_A2", listener=call_listener)
        my_cleanup_B1 = CleanupFunction("CLEANUP_B1", listener=call_listener)
        my_cleanup_B2 = CleanupFunction("CLEANUP_B2", listener=call_listener)
        my_cleanup_B3 = CleanupFunction("CLEANUP_B3", listener=call_listener)
        my_cleanup_A1M = Mock(side_effect=my_cleanup_A1)
        my_cleanup_A2M = Mock(side_effect=my_cleanup_A2)
        my_cleanup_B1M = Mock(side_effect=my_cleanup_B1)
        my_cleanup_B2M = Mock(side_effect=my_cleanup_B2)
        my_cleanup_B3M = Mock(side_effect=my_cleanup_B3)

        # -- SETUP:
        context = Context(runner=Mock())
        with scoped_context_layer(context):  # -- LAYER A:
            context.add_cleanup(my_cleanup_A1M)
            context.add_cleanup(my_cleanup_A2M)

            with scoped_context_layer(context):  # -- LAYER B:
                context.add_cleanup(my_cleanup_B1M)
                context.add_cleanup(my_cleanup_B2M)
                context.add_cleanup(my_cleanup_B3M)
                my_cleanup_B1M.assert_not_called()
                my_cleanup_B2M.assert_not_called()
                my_cleanup_B3M.assert_not_called()
            # -- context.pop(LAYER_B): Call cleanups for Bx
            expected_call_order = [
                "called:CLEANUP_B3",
                "called:CLEANUP_B2",
                "called:CLEANUP_B1",
            ]
            assert call_listener.collected == expected_call_order
            my_cleanup_A1M.assert_not_called()
            my_cleanup_A2M.assert_not_called()
            my_cleanup_B1M.assert_called_once()
            my_cleanup_B2M.assert_called_once()
            my_cleanup_B3M.assert_called_once()
        # -- context.pop(LAYER_A): Call cleanups for Ax
        expected_call_order = [
            "called:CLEANUP_B3",
            "called:CLEANUP_B2",
            "called:CLEANUP_B1",
            "called:CLEANUP_A2",
            "called:CLEANUP_A1",
        ]
        assert call_listener.collected == expected_call_order
        my_cleanup_A1M.assert_called_once()
        my_cleanup_A2M.assert_called_once()
        my_cleanup_B1M.assert_called_once()
        my_cleanup_B2M.assert_called_once()
        my_cleanup_B3M.assert_called_once()
示例#3
0
    def test_can_use_fixture_two_times(self):
        """Ensures that a fixture can be used multiple times 
        (with different names) within a context layer.
        """
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            fixture_object = FooFixture.setup(*args, **kwargs)
            setattr(context, fixture_object.name, fixture_object)
            checkpoints.append("foo.setup:%s" % fixture_object.name)
            yield fixture_object
            checkpoints.append("foo.cleanup:%s" % fixture_object.name)
            fixture_object.cleanup()

        checkpoints = []
        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture1 = use_fixture(foo, context, checkpoints, name="foo_1")
            the_fixture2 = use_fixture(foo, context, checkpoints, name="foo_2")
            # -- VERIFY: Fixture and context setup was performed.
            assert checkpoints == ["foo.setup:foo_1", "foo.setup:foo_2"]
            assert context.foo_1 is the_fixture1
            assert context.foo_2 is the_fixture2
            assert the_fixture1 is not the_fixture2

            checkpoints.append("scoped-block")

        # -- VERIFY: Fixture and context cleanup is performed.
        assert_context_cleanup(context, "foo_1")
        assert_context_cleanup(context, "foo_2")
        assert checkpoints == [
            "foo.setup:foo_1", "foo.setup:foo_2", "scoped-block",
            "foo.cleanup:foo_2", "foo.cleanup:foo_1"
        ]
示例#4
0
    def test_data_schema2(self):
        @fixture
        def foo(context, *args, **kwargs):
            # -- NOTE checkpoints: Injected from outer scope.
            params = "%r, %r" % (args, kwargs)
            checkpoints.append("foo.setup: %s" % params)
            yield "fixture.foo"
            checkpoints.append("foo.cleanup: %s" % params)

        fixture_registry = {
            "fixture.foo": fixture_call_params(foo, 1, 2, 3, name="foo_1")
        }

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with scoped_context_layer(context):
            use_fixture_by_tag("fixture.foo", context, fixture_registry)
            checkpoints.append("scoped-block")

        # -- VERIFY:
        assert checkpoints == [
            "foo.setup: (1, 2, 3), {'name': 'foo_1'}",
            "scoped-block",
            "foo.cleanup: (1, 2, 3), {'name': 'foo_1'}",
        ]
示例#5
0
    def test_data_schema2(self):
        @fixture
        def foo(context, *args, **kwargs):
            # -- NOTE checkpoints: Injected from outer scope.
            params = "%r, %r" % (args, kwargs)
            checkpoints.append("foo.setup: %s" % params)
            yield "fixture.foo"
            checkpoints.append("foo.cleanup: %s" % params)

        fixture_registry = {
            "fixture.foo": fixture_call_params(foo, 1, 2, 3, name="foo_1")
        }

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with scoped_context_layer(context):
            use_fixture_by_tag("fixture.foo", context, fixture_registry)
            checkpoints.append("scoped-block")

        # -- VERIFY:
        assert checkpoints == [
            "foo.setup: (1, 2, 3), {'name': 'foo_1'}",
            "scoped-block",
            "foo.cleanup: (1, 2, 3), {'name': 'foo_1'}",
        ]
示例#6
0
    def test_simplistic_composite_with_setup_error_skips_cleanup(self):
        def setup_bad_fixture_with_error(text):
            raise FixtureSetupError("OOPS")

        @fixture
        def sad_composite2(context, checkpoints, *args, **kwargs):
            checkpoints.append("foo.setup:_1")
            the_fixture1 = FooFixture.setup(*args, **kwargs)
            checkpoints.append("bad.setup_with_error")
            the_fixture2 = setup_bad_fixture_with_error(text="OOPS")
            checkpoints.append("bad.setup.done:NOT_REACHED")
            yield (the_fixture1, the_fixture2)
            checkpoints.append("foo.cleanup:_1:NOT_REACHED")

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(sad_composite2, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY:
        # * SAD: fixture1-cleanup is not called after fixture2-setup-error
        assert checkpoints == ["foo.setup:_1", "bad.setup_with_error"]
示例#7
0
    def test_invalid_data_schema_raises_value_error(self):
        @fixture
        def foo(context, *args, **kwargs):
            pass

        class BadFixtureData(object):
            def __init__(self, fixture_func, *args, **kwargs):
                self.fixture_func = fixture_func
                self.fixture_args = args
                self.fixture_kwargs = kwargs

        fixture_registry = {
            "fixture.foo": BadFixtureData(foo, 1, 2, 3, name="foo_1")
        }

        # -- PERFORM-TEST:
        context = make_runtime_context()
        with pytest.raises(ValueError) as exc_info:
            with scoped_context_layer(context):
                use_fixture_by_tag("fixture.foo", context, fixture_registry)

        # -- VERIFY:
        expected = "fixture_data: Expected tuple or fixture-func, but is:"
        assert expected in str(exc_info.value)
        assert "BadFixtureData object" in str(exc_info.value)
示例#8
0
    def test_invalid_data_schema_raises_value_error(self):
        @fixture
        def foo(context, *args, **kwargs):
            pass

        class BadFixtureData(object):
            def __init__(self, fixture_func, *args, **kwargs):
                self.fixture_func = fixture_func
                self.fixture_args = args
                self.fixture_kwargs = kwargs

        fixture_registry = {
            "fixture.foo": BadFixtureData(foo, 1, 2, 3, name="foo_1")
        }

        # -- PERFORM-TEST:
        context = make_runtime_context()
        with pytest.raises(ValueError) as exc_info:
            with scoped_context_layer(context):
                use_fixture_by_tag("fixture.foo", context, fixture_registry)

        # -- VERIFY:
        expected = "fixture_data: Expected tuple or fixture-func, but is:"
        assert expected in str(exc_info.value)
        assert "BadFixtureData object" in str(exc_info.value)
示例#9
0
    def test_bad_with_setup_and_cleanup_error(self):
        # -- GOOD: cleanup_fixture() part is called when setup-error occurs.
        # BUT: FixtureSetupError is hidden by FixtureCleanupError
        @fixture
        def bad_with_setup_and_cleanup_error(context, checkpoints, *args, **kwargs):
            def cleanup_bad_with_error():
                checkpoints.append("bad.cleanup_with_error")
                raise FixtureCleanupError()

            checkpoints.append("bad.setup_with_error")
            context.add_cleanup(cleanup_bad_with_error)
            raise FixtureSetupError()
            return FooFixture("NOT_REACHED")

        # -- PERFORM TEST:
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_setup_and_cleanup_error
        with pytest.raises(FixtureCleanupError) as exc_info:
            with scoped_context_layer(context):
                use_fixture(bad_fixture, context, checkpoints, name="BAD2")
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY: Ensure normal cleanup-parts were performed or tried.
        # OOPS: FixtureCleanupError in fixture-cleanup hides FixtureSetupError
        assert checkpoints == ["bad.setup_with_error", "bad.cleanup_with_error"]
        assert isinstance(exc_info.value, FixtureCleanupError), "LAST-EXCEPTION-WINS"
示例#10
0
    def test_use_composite_fixture_with_block_error(self):
        @fixture
        def fixture_foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "foo")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def composite2(context, checkpoints, *args, **kwargs):
            the_composite = use_composite_fixture_with(context, [
                fixture_call_params(fixture_foo, checkpoints, name="_1"),
                fixture_call_params(fixture_foo, checkpoints, name="_2"),
            ])
            return the_composite

        # -- PERFORM-TEST:
        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                use_fixture(composite2, context, checkpoints)
                checkpoints.append("scoped-block_with_error")
                raise RuntimeError("OOPS")
                checkpoints.append("scoped-block.done:NOT_REACHED")

        # -- ENSURES:
        # * fixture1-cleanup/cleanup is called even scoped-block-error
        # * fixture2-cleanup/cleanup is called even scoped-block-error
        # * fixture-cleanup occurs in reversed setup-order
        assert checkpoints == [
            "foo.setup:_1", "foo.setup:_2",
            "scoped-block_with_error",
            "foo.cleanup:_2", "foo.cleanup:_1"
        ]
示例#11
0
    def test_bad_with_cleanup_error_performs_all_cleanups(self):
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield FooFixture(*args, **kwargs)
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def bad_with_cleanup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup")
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup_with_error")
            raise FixtureCleanupError()
            checkpoints.append("bad.cleanup.done:NOT_REACHED")

        # -- PERFORM TEST:
        the_fixture1 = None
        the_fixture2 = None
        the_fixture3 = None
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_cleanup_error
        with pytest.raises(FixtureCleanupError):
            with scoped_context_layer(context):
                the_fixture1 = use_fixture(foo, context, checkpoints, name="foo_1")
                the_fixture2 = use_fixture(bad_fixture, context, checkpoints, name="BAD")
                the_fixture3 = use_fixture(foo, context, checkpoints, name="foo_3")
                checkpoints.append("scoped-block")

        # -- VERIFY: Tries to perform all cleanups even when cleanup-error(s) occur.
        assert checkpoints == [
            "foo.setup:foo_1", "bad.setup", "foo.setup:foo_3",
            "scoped-block",
            "foo.cleanup:foo_3", "bad.cleanup_with_error", "foo.cleanup:foo_1"]
示例#12
0
    def test_simplistic_composite_with_block_error_performs_cleanup(self):
        def setup_bad_fixture_with_error(text):
            raise FixtureSetupError("OOPS")

        @fixture
        def simplistic_composite2(context, checkpoints, *args, **kwargs):
            checkpoints.append("foo.setup:_1")
            the_fixture1 = FooFixture.setup(*args, name="_1")
            checkpoints.append("foo.setup:_2")
            the_fixture2 = FooFixture.setup(*args, name="_2")
            yield (the_fixture1, the_fixture2)
            checkpoints.append("foo.cleanup:_1")
            the_fixture1.cleanup()
            checkpoints.append("foo.cleanup:_2")
            the_fixture2.cleanup()

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                use_fixture(simplistic_composite2, context, checkpoints)
                checkpoints.append("scoped-block_with_error")
                raise RuntimeError("OOPS")
                checkpoints.append("scoped-block.end:NOT_REACHED")

        # -- VERIFY:
        # * fixture1-setup/cleanup is called when block-error occurs
        # * fixture2-setup/cleanup is called when block-error occurs
        # * fixture-cleanups occurs in specified composite-cleanup order
        assert checkpoints == [
            "foo.setup:_1", "foo.setup:_2",
            "scoped-block_with_error",
            "foo.cleanup:_1", "foo.cleanup:_2"
        ]
示例#13
0
    def test_on_cleanup_error__may_be_called_several_times_per_cleanup(self):
        def bad_cleanup1():
            raise RuntimeError("CLEANUP_1")

        def bad_cleanup2():
            raise RuntimeError("CLEANUP_2")

        class CleanupErrorCollector(object):
            def __init__(self):
                self.collected = []

            def __call__(self, context, cleanup_func, exception):
                self.collected.append((context, cleanup_func, exception))

        context = Context(runner=Mock())
        collect_cleanup_error = CleanupErrorCollector()
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                context.on_cleanup_error = collect_cleanup_error
                context.add_cleanup(bad_cleanup1)
                context.add_cleanup(bad_cleanup2)

        expected = [
            (context, bad_cleanup2, RuntimeError("CLEANUP_2")),
            (context, bad_cleanup1, RuntimeError("CLEANUP_1")),
        ]
        assert len(collect_cleanup_error.collected) == 2
        assert collect_cleanup_error.collected[0][:-1] == expected[0][:-1]
        assert collect_cleanup_error.collected[1][:-1] == expected[1][:-1]
示例#14
0
    def test_setup_error_with_context_cleanup2_then_cleanup_is_called(self):
        # -- CASE: Fixture is generator-function (contextmanager)
        # NOTE: Explicit use of context.add_cleanup()
        @fixture
        def foo(context, checkpoints, **kwargs):
            def cleanup_foo(arg=""):
                checkpoints.append("cleanup_foo:%s" % arg)

            checkpoints.append("foo.setup_with_error:foo_1")
            context.add_cleanup(cleanup_foo, "foo_1")
            raise FixtureSetupError("foo_1")
            checkpoints.append("foo.setup.done:NOT_REACHED")
            yield
            checkpoints.append("foo.cleanup:NOT_REACHED")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- ENSURE: cleanup_foo() is called
        assert checkpoints == [
            "foo.setup_with_error:foo_1", "cleanup_foo:foo_1"
        ]
示例#15
0
    def test_simplistic_composite_with_setup_error_skips_cleanup(self):
        def setup_bad_fixture_with_error(text):
            raise FixtureSetupError("OOPS")

        @fixture
        def sad_composite2(context, checkpoints, *args, **kwargs):
            checkpoints.append("foo.setup:_1")
            the_fixture1 = FooFixture.setup(*args, **kwargs)
            checkpoints.append("bad.setup_with_error")
            the_fixture2 = setup_bad_fixture_with_error(text="OOPS")
            checkpoints.append("bad.setup.done:NOT_REACHED")
            yield (the_fixture1, the_fixture2)
            checkpoints.append("foo.cleanup:_1:NOT_REACHED")

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(sad_composite2, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY:
        # * SAD: fixture1-cleanup is not called after fixture2-setup-error
        assert checkpoints == ["foo.setup:_1", "bad.setup_with_error"]
示例#16
0
    def test_simplistic_composite_with_block_error_performs_cleanup(self):
        def setup_bad_fixture_with_error(text):
            raise FixtureSetupError("OOPS")

        @fixture
        def simplistic_composite2(context, checkpoints, *args, **kwargs):
            checkpoints.append("foo.setup:_1")
            the_fixture1 = FooFixture.setup(*args, name="_1")
            checkpoints.append("foo.setup:_2")
            the_fixture2 = FooFixture.setup(*args, name="_2")
            yield (the_fixture1, the_fixture2)
            checkpoints.append("foo.cleanup:_1")
            the_fixture1.cleanup()
            checkpoints.append("foo.cleanup:_2")
            the_fixture2.cleanup()

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                use_fixture(simplistic_composite2, context, checkpoints)
                checkpoints.append("scoped-block_with_error")
                raise RuntimeError("OOPS")
                checkpoints.append("scoped-block.end:NOT_REACHED")

        # -- VERIFY:
        # * fixture1-setup/cleanup is called when block-error occurs
        # * fixture2-setup/cleanup is called when block-error occurs
        # * fixture-cleanups occurs in specified composite-cleanup order
        assert checkpoints == [
            "foo.setup:_1", "foo.setup:_2", "scoped-block_with_error",
            "foo.cleanup:_1", "foo.cleanup:_2"
        ]
示例#17
0
    def test_use_composite_fixture_with_block_error(self):
        @fixture
        def fixture_foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "foo")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def composite2(context, checkpoints, *args, **kwargs):
            the_composite = use_composite_fixture_with(context, [
                fixture_call_params(fixture_foo, checkpoints, name="_1"),
                fixture_call_params(fixture_foo, checkpoints, name="_2"),
            ])
            return the_composite

        # -- PERFORM-TEST:
        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                use_fixture(composite2, context, checkpoints)
                checkpoints.append("scoped-block_with_error")
                raise RuntimeError("OOPS")
                checkpoints.append("scoped-block.done:NOT_REACHED")

        # -- ENSURES:
        # * fixture1-cleanup/cleanup is called even scoped-block-error
        # * fixture2-cleanup/cleanup is called even scoped-block-error
        # * fixture-cleanup occurs in reversed setup-order
        assert checkpoints == [
            "foo.setup:_1", "foo.setup:_2", "scoped-block_with_error",
            "foo.cleanup:_2", "foo.cleanup:_1"
        ]
示例#18
0
    def test_use_composite_fixture(self):
        @fixture
        def fixture_foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "foo")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def composite2(context, checkpoints, *args, **kwargs):
            the_composite = use_composite_fixture_with(context, [
                fixture_call_params(fixture_foo, checkpoints, name="_1"),
                fixture_call_params(fixture_foo, checkpoints, name="_2"),
            ])
            return the_composite

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with scoped_context_layer(context):
            use_fixture(composite2, context, checkpoints)
            checkpoints.append("scoped-block")

        assert checkpoints == [
            "foo.setup:_1",
            "foo.setup:_2",
            "scoped-block",
            "foo.cleanup:_2",
            "foo.cleanup:_1",
        ]
示例#19
0
    def test_use_composite_fixture(self):
        @fixture
        def fixture_foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "foo")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def composite2(context, checkpoints, *args, **kwargs):
            the_composite = use_composite_fixture_with(context, [
                fixture_call_params(fixture_foo, checkpoints, name="_1"),
                fixture_call_params(fixture_foo, checkpoints, name="_2"),
            ])
            return the_composite

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with scoped_context_layer(context):
            use_fixture(composite2, context, checkpoints)
            checkpoints.append("scoped-block")

        assert checkpoints == [
            "foo.setup:_1", "foo.setup:_2",
            "scoped-block",
            "foo.cleanup:_2", "foo.cleanup:_1",
        ]
示例#20
0
    def test_can_use_fixture_two_times(self):
        """Ensures that a fixture can be used multiple times 
        (with different names) within a context layer.
        """
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            fixture_object = FooFixture.setup(*args, **kwargs)
            setattr(context, fixture_object.name, fixture_object)
            checkpoints.append("foo.setup:%s" % fixture_object.name)
            yield fixture_object
            checkpoints.append("foo.cleanup:%s" % fixture_object.name)
            fixture_object.cleanup()

        checkpoints = []
        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture1 = use_fixture(foo, context, checkpoints, name="foo_1")
            the_fixture2 = use_fixture(foo, context, checkpoints, name="foo_2")
            # -- VERIFY: Fixture and context setup was performed.
            assert checkpoints == ["foo.setup:foo_1", "foo.setup:foo_2"]
            assert context.foo_1 is the_fixture1
            assert context.foo_2 is the_fixture2
            assert the_fixture1 is not the_fixture2

            checkpoints.append("scoped-block")

        # -- VERIFY: Fixture and context cleanup is performed.
        assert_context_cleanup(context, "foo_1")
        assert_context_cleanup(context, "foo_2")
        assert checkpoints == ["foo.setup:foo_1",   "foo.setup:foo_2",
                               "scoped-block",
                               "foo.cleanup:foo_2", "foo.cleanup:foo_1"]
示例#21
0
    def test_bad_with_setup_and_cleanup_error(self):
        # -- GOOD: cleanup_fixture() part is called when setup-error occurs.
        # BUT: FixtureSetupError is hidden by FixtureCleanupError
        @fixture
        def bad_with_setup_and_cleanup_error(context, checkpoints, *args,
                                             **kwargs):
            def cleanup_bad_with_error():
                checkpoints.append("bad.cleanup_with_error")
                raise FixtureCleanupError()

            checkpoints.append("bad.setup_with_error")
            context.add_cleanup(cleanup_bad_with_error)
            raise FixtureSetupError()
            return FooFixture("NOT_REACHED")

        # -- PERFORM TEST:
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_setup_and_cleanup_error
        with pytest.raises(FixtureCleanupError) as exc_info:
            with scoped_context_layer(context):
                use_fixture(bad_fixture, context, checkpoints, name="BAD2")
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY: Ensure normal cleanup-parts were performed or tried.
        # OOPS: FixtureCleanupError in fixture-cleanup hides FixtureSetupError
        assert checkpoints == [
            "bad.setup_with_error", "bad.cleanup_with_error"
        ]
        assert isinstance(exc_info.value,
                          FixtureCleanupError), "LAST-EXCEPTION-WINS"
示例#22
0
    def test_bad_with_setup_error_aborts_on_first_error(self):
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield FooFixture(*args, **kwargs)
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def bad_with_setup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup_with_error")
            raise FixtureSetupError()
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup:NOT_REACHED")

        # -- PERFORM-TEST:
        the_fixture1 = None
        the_fixture2 = None
        the_fixture3 = None
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_setup_error
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                the_fixture1 = use_fixture(foo, context, checkpoints, name="foo_1")
                the_fixture2 = use_fixture(bad_fixture, context, checkpoints, name="BAD")
                the_fixture3 = use_fixture(foo, context, checkpoints, name="NOT_REACHED")
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY: Ensure cleanup-parts were performed until failure-point.
        assert isinstance(the_fixture1, FooFixture)
        assert the_fixture2 is None     # -- NEVER-STORED:  Due to setup error.
        assert the_fixture3 is None     # -- NEVER-CREATED: Due to bad_fixture.
        assert checkpoints == [
            "foo.setup:foo_1", "bad.setup_with_error", "foo.cleanup:foo_1"]
示例#23
0
def test_issue__getattr_with_protected_unknown_context_attribute_raises_no_error(
):
    context = Context(runner=Mock())
    with scoped_context_layer(context):  # CALLS-HERE: context._push()
        value = getattr(context, "_UNKNOWN_ATTRIB", "__UNKNOWN__")

    assert value == "__UNKNOWN__"
示例#24
0
 def test_add_cleanup_with_known_layer_and_kwargs(self):
     my_cleanup = Mock(spec=cleanup_func_with_args)
     context = Context(runner=Mock())
     with scoped_context_layer(context, layer="scenario"):
         context.add_cleanup(my_cleanup, layer="scenario", name="alice")
         my_cleanup.assert_not_called()
     # CALLS-HERE: context._pop()
     my_cleanup.assert_called_once_with(name="alice")
示例#25
0
 def test_add_cleanup_with_args(self):
     my_cleanup = Mock(spec=cleanup_func_with_args)
     context = Context(runner=Mock())
     with scoped_context_layer(context):
         context.add_cleanup(my_cleanup, 1, 2, 3)
         my_cleanup.assert_not_called()
     # CALLS-HERE: context._pop()
     my_cleanup.assert_called_once_with(1, 2, 3)
示例#26
0
 def test_add_cleanup_with_unknown_layer_raises_lookup_error(self):
     """Cleanup function is not registered"""
     my_cleanup = Mock(spec=cleanup_func)
     context = Context(runner=Mock())
     with scoped_context_layer(context):  # CALLS-HERE: context._push()
         with pytest.raises(LookupError) as error:
             context.add_cleanup(my_cleanup, layer="other")
     my_cleanup.assert_not_called()
示例#27
0
 def test_cleanup_func_is_called_when_context_frame_is_popped(self):
     my_cleanup = Mock(spec=cleanup_func)
     context = Context(runner=Mock())
     with scoped_context_layer(context):  # CALLS-HERE: context._push()
         context.add_cleanup(my_cleanup)
         # -- ENSURE: Not called before context._pop()
         my_cleanup.assert_not_called()
     # CALLS-HERE: context._pop()
     my_cleanup.assert_called_once()
示例#28
0
    def test_add_cleanup__rejects_noncallable_cleanup_func(self):
        class NonCallable(object):
            pass

        non_callable = NonCallable()
        context = Context(runner=Mock())

        with pytest.raises(AssertionError) as e:
            with scoped_context_layer(context):
                context.add_cleanup(non_callable)
        assert "REQUIRES: callable(cleanup_func)" in str(e.value)
示例#29
0
    def test_unknown_fixture_raises_lookup_error(self):
        fixture_registry = {}

        # -- PERFORM-TEST:
        context = make_runtime_context()
        with pytest.raises(LookupError) as exc_info:
            with scoped_context_layer(context):
                use_fixture_by_tag("UNKNOWN_FIXTURE", context, fixture_registry)

        # -- VERIFY:
        assert "Unknown fixture-tag: UNKNOWN_FIXTURE" in str(exc_info.value)
示例#30
0
    def test_unknown_fixture_raises_lookup_error(self):
        fixture_registry = {}

        # -- PERFORM-TEST:
        context = make_runtime_context()
        with pytest.raises(LookupError) as exc_info:
            with scoped_context_layer(context):
                use_fixture_by_tag("UNKNOWN_FIXTURE", context,
                                   fixture_registry)

        # -- VERIFY:
        assert "Unknown fixture-tag: UNKNOWN_FIXTURE" in str(exc_info.value)
示例#31
0
 def cleanup_steps():
     logger.info(f'Teardown running for {name}')
     for scenario in setup_scenarios['teardown']:
         if any(
                 tag.startswith('fixture.browser')
                 for tag in scenario.tags):
             with scoped_context_layer(context,
                                       layer_name='setup_teardown'):
                 run_scenario(context, scenario)
         else:
             run_scenario(context, scenario)
     for scenario in setup_scenarios['setup']:
         scenario.reset()
示例#32
0
    def test_fixture_with_kwargs(self):
        """Ensures that keyword args are passed to fixture function."""
        @fixture
        def bar(context, *args, **kwargs):
            fixture_object = BarFixture.setup(*args, **kwargs)
            context.bar = fixture_object
            return fixture_object

        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(bar, context, name="bar", timeout=10)

        expected_kwargs = dict(name="bar", timeout=10)
        assert the_fixture.kwargs == expected_kwargs
示例#33
0
    def test_fixture_with_kwargs(self):
        """Ensures that keyword args are passed to fixture function."""
        @fixture
        def bar(context, *args, **kwargs):
            fixture_object = BarFixture.setup(*args, **kwargs)
            context.bar = fixture_object
            return fixture_object

        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(bar, context, name="bar", timeout=10)

        expected_kwargs = dict(name="bar", timeout=10)
        assert the_fixture.kwargs == expected_kwargs
示例#34
0
    def test_fixture_with_args(self):
        """Ensures that positional args are passed to fixture function."""
        @fixture
        def foo(context, *args, **kwargs):
            fixture_object = FooFixture.setup(*args, **kwargs)
            context.foo = fixture_object
            yield fixture_object
            fixture_object.cleanup()

        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(foo, context, 1, 2, 3)

        expected_args = (1, 2, 3)
        assert the_fixture.args == expected_args
示例#35
0
    def test_fixture_with_args(self):
        """Ensures that positional args are passed to fixture function."""
        @fixture
        def foo(context, *args, **kwargs):
            fixture_object = FooFixture.setup(*args, **kwargs)
            context.foo = fixture_object
            yield fixture_object
            fixture_object.cleanup()

        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(foo, context, 1, 2, 3)

        expected_args = (1, 2, 3)
        assert the_fixture.args == expected_args
示例#36
0
    def test_on_cleanup_error__is_called_if_defined(self):
        def bad_cleanup():
            raise RuntimeError("in CLEANUP call")

        def handle_cleanup_error(context, cleanup_func, exception):
            print("CALLED: handle_cleanup_error")

        context = Context(runner=Mock())
        handle_cleanup_error_func = Mock(spec=handle_cleanup_error)
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                context.on_cleanup_error = handle_cleanup_error_func
                context.add_cleanup(bad_cleanup)

        handle_cleanup_error_func.assert_called_once()
示例#37
0
    def test_cleanup_funcs_are_called_when_context_frame_is_popped(self):
        my_cleanup1 = Mock(spec=cleanup_func)
        my_cleanup2 = Mock(spec=cleanup_func)

        # -- SETUP:
        context = Context(runner=Mock())
        with scoped_context_layer(context):
            context.add_cleanup(my_cleanup1)
            context.add_cleanup(my_cleanup2)

            # -- ENSURE: Not called before context._pop()
            my_cleanup1.assert_not_called()
            my_cleanup2.assert_not_called()
        # -- CALLS-HERE: context._pop()
        my_cleanup1.assert_called_once()
        my_cleanup2.assert_called_once()
示例#38
0
def setup_teardown(context, name, set_teardown=False, teardown_only=False):
    """
    Based on a tag request (e.g. - @fixture.setup.{name}), run the steps of the
    @configure.{name} setup feature if the setup feature has not been previously
    run. Adds a cleanup step after the feature/scenario if set_teardown is True
    """
    setup_scenarios = context.context_setup.get(name, None)

    if not setup_scenarios:
        logger.error(
            f'Setup Teardown was requested, but no context feature named {name} was found'
        )
        return

    logger.info(f'Setup running for {name}')

    if not teardown_only:
        for scenario in setup_scenarios['setup']:
            if scenario.should_run():
                if any(
                        tag.startswith('fixture.browser')
                        for tag in scenario.tags):
                    with scoped_context_layer(context,
                                              layer_name='setup_teardown'):
                        run_scenario(context, scenario)
                else:
                    run_scenario(context, scenario)
                scenario.skip()

    if set_teardown:

        def cleanup_steps():
            logger.info(f'Teardown running for {name}')
            for scenario in setup_scenarios['teardown']:
                if any(
                        tag.startswith('fixture.browser')
                        for tag in scenario.tags):
                    with scoped_context_layer(context,
                                              layer_name='setup_teardown'):
                        run_scenario(context, scenario)
                else:
                    run_scenario(context, scenario)
            for scenario in setup_scenarios['setup']:
                scenario.reset()

        context.add_cleanup(cleanup_steps)
    return
示例#39
0
    def test_on_cleanup_error__prints_error_by_default(self, capsys):
        def bad_cleanup_func():
            raise RuntimeError("in CLEANUP call")

        bad_cleanup = Mock(side_effect=bad_cleanup_func)

        context = Context(runner=Mock())
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                context.add_cleanup(bad_cleanup)

        captured_output, _ = capsys.readouterr()
        bad_cleanup.assert_called()
        assert "CLEANUP-ERROR in " in captured_output
        assert "RuntimeError: in CLEANUP call" in captured_output
        # -- FOR DIAGNOSTICS:
        print(captured_output)
示例#40
0
    def test_use_fixture_with_setup_error(self):
        @fixture
        def fixture_foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "foo")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def bad_with_setup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup_with_error")
            raise FixtureSetupError("OOPS")
            yield
            checkpoints.append("bad.cleanup:NOT_REACHED")

        @fixture
        def composite3(context, checkpoints, *args, **kwargs):
            bad_fixture = bad_with_setup_error
            the_fixture1 = use_fixture(fixture_foo,
                                       context,
                                       checkpoints,
                                       name="_1")
            the_fixture2 = use_fixture(bad_fixture,
                                       context,
                                       checkpoints,
                                       name="OOPS")
            the_fixture3 = use_fixture(fixture_foo,
                                       context,
                                       checkpoints,
                                       name="_3:NOT_REACHED")
            return (the_fixture1, the_fixture2, the_fixture3)  # NOT_REACHED

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(composite3, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- ENSURES:
        # * fixture1-cleanup is called even after fixture2-setup-error
        # * fixture3-setup/cleanup are not called due to fixture2-setup-error
        assert checkpoints == [
            "foo.setup:_1", "bad.setup_with_error", "foo.cleanup:_1"
        ]
示例#41
0
    def test_bad_with_setup_error_aborts_on_first_error(self):
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield FooFixture(*args, **kwargs)
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def bad_with_setup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup_with_error")
            raise FixtureSetupError()
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup:NOT_REACHED")

        # -- PERFORM-TEST:
        the_fixture1 = None
        the_fixture2 = None
        the_fixture3 = None
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_setup_error
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                the_fixture1 = use_fixture(foo,
                                           context,
                                           checkpoints,
                                           name="foo_1")
                the_fixture2 = use_fixture(bad_fixture,
                                           context,
                                           checkpoints,
                                           name="BAD")
                the_fixture3 = use_fixture(foo,
                                           context,
                                           checkpoints,
                                           name="NOT_REACHED")
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY: Ensure cleanup-parts were performed until failure-point.
        assert isinstance(the_fixture1, FooFixture)
        assert the_fixture2 is None  # -- NEVER-STORED:  Due to setup error.
        assert the_fixture3 is None  # -- NEVER-CREATED: Due to bad_fixture.
        assert checkpoints == [
            "foo.setup:foo_1", "bad.setup_with_error", "foo.cleanup:foo_1"
        ]
示例#42
0
    def test_setup_eror_with_plaingen_then_cleanup_is_not_called(self):
        # -- CASE: Fixture is generator-function
        @fixture
        def foo(context, checkpoints):
            checkpoints.append("foo.setup.begin")
            raise FixtureSetupError("foo")
            checkpoints.append("foo.setup.done:NOT_REACHED")
            yield
            checkpoints.append("foo.cleanup:NOT_REACHED")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        assert checkpoints == ["foo.setup.begin"]
示例#43
0
    def test_setup_eror_with_plaingen_then_cleanup_is_not_called(self):
        # -- CASE: Fixture is generator-function
        @fixture
        def foo(context, checkpoints):
            checkpoints.append("foo.setup.begin")
            raise FixtureSetupError("foo")
            checkpoints.append("foo.setup.done:NOT_REACHED")
            yield
            checkpoints.append("foo.cleanup:NOT_REACHED")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        assert checkpoints == ["foo.setup.begin"]
示例#44
0
    def test_bad_with_cleanup_error_performs_all_cleanups(self):
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield FooFixture(*args, **kwargs)
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def bad_with_cleanup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup")
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup_with_error")
            raise FixtureCleanupError()
            checkpoints.append("bad.cleanup.done:NOT_REACHED")

        # -- PERFORM TEST:
        the_fixture1 = None
        the_fixture2 = None
        the_fixture3 = None
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_cleanup_error
        with pytest.raises(FixtureCleanupError):
            with scoped_context_layer(context):
                the_fixture1 = use_fixture(foo,
                                           context,
                                           checkpoints,
                                           name="foo_1")
                the_fixture2 = use_fixture(bad_fixture,
                                           context,
                                           checkpoints,
                                           name="BAD")
                the_fixture3 = use_fixture(foo,
                                           context,
                                           checkpoints,
                                           name="foo_3")
                checkpoints.append("scoped-block")

        # -- VERIFY: Tries to perform all cleanups even when cleanup-error(s) occur.
        assert checkpoints == [
            "foo.setup:foo_1", "bad.setup", "foo.setup:foo_3", "scoped-block",
            "foo.cleanup:foo_3", "bad.cleanup_with_error", "foo.cleanup:foo_1"
        ]
示例#45
0
    def test_with_function(self):
        @fixture
        def bar(context, checkpoints, *args, **kwargs):
            checkpoints.append("bar.setup")
            fixture_object = BarFixture.setup(*args, **kwargs)
            context.bar = fixture_object
            return fixture_object

        checkpoints = []
        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(bar, context, checkpoints)
            assert_context_setup(context, "bar", BarFixture)
            assert_fixture_setup_called(the_fixture)
            assert_fixture_cleanup_not_called(the_fixture)
            assert checkpoints == ["bar.setup"]
            print("Do something...")
        assert_context_cleanup(context, "foo")
        assert_fixture_cleanup_not_called(the_fixture)
示例#46
0
    def test_bad_with_cleanup_error(self):
        @fixture
        def bad_with_cleanup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup")
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup_with_error")
            raise FixtureCleanupError()

        # -- PERFORM TEST:
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_cleanup_error
        with pytest.raises(FixtureCleanupError):
            with scoped_context_layer(context):
                use_fixture(bad_fixture, context, checkpoints)
                checkpoints.append("scoped-block")

        # -- VERIFY: Ensure normal cleanup-parts were performed or tried.
        assert checkpoints == ["bad.setup", "scoped-block", "bad.cleanup_with_error"]
示例#47
0
    def test_basic_lifecycle(self):
        # -- NOTE: Use explicit checks instead of assert-helper functions.
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            checkpoints.append("foo.setup")
            yield FooFixture()
            checkpoints.append("foo.cleanup")

        checkpoints = []
        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(foo, context, checkpoints)
            # -- ENSURE: Fixture setup is performed (and as expected)
            assert isinstance(the_fixture, FooFixture)
            assert checkpoints == ["foo.setup"]
            checkpoints.append("scoped-block")

        # -- ENSURE: Fixture cleanup was performed
        assert checkpoints == ["foo.setup", "scoped-block", "foo.cleanup"]
示例#48
0
    def test_block_eror_with_plaingen_then_cleanup_is_called(self):
        # -- CASE: Fixture is generator-function
        @fixture
        def foo(context, checkpoints):
            checkpoints.append("foo.setup")
            yield
            checkpoints.append("foo.cleanup")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                checkpoints.append("scoped-block_with_error")
                raise RuntimeError("scoped-block")
                checkpoints.append("NOT_REACHED")

        # -- ENSURE:
        assert checkpoints == [
            "foo.setup", "scoped-block_with_error", "foo.cleanup"
        ]
示例#49
0
    def test_setup_error_with_context_cleanup1_then_cleanup_is_called(self):
        # -- CASE: Fixture is normal function
        @fixture
        def foo(context, checkpoints):
            def cleanup_foo(arg=""):
                checkpoints.append("cleanup_foo:%s" % arg)

            checkpoints.append("foo.setup_with_error:foo_1")
            context.add_cleanup(cleanup_foo, "foo_1")
            raise FixtureSetupError("foo")
            checkpoints.append("foo.setup.done:NOT_REACHED")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- ENSURE: cleanup_foo() is called (LATE-CLEANUP on scope-exit)
        assert checkpoints == ["foo.setup_with_error:foo_1", "cleanup_foo:foo_1"]
示例#50
0
    def test_with_generator_function(self):
        @fixture
        def foo(context, checkpoints, *args, **kwargs):
            checkpoints.append("foo.setup")
            fixture_object = FooFixture.setup(*args, **kwargs)
            context.foo = fixture_object
            yield fixture_object
            fixture_object.cleanup()
            checkpoints.append("foo.cleanup.done")

        checkpoints = []
        context = make_runtime_context()
        with scoped_context_layer(context):
            the_fixture = use_fixture(foo, context, checkpoints)
            assert_context_setup(context, "foo", FooFixture)
            assert_fixture_setup_called(the_fixture)
            assert_fixture_cleanup_not_called(the_fixture)
            assert checkpoints == ["foo.setup"]
            print("Do something...")
        assert_context_cleanup(context, "foo")
        assert_fixture_cleanup_called(the_fixture)
        assert checkpoints == ["foo.setup", "foo.cleanup.done"]
示例#51
0
    def test_invalid_fixture_function(self):
        """Test invalid generator function with more than one yield-statement
        (not a valid fixture/context-manager).
        """
        @fixture
        def invalid_fixture(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup")
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup")
            yield None  # -- SYNDROME HERE: More than one yield-statement

        # -- PERFORM-TEST:
        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(InvalidFixtureError):
            with scoped_context_layer(context):
                the_fixture = use_fixture(invalid_fixture, context, checkpoints)
                assert checkpoints == ["bad.setup"]
                checkpoints.append("scoped-block")

        # -- VERIFY: Ensure normal cleanup-parts were performed.
        assert checkpoints == ["bad.setup", "scoped-block", "bad.cleanup"]
示例#52
0
    def test_use_composite_fixture_with_setup_error(self):
        @fixture
        def fixture_foo(context, checkpoints, *args, **kwargs):
            fixture_name = kwargs.get("name", "foo")
            checkpoints.append("foo.setup:%s" % fixture_name)
            yield
            checkpoints.append("foo.cleanup:%s" % fixture_name)

        @fixture
        def bad_with_setup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup_with_error")
            raise FixtureSetupError("OOPS")
            yield
            checkpoints.append("bad.cleanup:NOT_REACHED")

        @fixture
        def composite3(context, checkpoints, *args, **kwargs):
            bad_fixture = bad_with_setup_error
            the_composite = use_composite_fixture_with(context, [
                fixture_call_params(fixture_foo, checkpoints, name="_1"),
                fixture_call_params(bad_fixture, checkpoints, name="OOPS"),
                fixture_call_params(fixture_foo, checkpoints, name="_3:NOT_REACHED"),
            ])
            return the_composite

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(composite3, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- ENSURES:
        # * fixture1-cleanup is called even after fixture2-setup-error
        # * fixture3-setup/cleanup are not called due to fixture2-setup-error
        assert checkpoints == [
            "foo.setup:_1", "bad.setup_with_error", "foo.cleanup:_1"
        ]
示例#53
0
    def test_setup_eror_with_finallygen_then_cleanup_is_called(self):
        # -- CASE: Fixture is generator-function
        @fixture
        def foo(context, checkpoints):
            try:
                checkpoints.append("foo.setup.begin")
                raise FixtureSetupError("foo")
                checkpoints.append("foo.setup.done:NOT_REACHED")
                yield
                checkpoints.append("foo.cleanup:NOT_REACHED")
            finally:
                checkpoints.append("foo.cleanup.finally")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                # -- NEVER-REACHED:
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- ENSURE: fixture-cleanup (foo.cleanup) is called (EARLY-CLEANUP).
        assert checkpoints == ["foo.setup.begin", "foo.cleanup.finally"]
示例#54
0
    def test_block_eror_with_context_cleanup_then_cleanup_is_called(self):
        # -- CASE: Fixture is normal-function
        @fixture
        def bar(context, checkpoints):
            def cleanup_bar():
                checkpoints.append("cleanup_bar")

            checkpoints.append("bar.setup")
            context.add_cleanup(cleanup_bar)

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(RuntimeError):
            with scoped_context_layer(context):
                use_fixture(bar, context, checkpoints)
                checkpoints.append("scoped-block_with_error")
                raise RuntimeError("scoped-block")
                checkpoints.append("NOT_REACHED")

        # -- ENSURE:
        assert checkpoints == [
            "bar.setup", "scoped-block_with_error", "cleanup_bar"
        ]
示例#55
0
    def test_data_schema1(self):
        @fixture
        def foo(context, *args, **kwargs):
            # -- NOTE checkpoints: Injected from outer scope.
            checkpoints.append("foo.setup")
            yield "fixture:foo"
            checkpoints.append("foo.cleanup")

        fixture_registry = {
            "fixture.foo": foo,
        }

        # -- PERFORM-TEST:
        context = make_runtime_context()
        checkpoints = []
        with scoped_context_layer(context):
            use_fixture_by_tag("fixture.foo", context, fixture_registry)
            checkpoints.append("scoped-block")

        # -- VERIFY:
        assert checkpoints == [
            "foo.setup", "scoped-block", "foo.cleanup"
        ]
示例#56
0
    def test_bad_with_setup_error(self):
        # -- SAD: cleanup_fixture() part is called when setup-error occurs,
        #    but not the cleanup-part of the generator (generator-magic).
        @fixture
        def bad_with_setup_error(context, checkpoints, *args, **kwargs):
            checkpoints.append("bad.setup_with_error")
            raise FixtureSetupError()
            yield FooFixture(*args, **kwargs)
            checkpoints.append("bad.cleanup:NOT_REACHED")

        # -- PERFORM-TEST:
        the_fixture = None
        checkpoints = []
        context = make_runtime_context()
        bad_fixture = bad_with_setup_error
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                the_fixture = use_fixture(bad_fixture, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- VERIFY: Ensure normal cleanup-parts were performed.
        # * SAD: fixture-cleanup is not called due to fixture-setup error.
        assert the_fixture is None  # -- NEVER STORED: Due to setup error.
        assert checkpoints == ["bad.setup_with_error"]
示例#57
0
    def test_setup_error_with_context_cleanup2_then_cleanup_is_called(self):
        # -- CASE: Fixture is generator-function (contextmanager)
        # NOTE: Explicit use of context.add_cleanup()
        @fixture
        def foo(context, checkpoints, **kwargs):
            def cleanup_foo(arg=""):
                checkpoints.append("cleanup_foo:%s" % arg)

            checkpoints.append("foo.setup_with_error:foo_1")
            context.add_cleanup(cleanup_foo, "foo_1")
            raise FixtureSetupError("foo_1")
            checkpoints.append("foo.setup.done:NOT_REACHED")
            yield
            checkpoints.append("foo.cleanup:NOT_REACHED")

        checkpoints = []
        context = make_runtime_context()
        with pytest.raises(FixtureSetupError):
            with scoped_context_layer(context):
                use_fixture(foo, context, checkpoints)
                checkpoints.append("scoped-block:NOT_REACHED")

        # -- ENSURE: cleanup_foo() is called
        assert checkpoints == ["foo.setup_with_error:foo_1", "cleanup_foo:foo_1"]
示例#58
0
def test_issue__getattr_with_protected_unknown_context_attribute_raises_no_error():
    context = Context(runner=Mock())
    with scoped_context_layer(context):  # CALLS-HERE: context._push()
        value = getattr(context, "_UNKNOWN_ATTRIB", "__UNKNOWN__")

    assert value == "__UNKNOWN__"