Beispiel #1
0
def test_stepregistry_is_initialized_with_no_step_impls():
    """The StepRegistry should be initialized with no registered Step Implementations"""
    # given & when
    registry = StepRegistry()

    # then
    assert registry.step_implementations() == {}
Beispiel #2
0
    def test_registering_object(self):
        """
            Test registering object as steps
        """
        registry = StepRegistry()
        registry.steps.should.be.empty

        class MySteps(object):
            ignore = ["no_step_method"]

            def some_step(step):
                """When I call some step"""

            def some_other_step(step):
                """
                    Then I expect some behaviour
                """

            def no_step_method(data):
                """
                    This is not a step method
                """

        steps_object = MySteps()
        registry.register_object(steps_object)

        registry.steps.should.have.length_of(2)
        registry.steps["When I call some step"].should.be.equal(steps_object.some_step)
        registry.steps["Then I expect some behaviour"].should.be.equal(steps_object.some_other_step)
Beispiel #3
0
    def test_registering_object(self):
        """
            Test registering object as steps
        """
        registry = StepRegistry()
        registry.steps.should.be.empty

        class MySteps(object):
            ignore = ["no_step_method"]

            def some_step(step):
                """When I call some step"""

            def some_other_step(step):
                """
                    Then I expect some behaviour
                """

            def no_step_method(data):
                """
                    This is not a step method
                """

        steps_object = MySteps()
        registry.register_object(steps_object)

        registry.steps.should.have.length_of(2)
        registry.steps["When I call some step"].should.be.equal(
            steps_object.some_step)
        registry.steps["Then I expect some behaviour"].should.be.equal(
            steps_object.some_other_step)
Beispiel #4
0
    def test_registering_steps_with_gherkin_decorators(self):
        """
            Test registering steps with gherkin specific decorators
        """
        def step_given():
            pass

        def step_when():
            pass

        def step_then():
            pass

        registry = StepRegistry()
        registry.steps.should.be.empty

        given(r"I have the number {:g}")(step_given)
        registry.steps.should.have.length_of(1)
        registry.steps[r"Given I have the number {:g}"] = step_given

        # cannot test the when function because sure overwrites it!
        # stupid stuff
        # step_when(r"I add \d+ to my number")(step_when)
        # registry.steps.should.have.length_of(2)
        # registry.steps[r"When I add \d+ to my number"] = step_when

        then(re.compile(r"I expect my number to be \d+"))(step_then)
        registry.steps.should.have.length_of(2)
Beispiel #5
0
def test_stepregistry_should_allow_to_register_step_impls():
    """The StepRegistry should allow to register a Step Implementation"""
    # given
    registry = StepRegistry()

    # when
    registry.register("Given", "pattern", None)

    # then
    assert registry.step_implementations("Given") == [
        StepImpl("Given", "pattern", None)
    ]
Beispiel #6
0
def test_stepregistry_should_create_one_step_decorator_per_keyword():
    """The StepRegistry should create one Step decorator for each keyword"""
    # given
    registry = StepRegistry()
    context = {}

    # when
    registry.create_step_decorators(context)

    # then
    assert len(context) == 4
    assert "given" in context
    assert "when" in context
    assert "then" in context
    assert "step" in context
Beispiel #7
0
    def behave_like(self, sentence):
        """
            Make step behave like another one

            :param string sentence: the sentence of the step to behave like
        """
        # check if this step has already failed from a previous behave_like call
        if self.state is Step.State.FAILED:
            return

        # create step according to given sentence
        new_step = Step(None, sentence, self.path, self.line, self.parent,
                        True)
        merge_step(new_step, StepRegistry().steps)

        # run or debug step
        if world.config.debug_steps:
            new_step.debug()
        else:
            new_step.run()

        # re-raise exception if the failed
        if new_step.state is Step.State.FAILED:
            new_step.failure.exception.args = (
                "Step '{0}' failed: '{1}'".format(
                    sentence, new_step.failure.exception.message), )
            raise new_step.failure.exception
Beispiel #8
0
def reset_registries():
    """
    Fixture to automatically reset singleton registries
    """
    StepRegistry().clear()
    HookRegistry().reset()
    ExtensionRegistry().reset()
