Beispiel #1
0
    def _get_test_fmt_vars(self, test_spec):
        """Get any format variables that can be inferred for the test at this point

        Args:
            test_spec (dict): Test specification, possibly with included config files

        Returns:
            dict: available format variables
        """
        # Get included variables so we can do things like:
        # skipif: {my_integer} > 2
        # skipif: 'https' in '{hostname}'
        # skipif: '{hostname}'.contains('ignoreme')
        fmt_vars = {}

        global_cfg = load_global_cfg(self.config)
        fmt_vars.update(**global_cfg.get("variables", {}))

        included = test_spec.get("includes", [])
        for i in included:
            fmt_vars.update(**i.get("variables", {}))

        # Needed if something in a config file uses tavern.env_vars
        tavern_box = get_tavern_box()

        try:
            fmt_vars = _format_without_inner(fmt_vars, tavern_box)
        except exceptions.MissingFormatError as e:
            # eg, if we have {tavern.env_vars.DOESNT_EXIST}
            msg = "Tried to use tavern format variable that did not exist"
            raise exceptions.MissingFormatError(msg) from e

        tavern_box.merge_update(**fmt_vars)
        return tavern_box
Beispiel #2
0
def _format_test_marks(original_marks, fmt_vars, test_name):
    """Given the 'raw' marks from the test and any available format variables,
    generate new  marks for this test

    Args:
        original_marks (list): Raw string from test - should correspond to either a
            pytest builtin mark or a custom user mark
        fmt_vars (dict): dictionary containing available format variables
        test_name (str): Name of test (for error logging)

    Returns:
        tuple: first element is normal pytest mark objects, second element is all
            marks which were formatted (no matter their content)

    Todo:
        Fix doctests below - failing due to missing pytest markers

    Example:

        # >>> _format_test_marks([], {}, 'abc')
        # ([], [])
        # >>> _format_test_marks(['tavernmarker'], {}, 'abc')
        # (['tavernmarker'], [])
        # >>> _format_test_marks(['{formatme}'], {'formatme': 'tavernmarker'}, 'abc')
        # (['tavernmarker'], [])
        # >>> _format_test_marks([{'skipif': '{skiptest}'}], {'skiptest': true}, 'abc')
        # (['tavernmarker'], [])

    """

    pytest_marks = []
    formatted_marks = []

    for m in original_marks:
        if isinstance(m, str):
            # a normal mark
            m = _format_without_inner(m, fmt_vars)
            pytest_marks.append(getattr(pytest.mark, m))
        elif isinstance(m, dict):
            # skipif or parametrize (for now)
            for markname, extra_arg in m.items():
                # NOTE
                # cannot do 'skipif' and rely on a parametrized
                # argument.
                try:
                    extra_arg = _format_without_inner(extra_arg, fmt_vars)
                except exceptions.MissingFormatError as e:
                    msg = "Tried to use mark '{}' (with value '{}') in test '{}' but one or more format variables was not in any configuration file used by the test".format(
                        markname, extra_arg, test_name
                    )
                    # NOTE
                    # we could continue and let it fail in the test, but
                    # this gives a better indication of what actually
                    # happened (even if it is difficult to test)
                    raise exceptions.MissingFormatError(msg) from e
                else:
                    pytest_marks.append(getattr(pytest.mark, markname)(extra_arg))
                    formatted_marks.append({markname: extra_arg})
        else:
            raise exceptions.BadSchemaError("Unexpected mark type '{}'".format(type(m)))

    return pytest_marks, formatted_marks
Beispiel #3
0
    def _generate_items(self, test_spec):
        """Modify or generate tests based on test spec

        If there are any 'parametrize' marks, this will generate extra tests
        based on the values

        Args:
            test_spec (dict): Test specification

        Yields:
            YamlItem: Tavern YAML test
        """
        item = YamlItem(test_spec["test_name"], self, test_spec, self.fspath)

        original_marks = test_spec.get("marks", [])

        if original_marks:
            fmt_vars = self._get_test_fmt_vars(test_spec)
            pytest_marks = []
            formatted_marks = []

            for m in original_marks:
                if isinstance(m, str):
                    # a normal mark
                    m = format_keys(m, fmt_vars)
                    pytest_marks.append(getattr(pytest.mark, m))
                elif isinstance(m, dict):
                    # skipif or parametrize (for now)
                    for markname, extra_arg in m.items():
                        # NOTE
                        # cannot do 'skipif' and rely on a parametrized
                        # argument.
                        try:
                            extra_arg = format_keys(extra_arg, fmt_vars)
                        except exceptions.MissingFormatError as e:
                            msg = "Tried to use mark '{}' (with value '{}') in test '{}' but one or more format variables was not in any configuration file used by the test".format(
                                markname, extra_arg, test_spec["test_name"]
                            )
                            # NOTE
                            # we could continue and let it fail in the test, but
                            # this gives a better indication of what actually
                            # happened (even if it is difficult to test)
                            raise_from(exceptions.MissingFormatError(msg), e)
                        else:
                            pytest_marks.append(
                                getattr(pytest.mark, markname)(extra_arg)
                            )
                            formatted_marks.append({markname: extra_arg})

            # Do this after we've added all the other marks so doing
            # things like selecting on mark names still works even
            # after parametrization
            parametrize_marks = [
                i for i in formatted_marks if isinstance(i, dict) and "parametrize" in i
            ]
            if parametrize_marks:
                # no 'yield from' in python 2...
                for new_item in self.get_parametrized_items(
                    test_spec, parametrize_marks, pytest_marks
                ):
                    yield new_item

                # Only yield the parametrized ones
                return

            item.add_markers(pytest_marks)

        yield item