コード例 #1
0
ファイル: plain.py プロジェクト: yazbekludmila/FRETEBRAS
 def scenario(self, scenario):
     self.reset_steps()
     self.stream.write(u"\n")
     indent = make_indentation(self.indent_size)
     text = u"%s%s: %s\n" % (indent, scenario.keyword, scenario.name)
     self.write_tags(scenario.tags, indent)
     self.stream.write(text)
コード例 #2
0
ファイル: plain.py プロジェクト: yazbekludmila/FRETEBRAS
 def multiline_indentation(self):
     if self._multiline_indentation is None:
         offset = 0
         if self.show_aligned_keywords:
             offset = 2
         indentation = make_indentation(3 * self.indent_size + offset)
         self._multiline_indentation = indentation
     return self._multiline_indentation
コード例 #3
0
class StepsCatalogFormatter(StepsDocFormatter):
    """
    Provides formatter class that shows the documentation of all registered
    step definitions. The primary purpose is to provide help for a test writer.

    In order to ease work for non-programmer testers, the technical details of
    the steps (i.e. function name, source location) are ommited and the
    steps are shown as they would apprear in a feature file (no noisy '@',
    or '(', etc.).

    Also, the output is sorted by step type (Given, When, Then)

    Generic step definitions are listed with all three step types.

    EXAMPLE:
        $ Pyautomators --dry-run -f steps.catalog features/
        Given a file named "{filename}" with
            Creates a textual file with the content provided as docstring.

        When I run "{command}"
            Run a command as subprocess, collect its output and returncode.

        Given a file named "{filename}" exists
         When a file named "{filename}" exists
         Then a file named "{filename}" exists
            Verifies that a file with this filename exists.

            .. code-block:: gherkin

                Given a file named "abc.txt" exists
                 When a file named "abc.txt" exists
        ...

    .. note::
        Supports Pyautomators dry-run mode.
    """
    name = "steps.catalog"
    description = "Shows non-technical documentation for step definitions."
    shows_location = False
    shows_function_name = False
    ordered_by_location = False
    doc_prefix = make_indentation(4)


    def describe_step_definition(self, step_definition, step_type=None):
        if not step_type:
            step_type = step_definition.step_type
        assert step_type
        desc = []
        if step_type == "step":
            for step_type1 in self.step_types[:-1]:
                text = u"%5s %s" % (step_type1.title(), step_definition.pattern)
                desc.append(text)
        else:
            desc.append(u"%s %s" % (step_type.title(), step_definition.pattern))

        return '\n'.join(desc)
コード例 #4
0
ファイル: junit.py プロジェクト: yazbekludmila/FRETEBRAS
 def describe_step(self, step):
     status_text = _text(step.status.name)
     if self.show_timings:
         status_text += u" in %0.3fs" % step.duration
     text = u'%s %s ... ' % (step.keyword, step.name)
     text += u'%s\n' % status_text
     if self.show_multiline:
         prefix = make_indentation(2)
         if step.text:
             text += ModelDescriptor.describe_docstring(step.text, prefix)
         elif step.table:
             text += ModelDescriptor.describe_table(step.table, prefix)
     return text
コード例 #5
0
ファイル: junit.py プロジェクト: yazbekludmila/FRETEBRAS
    def describe_scenario(self, scenario):
        """Describe the scenario and the test status.
        NOTE: table, multiline text is missing in description.

        :param scenario:  Scenario that was tested.
        :return: Textual description of the scenario.
        """
        header_line = u'\[email protected]\n'
        if self.show_tags and scenario.tags:
            header_line += u'\n  %s\n' % self.describe_tags(scenario.tags)
        header_line += u'  %s: %s\n' % (scenario.keyword, scenario.name)
        footer_line = u'\[email protected]\n' + u'-' * 80 + '\n'
        text = u''
        for step in scenario:
            text += self.describe_step(step)
        step_indentation = make_indentation(4)
        return header_line + indent(text, step_indentation) + footer_line
