Skip to content

Commit

Permalink
Implement dots formatter. Refs #178
Browse files Browse the repository at this point in the history
  • Loading branch information
timofurrer committed Dec 23, 2018
1 parent f38e57b commit 79a2b86
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 0 deletions.
45 changes: 45 additions & 0 deletions docs/commandline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,51 @@ destroying them.
radish SomeFeature.feature --no-line-jump
Run - dots output formatter
---------------------------

By default the `gherkin` output formatter is used.
This formatter prints the Features in a gherkin style.
In most of the cases that's the same as the input Feature File content.
This gherkin output formatter is rather verbose: all Features, Scenarios and Steps are printed.

You can use the `dots` output formatter with the `-f dots` command line option.
Every passed Scenario will be printed as a dot (`.`).
Other possible symbols are:

* `P` for *pending*
* `U` for *untested*
* `S` for *skipped*
* `F` for *failed*

If a Scenario has failed, the failed Step will be printed in the summary in the end:

.. code:: bash
$ radish SomeFeature.feature -f dots
features/SomeFeature.feature: ..FFF..
Failures:
features/SomeFeature.feature: Subtract numbers wrongly
Then I expect the difference to be 3
AttributeError: 'int' object has no attribute 'step'
features/SomeFeature.feature: A Scenario Outline - row 0
Then I expect the sum to be 3
AssertionError: The expected sum 3 does not match actual sum 11
features/SomeFeature.feature: A Scenario Outline - row 1
Then I expect the sum to be 9
AssertionError: The expected sum 9 does not match actual sum 17
1 features (0 passed, 1 failed)
7 scenarios (4 passed, 3 failed)
20 steps (17 passed, 3 failed)
Run 1545585467 finished within a moment
Run - Writing out Scenario and Step ids
---------------------------------------

Expand Down
95 changes: 95 additions & 0 deletions radish/extensions/formatters/dots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-

"""
This radish extension provides the functionality to write the feature file run to the console.
"""

from __future__ import unicode_literals
from __future__ import print_function

import sys
import colorful as cf

from radish.terrain import world
from radish.hookregistry import before, after
from radish.scenariooutline import ScenarioOutline
from radish.scenarioloop import ScenarioLoop
from radish.stepmodel import Step
from radish.extensionregistry import extension


@extension
class DotOutputFormatter(object):
"""
Output formatter in the dot style.
"""

LOAD_IF = staticmethod(lambda config: config.formatter == "dots")
LOAD_PRIORITY = 30

STATE_SYMBOLS = {
Step.State.PASSED: ".",
Step.State.PENDING: "P",
Step.State.UNTESTED: "U",
Step.State.SKIPPED: "S",
Step.State.FAILED: "F",
}

def __init__(self):
before.each_feature(self.dot_formatter_before_each_feature)
after.each_feature(lambda *args, **kwargs: sys.stdout.write("\n"))
after.each_scenario(self.dot_formatter_after_each_scenario)
after.each_step(self.dot_formatter_after_each_step)
after.all(self.dot_formatter_failure_summary)

self._failed_steps = []

def dot_formatter_before_each_feature(self, feature):
"""
Writes feature header to the console
:param Feature feature: the feature to write to the console
"""
output = cf.bold_black(feature.path) + ": "
sys.stdout.write(str(output))

def dot_formatter_after_each_scenario(self, scenario):
"""
If the scenario is a ExampleScenario it will write the Examples header
:param Scenario scenario: the scenario which was ran.
"""
if isinstance(scenario, (ScenarioOutline, ScenarioLoop)):
return

sys.stdout.write(self.STATE_SYMBOLS[scenario.state])

def dot_formatter_after_each_step(self, step):
if step.state == Step.State.FAILED:
self._failed_steps.append(step)

def dot_formatter_failure_summary(self, features, marker):
"""Output summary for failed Scenarios."""
if not self._failed_steps:
return