Beispiel #9
0
    def tearDown(self):
        """
            Tear down the test

            Delete all singletons
        """
        StepRegistry().clear()
        HookRegistry().reset()
Beispiel #10
0
    def setUp(self):
        """
            Setup test

            Initialize all singletons
        """
        StepRegistry()
        return True
Beispiel #11
0
def test_stepregistry_step_decorator_should_register_func_with_proper_keyword(keyword):
    """The StepRegistry should create one Step decorator for each keyword"""
    # given
    registry = StepRegistry()
    context = {}
    registry.create_step_decorators(context)

    # when
    def test_step():
        ...

    test_step = context[keyword.lower()]("pattern")(test_step)

    # then
    assert registry.step_implementations(keyword) == [
        StepImpl(keyword, "pattern", test_step)
    ]
Beispiel #12
0
def test_stepregitry_step_decorators_for_all_keywords():
    """The StepRegistry should return the Step Implementations registered
    with the ``step`` decorator for all keywords.
    """
    # given
    registry = StepRegistry()
    context = {}
    registry.create_step_decorators(context)

    # when
    def test_step():
        ...

    test_step = context["step"]("pattern")(test_step)

    # then
    assert registry.step_implementations("Given") == [
        StepImpl("Step", "pattern", test_step)
    ]
Beispiel #13
0
    def test_registering_steps(self):
        """
            Test registering multiple steps
        """
        registry = StepRegistry()
        registry.steps.should.be.empty

        def step_a():
            pass

        def step_b():
            pass

        registry.register("abc", step_a)
        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)

        registry.register("def", step_b)
        registry.steps.should.have.length_of(2)
        registry.steps["def"].should.be.equal(step_b)
Beispiel #14
0
    def test_registering_same_step(self):
        """
            Test registering step with same regex
        """
        registry = StepRegistry()
        registry.steps.should.be.empty

        def step_a():
            pass

        def step_b():
            pass

        registry.register("abc", step_a)
        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)

        registry.register.when.called_with("abc", step_b).should.throw(SameStepError, "Cannot register step step_b with regex 'abc' because it is already used by step step_a")

        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)
Beispiel #15
0
    def test_registering_same_step(self):
        """
            Test registering step with same regex
        """
        registry = StepRegistry()
        registry.steps.should.be.empty

        def step_a():
            pass

        def step_b():
            pass

        registry.register("abc", step_a)
        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)

        registry.register.when.called_with("abc", step_b).should.throw(
            SameStepError,
            "Cannot register step step_b with regex 'abc' because it is already used by step step_a"
        )

        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)
Beispiel #16
0
def test_stepregistry_should_gracefully_accept_double_registration():
    """
    The StepRegistry should gracefully accept a duplicate registration of a Step Implementation
    """
    # given
    registry = StepRegistry()
    registry.register("Given", "pattern", None)

    # when
    registry.register("Given", "pattern", None)

    # then
    assert registry.step_implementations("Given") == [
        StepImpl("Given", "pattern", None)
    ]
Beispiel #17
0
    def test_registering_steps_with_decorator(self):
        """
            Test registering steps with decorator
        """
        registry = StepRegistry()
        registry.steps.should.have.length_of(0)

        def step_a():
            pass

        def step_b():
            pass

        step("abc")(step_a)
        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)

        step("def")(step_b)
        registry.steps.should.have.length_of(2)
        registry.steps["def"].should.be.equal(step_b)
Beispiel #18
0
    def test_registering_steps(self):
        """
            Test registering multiple steps
        """
        registry = StepRegistry()
        registry.steps.should.be.empty

        def step_a():
            pass

        def step_b():
            pass

        registry.register("abc", step_a)
        registry.steps.should.have.length_of(1)
        registry.steps["abc"].should.be.equal(step_a)

        registry.register("def", step_b)
        registry.steps.should.have.length_of(2)
        registry.steps["def"].should.be.equal(step_b)