コード例 #6
0
ファイル: plain.py プロジェクト: yazbekludmila/FRETEBRAS
    def result(self, step):
        """
        Process the result of a step (after step execution).

        :param step:   Step object with result to process.
        """
        step = self.steps.pop(0)
        indent = make_indentation(2 * self.indent_size)
        if self.show_aligned_keywords:
            # -- RIGHT-ALIGN KEYWORDS (max. keyword width: 6):
            text = u"%s%6s %s ... " % (indent, step.keyword, step.name)
        else:
            text = u"%s%s %s ... " % (indent, step.keyword, step.name)
        self.stream.write(text)

        status_text = step.status.name
        if self.show_timings:
            status_text += " in %0.3fs" % step.duration

        unicode_errors = 0
        if step.error_message:
            try:
                self.stream.write(u"%s\n%s\n" %
                                  (status_text, step.error_message))
            except UnicodeError as e:
                unicode_errors += 1
                self.stream.write(u"%s\n" % status_text)
                self.stream.write(u"%s while writing error message: %s\n" % \
                                  (e.__class__.__name__, e))
                if self.RAISE_OUTPUT_ERRORS:
                    raise
        else:
            self.stream.write(u"%s\n" % status_text)

        if self.show_multiline:
            if step.text:
                try:
                    self.doc_string(step.text)
                except UnicodeError as e:
                    unicode_errors += 1
                    self.stream.write(u"%s while writing docstring: %s\n" % \
                                      (e.__class__.__name__, e))
                    if self.RAISE_OUTPUT_ERRORS:
                        raise
            if step.table:
                self.table(step.table)
コード例 #7
0
class StepsUsageFormatter(AbstractStepsFormatter):
    """
    Provides formatter class that shows how step definitions are used by steps.

    EXAMPLE:
        $ Pyautomators --dry-run -f steps.usage features/
        ...

    .. note::
        Supports Pyautomators dry-run mode.
    """
    name = "steps.usage"
    description = "Shows how step definitions are used by steps."
    doc_prefix = make_indentation(4)
    min_location_column = 40

    def __init__(self, stream_opener, config):
        super(StepsUsageFormatter, self).__init__(stream_opener, config)
        self.step_usage_database = {}
        self.undefined_steps = []

    def reset(self):
        super(StepsUsageFormatter, self).reset()
        self.step_usage_database = {}
        self.undefined_steps = []

    # pylint: disable=invalid-name
    def get_step_type_for_step_definition(self, step_definition):
        step_type = step_definition.step_type
        if not step_type:
            # -- DETERMINE STEP-TYPE FROM STEP-REGISTRY:
            assert self.step_registry
            for step_type, values in self.step_registry.steps.items():
                if step_definition in values:
                    return step_type
            # -- OTHERWISE:
            step_type = "step"
        return step_type
    # pylint: enable=invalid-name

    def select_unused_step_definitions(self):
        step_definitions = set()
        for step_type, values in self.step_registry.steps.items():
            step_definitions.update(values)
        used_step_definitions = set(self.step_usage_database.keys())
        unused_step_definitions = step_definitions - used_step_definitions
        return unused_step_definitions

    def update_usage_database(self, step_definition, step):
        matching_steps = self.step_usage_database.get(step_definition, None)
        if matching_steps is None:
            assert step_definition.step_type is not None
            matching_steps = self.step_usage_database[step_definition] = []
        # -- AVOID DUPLICATES: From Scenario Outlines
        if not steps_contain(matching_steps, step):
            matching_steps.append(step)

    def update_usage_database_for_step(self, step):
        step_definition = self.step_registry.find_step_definition(step)
        if step_definition:
            self.update_usage_database(step_definition, step)
        # elif step not in self.undefined_steps:
        elif not steps_contain(self.undefined_steps, step):
            # -- AVOID DUPLICATES: From Scenario Outlines
            self.undefined_steps.append(step)

    # pylint: disable=invalid-name
    def update_usage_database_for_feature(self, feature):
        # -- PROCESS BACKGROUND (if exists): Use Background steps only once.
        if feature.background:
            for step in feature.background.steps:
                self.update_usage_database_for_step(step)

        # -- PROCESS SCENARIOS: Without background steps.
        for scenario in feature.walk_scenarios():
            for step in scenario.steps:
                self.update_usage_database_for_step(step)
    # pylint: enable=invalid-name

    # -- FORMATTER API:
    def feature(self, feature):
        super(StepsUsageFormatter, self).feature(feature)
        self.update_usage_database_for_feature(feature)

    # -- REPORT API:
    def report(self):
        self.report_used_step_definitions()
        self.report_unused_step_definitions()
        self.report_undefined_steps()
        self.stream.write("\n")

    # -- REPORT SPECIFIC-API:
    def report_used_step_definitions(self):
        # -- STEP: Used step definitions.
        # ORDERING: Sort step definitions by file location.
        get_location = lambda x: x[0].location
        step_definition_items = self.step_usage_database.items()
        step_definition_items = sorted(step_definition_items, key=get_location)

        for step_definition, steps in step_definition_items:
            stepdef_text = self.describe_step_definition(step_definition)
            steps_text = [u"  %s %s" % (step.keyword, step.name)
                          for step in steps]
            steps_text.append(stepdef_text)
            max_size = compute_words_maxsize(steps_text)
            if max_size < self.min_location_column:
                max_size = self.min_location_column

            schema = u"%-" + _text(max_size) + "s  # %s\n"
            self.stream.write(schema % (stepdef_text, step_definition.location))
            schema = u"%-" + _text(max_size) + "s  # %s\n"
            for step, step_text in zip(steps, steps_text):
                self.stream.write(schema % (step_text, step.location))
            self.stream.write("\n")

    def report_unused_step_definitions(self):
        unused_step_definitions = self.select_unused_step_definitions()
        if not unused_step_definitions:
            return

        # -- STEP: Prepare report for unused step definitions.
        # ORDERING: Sort step definitions by file location.
        get_location = lambda x: x.location
        step_definitions = sorted(unused_step_definitions, key=get_location)
        step_texts = [self.describe_step_definition(step_definition)
                      for step_definition in step_definitions]

        max_size = compute_words_maxsize(step_texts)
        if max_size < self.min_location_column-2:
            max_size = self.min_location_column-2

        # -- STEP: Write report.
        schema = u"  %-" + _text(max_size) + "s  # %s\n"
        self.stream.write("UNUSED STEP DEFINITIONS[%d]:\n" % len(step_texts))
        for step_definition, step_text in zip(step_definitions, step_texts):
            self.stream.write(schema % (step_text, step_definition.location))

    def report_undefined_steps(self):
        if not self.undefined_steps:
            return

        # -- STEP: Undefined steps.
        undefined_steps = sorted(self.undefined_steps,
                                 key=attrgetter("location"))

        steps_text = [u"  %s %s" % (step.keyword, step.name)
                      for step in undefined_steps]
        max_size = compute_words_maxsize(steps_text)
        if max_size < self.min_location_column:
            max_size = self.min_location_column

        self.stream.write("\nUNDEFINED STEPS[%d]:\n" % len(steps_text))
        schema = u"%-" + _text(max_size) + "s  # %s\n"
        for step, step_text in zip(undefined_steps, steps_text):
            self.stream.write(schema % (step_text, step.location))