output = "\n" + cf.bold_red("Failures:") + "\n"

for step in self._failed_steps:
output += "{}: {}\n {}\n".format(
step.path, step.parent.sentence, cf.red(step.sentence)
)
if world.config.with_traceback:
output += " {}\n".format(
"\n ".join(
[
str(cf.red(l))
for l in step.failure.traceback.split("\n")[:-2]
]
)
)
output += " {}: {}\n\n".format(
cf.bold_red(step.failure.name), cf.red(step.failure.reason)
)

sys.stdout.write(str(output) + "\n")
37 changes: 37 additions & 0 deletions tests/features/everything_with_failures.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@everything
Feature: Everything in one Feature
A feature file with everything in it.

Background: A simple Background
Given I have the number 5
And I have the number 3

@foo
Scenario: Add numbers
When I add them up
Then I expect the sum to be 8

Scenario: Subtract numbers
When I subtract them
Then I expect the difference to be 2

@bad
Scenario: Subtract numbers wrongly
When I subtract them
Then I expect the difference to be 3

Scenario Outline: A Scenario Outline
Given I have the number <x>
And I have the number <y>
When I add them up
Then I expect the sum to be <z>

Examples:
| x | y | z |
| 1 | 2 | 3 |
| 4 | 5 | 9 |

Scenario Loop 2: This is a looped Scenario
Given I have an instable function
When I execute it
Then I expect it to pass
7 changes: 7 additions & 0 deletions tests/integration/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@
"failing-scenario-middle-success-wip",
),
(["scenario-outline"], ["--wip"], 1, "scenario-outline-failed-wip"),
(
["everything_with_failures"],
["-t", "-f", "dots"],
1,
"everything_with_failures_dot_formatter",
),
],
ids=[
"Empty Feature File",
Expand Down Expand Up @@ -283,6 +289,7 @@
"Feature with single Scenario and Steps producing JUnit XML",
"Feature which fails with wip tag",
"Feature which does not fail with wip tag",
"Feature which has everything in it and some Scenario fail",
],
)
def test_main_cli_calls(
Expand Down
35 changes: 35 additions & 0 deletions tests/output/everything_with_failures_dot_formatter.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
features/everything_with_failures.feature: ..FFF..

Failures:
features/everything_with_failures.feature: Subtract numbers wrongly
Then I expect the difference to be 3
Traceback (most recent call last):
 File "/home/tuxtimo/work/radish/radish/stepmodel.py", line 117, in run
 self.definition_func(self, **kwargs) # pylint: disable=not-callable
 File "/home/tuxtimo/work/radish/tests/radish/steps.py", line 83, in expect_sum
 expected_diff.step.context.difference
AttributeError: 'int' object has no attribute 'step'

features/everything_with_failures.feature: A Scenario Outline - row 0
Then I expect the sum to be 3
Traceback (most recent call last):
 File "/home/tuxtimo/work/radish/radish/stepmodel.py", line 117, in run
 self.definition_func(self, **kwargs) # pylint: disable=not-callable
 File "/home/tuxtimo/work/radish/tests/radish/steps.py", line 73, in expect_sum
 expected_sum, step.context.sum
AssertionError: The expected sum 3 does not match actual sum 11

features/everything_with_failures.feature: A Scenario Outline - row 1
Then I expect the sum to be 9
Traceback (most recent call last):
 File "/home/tuxtimo/work/radish/radish/stepmodel.py", line 117, in run
 self.definition_func(self, **kwargs) # pylint: disable=not-callable
 File "/home/tuxtimo/work/radish/tests/radish/steps.py", line 73, in expect_sum
 expected_sum, step.context.sum
AssertionError: The expected sum 9 does not match actual sum 17


1 features (0 passed, 1 failed)
7 scenarios (4 passed, 3 failed)
20 steps (17 passed, 3 failed)
Run test-marker finished within a moment

0 comments on commit 79a2b86

Please sign in to comment.