Beispiel #19
0
def test_stepregitry_register_func_with_multiple_decorators():
    """The StepRegistry should allow a function to be registered with multiple Step decorators"""
    # given
    registry = StepRegistry()
    context = {}
    registry.create_step_decorators(context)

    # when
    def test_step():
        ...

    test_step = context["given"]("pattern")(test_step)
    test_step = context["when"]("pattern")(test_step)

    # then
    assert registry.step_implementations("Given") == [
        StepImpl("Given", "pattern", test_step)
    ]
    assert registry.step_implementations("When") == [
        StepImpl("When", "pattern", test_step)
    ]
Beispiel #20
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "scenarios": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "steps": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios):
                    continue

                if isinstance(scenario, ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_yellow("{0} pending")

        output = colorful.bold_white(
            "{0} features (".format(stats["features"]["amount"])
        )
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white(
            "{} scenarios (".format(stats["scenarios"]["amount"])
        )
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(
                pending_steps, lambda x: x.definition_func
            )
            output += colorful.white(
                "\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps".format(
                    len(pending_step_implementations),
                    "s" if len(pending_step_implementations) is not 1 else "",
                    len(pending_steps),
                    "s" if len(pending_steps) is not 1 else "",
                    "\n  ".join(
                        [
                            "-  '{0}' @ {1}".format(
                                sr.get_pattern(s.definition_func),
                                get_func_code(s.definition_func).co_filename,
                            )
                            for s in pending_step_implementations
                        ]
                    ),
                )
            )

        output += "\n"

        if world.config.wip:
            if stats["scenarios"]["passed"] > 0:
                output += colorful.red(
                    "\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:\n"
                )

                has_passed_scenarios = False
                for feature in features:
                    passed_scenarios = list(
                        filter(
                            lambda s: s.state == Step.State.PASSED,
                            feature.all_scenarios,
                        )
                    )
                    for scenario in passed_scenarios:
                        output += colorful.red(
                            "\n - {}: {}".format(feature.path, scenario.sentence)
                        )
                        has_passed_scenarios = True

                if has_passed_scenarios:
                    output += "\n"
            else:
                output += colorful.green(
                    "\nThe --wip switch was used, so the failures were expected. All is good.\n"
                )

        output += colorful.cyan(
            "Run {0} finished within {1}".format(
                marker, humanize.naturaldelta(duration)
            )
        )

        write(output)
Beispiel #21
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "scenarios": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
            "steps": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0,
            },
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios):
                    continue

                if isinstance(scenario,
                              ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_yellow("{0} pending")

        output = colorful.bold_white("{0} features (".format(
            stats["features"]["amount"]))
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} scenarios (".format(
            stats["scenarios"]["amount"]))
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(
            stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(
                pending_steps, lambda x: x.definition_func)
            output += colorful.white(
                "\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps"
                .format(
                    len(pending_step_implementations),
                    "s" if len(pending_step_implementations) is not 1 else "",
                    len(pending_steps),
                    "s" if len(pending_steps) is not 1 else "",
                    "\n  ".join([
                        "-  '{0}' @ {1}".format(
                            sr.get_pattern(s.definition_func),
                            get_func_code(s.definition_func).co_filename,
                        ) for s in pending_step_implementations
                    ]),
                ))

        output += "\n"

        if world.config.wip:
            if stats["scenarios"]["passed"] > 0:
                output += colorful.red(
                    "\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:\n"
                )

                has_passed_scenarios = False
                for feature in features:
                    passed_scenarios = list(
                        filter(
                            lambda s: s.state == Step.State.PASSED,
                            feature.all_scenarios,
                        ))
                    for scenario in passed_scenarios:
                        output += colorful.red("\n - {}: {}".format(
                            feature.path, scenario.sentence))
                        has_passed_scenarios = True

                if has_passed_scenarios:
                    output += "\n"
            else:
                output += colorful.green(
                    "\nThe --wip switch was used, so the failures were expected. All is good.\n"
                )

        output += colorful.cyan("Run {0} finished within {1}".format(
            marker, humanize.naturaldelta(duration)))

        write(output)
Beispiel #22
0
def stepregistry():
    """
    Fixture to create and get a clean StepRegistry instance.
    """
    registry = StepRegistry()
    yield registry
Beispiel #23
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0, "pending": 0},
            "scenarios": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0, "pending": 0},
            "steps": {"amount": 0, "passed": 0, "failed": 0, "skipped": 0, "untested": 0, "pending": 0},
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios, world.config.feature_tags, world.config.scenario_tags):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios, world.config.feature_tags, world.config.scenario_tags):
                    continue

                if isinstance(scenario, ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_brown("{0} pending")

        output = colorful.bold_white("{0} features (".format(stats["features"]["amount"]))
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} scenarios (".format(stats["scenarios"]["amount"]))
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(pending_steps, lambda x: x.definition_func)
            output += colorful.white("\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps".format(
                len(pending_step_implementations),
                "s" if len(pending_step_implementations) is not 1 else "",
                len(pending_steps),
                "s" if len(pending_steps) is not 1 else "",
                "\n  ".join(["-  '{0}' @ {1}".format(sr.get_pattern(s.definition_func), get_func_code(s.definition_func).co_filename) for s in pending_step_implementations])
            ))

        output += "\n"
        output += colorful.cyan("Run {0} finished within {1}:{2} minutes".format(marker, int(duration.total_seconds()) / 60, duration.total_seconds() % 60.0))

        write(output)
Beispiel #24
0
def test_step_matches_configs(match_config_files,
                              basedirs,
                              cover_min_percentage=None,
                              cover_show_missing=False):
    """
    Test if the given match config files matches the actual
    matched step implementations.
    """
    if cover_min_percentage is not None and float(cover_min_percentage) > 100:
        sys.stderr.write(
            str(
                colorful.magenta(
                    'You are a little cocky to think you can reach a minimum coverage of {0:.2f}%\n'
                    .format(float(cover_min_percentage)))))
        return 3

    # load user's custom python files
    for basedir in basedirs:
        load_modules(basedir)

    steps = StepRegistry().steps

    if not steps:
        sys.stderr.write(
            str(
                colorful.magenta(
                    'No step implementations found in {0}, thus doesn\'t make sense to continue'
                    .format(basedirs))))
        return 4

    failed = 0
    passed = 0
    covered_steps = set()

    for match_config_file in match_config_files:
        # load the given match config file
        with codecs.open(match_config_file, "r", "utf-8") as f:
            match_config = yaml.safe_load(f)

        if not match_config:
            print(
                colorful.magenta(
                    'No sentences found in {0} to test against'.format(
                        match_config_file)))
            return 5

        print(
            colorful.yellow('Testing sentences from {0}:'.format(
                colorful.bold_yellow(match_config_file))))
        failed_sentences, passed_senteces = test_step_matches(
            match_config, steps)
        failed += failed_sentences
        passed += passed_senteces

        covered_steps = covered_steps.union(x['should_match']
                                            for x in match_config
                                            if 'should_match' in x)

        # newline
        sys.stdout.write('\n')

    report = colorful.bold_white('{0} sentences ('.format(failed + passed))
    if passed > 0:
        report += colorful.bold_green('{0} passed'.format(passed))

    if passed > 0 and failed > 0:
        report += colorful.bold_white(', ')

    if failed > 0:
        report += colorful.bold_red('{0} failed'.format(failed))
    report += colorful.bold_white(')')
    print(report)

    step_coverage = 100.0 / len(steps) * len(covered_steps)
    coverage_report = colorful.bold_white(
        'Covered {0} of {1} step implementations'.format(
            len(covered_steps), len(steps)))

    ret = 0 if failed == 0 else 1

    if cover_min_percentage:
        coverage_color = colorful.bold_green if step_coverage >= float(
            cover_min_percentage) else colorful.bold_red
        coverage_report += colorful.bold_white(' (coverage: ')
        coverage_report += coverage_color('{0:.2f}%'.format(step_coverage))
        if float(cover_min_percentage) > step_coverage:
            coverage_report += colorful.bold_white(
                ', expected a minimum of {0}'.format(
                    colorful.bold_green(cover_min_percentage + '%')))
            if failed == 0:
                ret = 2
            # if tests have passed and coverage is too low we fail with exit code 2
        coverage_report += colorful.bold_white(')')

    print(coverage_report)

    if cover_show_missing:
        missing_steps = get_missing_steps(steps, covered_steps)
        if missing_steps:
            missing_step_report = colorful.bold_yellow('Missing steps:\n')
            for step in missing_steps:
                missing_step_report += '- {0} at '.format(
                    colorful.cyan(step[0]))
                missing_step_report += colorful.cyan(step[1]) + '\n'
            sys.stdout.write(missing_step_report)

    return ret
Beispiel #25
0
    def console_write(self, features, marker):
        """
            Writes the endreport for all features

            :param list features: all features
        """
        stats = {
            "features": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0
            },
            "scenarios": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0
            },
            "steps": {
                "amount": 0,
                "passed": 0,
                "failed": 0,
                "skipped": 0,
                "untested": 0,
                "pending": 0
            },
        }
        pending_steps = []
        duration = timedelta()
        for feature in features:
            if not feature.has_to_run(world.config.scenarios,
                                      world.config.feature_tags,
                                      world.config.scenario_tags):
                continue
            stats["features"]["amount"] += 1
            stats["features"][feature.state] += 1

            if feature.state in [Step.State.PASSED, Step.State.FAILED]:
                duration += feature.duration

            for scenario in feature.all_scenarios:
                if not scenario.has_to_run(world.config.scenarios,
                                           world.config.feature_tags,
                                           world.config.scenario_tags):
                    continue

                if isinstance(scenario,
                              ScenarioOutline):  # skip ScenarioOutlines
                    continue
                if isinstance(scenario, ScenarioLoop):  # skip ScenarioLoop
                    continue

                stats["scenarios"]["amount"] += 1
                stats["scenarios"][scenario.state] += 1
                for step in scenario.steps:
                    stats["steps"]["amount"] += 1
                    stats["steps"][step.state] += 1

                    if step.state == Step.State.PENDING:
                        pending_steps.append(step)

        colored_closing_paren = colorful.bold_white(")")
        colored_comma = colorful.bold_white(", ")
        passed_word = colorful.bold_green("{0} passed")
        failed_word = colorful.bold_red("{0} failed")
        skipped_word = colorful.cyan("{0} skipped")
        pending_word = colorful.bold_brown("{0} pending")

        output = colorful.bold_white("{0} features (".format(
            stats["features"]["amount"]))
        output += passed_word.format(stats["features"]["passed"])
        if stats["features"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["features"]["failed"])
        if stats["features"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["features"]["skipped"])
        if stats["features"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["features"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} scenarios (".format(
            stats["scenarios"]["amount"]))
        output += passed_word.format(stats["scenarios"]["passed"])
        if stats["scenarios"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["scenarios"]["failed"])
        if stats["scenarios"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["scenarios"]["skipped"])
        if stats["scenarios"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["scenarios"]["pending"])
        output += colored_closing_paren

        output += "\n"
        output += colorful.bold_white("{} steps (".format(
            stats["steps"]["amount"]))
        output += passed_word.format(stats["steps"]["passed"])
        if stats["steps"]["failed"]:
            output += colored_comma + failed_word.format(
                stats["steps"]["failed"])
        if stats["steps"]["skipped"]:
            output += colored_comma + skipped_word.format(
                stats["steps"]["skipped"])
        if stats["steps"]["pending"]:
            output += colored_comma + pending_word.format(
                stats["steps"]["pending"])
        output += colored_closing_paren

        if pending_steps:
            sr = StepRegistry()
            pending_step_implementations = make_unique_obj_list(
                pending_steps, lambda x: x.definition_func)
            output += colorful.white(
                "\nYou have {0} pending step implementation{1} affecting {2} step{3}:\n  {4}\n\nNote: this could be the reason for some failing subsequent steps"
                .format(
                    len(pending_step_implementations),
                    "s" if len(pending_step_implementations) is not 1 else "",
                    len(pending_steps),
                    "s" if len(pending_steps) is not 1 else "", "\n  ".join([
                        "-  '{0}' @ {1}".format(
                            sr.get_pattern(s.definition_func),
                            get_func_code(s.definition_func).co_filename)
                        for s in pending_step_implementations
                    ])))

        output += "\n"
        output += colorful.cyan(
            "Run {0} finished within {1}:{2} minutes".format(
                marker,
                int(duration.total_seconds()) / 60,
                duration.total_seconds() % 60.0))

        write(output)