コード例 #8
0
class StepsDocFormatter(AbstractStepsFormatter):
    """
    Provides formatter class that shows the documentation of all registered
    step definitions. The primary purpose is to provide help for a test writer.

    EXAMPLE:
        $ Pyautomators --dry-run -f steps.doc features/
        @given('a file named "{filename}" with')
          Function: step_a_file_named_filename_with()
          Location: Pyautomators4cmd0/command_steps.py:50
            Creates a textual file with the content provided as docstring.

        @when('I run "{command}"')
          Function: step_i_run_command()
          Location: Pyautomators4cmd0/command_steps.py:80
            Run a command as subprocess, collect its output and returncode.

        @step('a file named "{filename}" exists')
          Function: step_file_named_filename_exists()
          Location: Pyautomators4cmd0/command_steps.py:305
            Verifies that a file with this filename exists.

            .. code-block:: gherkin

                Given a file named "abc.txt" exists
                 When a file named "abc.txt" exists
        ...

    .. note::
        Supports Pyautomators dry-run mode.
    """
    name = "steps.doc"
    description = "Shows documentation for step definitions."
    shows_location = True
    shows_function_name = True
    ordered_by_location = True
    doc_prefix = make_indentation(4)

    # -- REPORT SPECIFIC-API:
    def report(self):
        self.report_step_definition_docs()
        self.stream.write("\n")

    def report_step_definition_docs(self):
        step_definitions = []
        for step_type in self.step_types:
            for step_definition in self.step_registry.steps[step_type]:
                # step_definition.step_type = step_type
                assert step_definition.step_type is not None
                step_definitions.append(step_definition)

        if self.ordered_by_location:
            step_definitions = sorted(step_definitions,
                                      key=attrgetter("location"))

        for step_definition in step_definitions:
            self.write_step_definition(step_definition)

    def write_step_definition(self, step_definition):
        step_definition_text = self.describe_step_definition(step_definition)
        self.stream.write(u"%s\n" % step_definition_text)
        doc = inspect.getdoc(step_definition.func)
        func_name = step_definition.func.__name__
        if self.shows_function_name and func_name not in ("step", "impl"):
            self.stream.write(u"  Function: %s()\n" % func_name)
        if self.shows_location:
            self.stream.write(u"  Location: %s\n" % step_definition.location)
        if doc:
            doc = doc.strip()
            self.stream.write(indent(doc, self.doc_prefix))
            self.stream.write("\n")
        self.stream.write("\n")
コード例 #9
0
ファイル: plain.py プロジェクト: yazbekludmila/FRETEBRAS
 def background(self, background):
     self.reset_steps()
     indent = make_indentation(self.indent_size)
     text = u"%s%s: %s\n" % (indent, background.keyword, background.name)
     self.stream.write(text)