Repository: go-bdd/gobdd
Pull request #38 (2019-08-28 04:42:34)

refactor reporter


Patch:
diff --git a/features/tags.feature b/features/tags.feature
index 847cd6f..7f53005 100644
--- a/features/tags.feature
+++ b/features/tags.feature
@@ -2,6 +2,9 @@ Feature: ignored tags
   @tag
   Scenario: the scenario should be pass
     Then the test should pass
-
+  @tag
+  Scenario Outline: the scenario should be pass
+    Then the test should pass
+    Examples:
   Scenario: the test should never be executed
     Then fail the test
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 148cb53..21491c2 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,5 @@ go 1.12
 require (
 	github.com/cucumber/gherkin-go v5.1.0+incompatible
 	github.com/logrusorgru/aurora v0.0.0-20190428105938-cea283e61946
-	github.com/mattn/goveralls v0.0.2 // indirect
-	golang.org/x/tools v0.0.0-20190730215328-ed3277de2799 // indirect
+	github.com/stretchr/testify v1.4.0
 )
diff --git a/go.sum b/go.sum
index 414d084..637ff64 100644
--- a/go.sum
+++ b/go.sum
@@ -1,13 +1,15 @@
 github.com/cucumber/gherkin-go v5.1.0+incompatible h1:RCvyVI6KQLI2IJkijZBeJcE4K3U7DnhQ1RjD7VV+AIk=
 github.com/cucumber/gherkin-go v5.1.0+incompatible/go.mod h1:bYJ65F+CDEAL70FXAu7/ef4ayC/NhRXO8zEW3IB21w0=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/logrusorgru/aurora v0.0.0-20190428105938-cea283e61946 h1:z+WaKrgu3kCpcdnbK9YG+JThpOCd1nU5jO5ToVmSlR4=
 github.com/logrusorgru/aurora v0.0.0-20190428105938-cea283e61946/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc=
-github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190730215328-ed3277de2799 h1:rvNf5qrBjmtxebJHK+blZSkGIv+Yg6UlDnl2ApkB6m4=
-golang.org/x/tools v0.0.0-20190730215328-ed3277de2799/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/gobdd.go b/gobdd.go
index 1d1ec71..3ce536e 100644
--- a/gobdd.go
+++ b/gobdd.go
@@ -164,17 +164,23 @@ func (s *Suite) executeFeature(file string) error {
 
 func (s *Suite) runFeature(feature *gherkin.Feature) error {
 	log.SetOutput(ioutil.Discard)
-	r := reporter.NewFmt()
+	r := reporter.NewReporter()
+	_ = r.Report(feature)
 	hasErrors := false
 	var bkgSteps *gherkin.Background
 
 	for _, child := range feature.Children {
 		if scenario, ok := child.(*gherkin.Scenario); ok {
 			if s.skipScenario(scenario.Tags) {
-				r.SkippedScenario(scenario)
+				r.Skip(scenario)
 				continue
 			}
-			err := s.runScenario(scenario, bkgSteps, r)
+			ctx := context.New()
+
+			if bkgSteps != nil {
+				s.runSteps(ctx, r, bkgSteps.Steps)
+			}
+			err := s.runScenario(ctx, scenario, bkgSteps, r)
 			if err != nil {
 				hasErrors = true
 			}
@@ -182,11 +188,16 @@ func (s *Suite) runFeature(feature *gherkin.Feature) error {
 
 		if scenario, ok := child.(*gherkin.ScenarioOutline); ok {
 			if s.skipScenario(scenario.Tags) {
-				r.SkippedScenarioOutline(scenario)
+				r.Skip(scenario)
 				continue
 			}
 
-			err := s.runScenarioOutline(scenario, bkgSteps, r)
+			ctx := context.New()
+			if bkgSteps != nil {
+				s.runSteps(ctx, r, bkgSteps.Steps)
+			}
+
+			err := s.runScenarioOutline(scenario, r)
 			if err != nil {
 				hasErrors = true
 			}
@@ -194,11 +205,11 @@ func (s *Suite) runFeature(feature *gherkin.Feature) error {
 
 		if bkg, ok := child.(*gherkin.Background); ok {
 			bkgSteps = bkg
+			_ = r.Report(bkg)
 		}
 	}
 
 	r.GenerateReport()
-
 	if hasErrors {
 		return errors.New("the feature contains errors")
 	}
@@ -206,10 +217,10 @@ func (s *Suite) runFeature(feature *gherkin.Feature) error {
 	return nil
 }
 
-func (s *Suite) runScenarioOutline(outline *gherkin.ScenarioOutline, bkg *gherkin.Background, reporter reporter.Reporter) error {
+func (s *Suite) runScenarioOutline(outline *gherkin.ScenarioOutline, reporter *reporter.Reporter) error {
 	s.callBeforeScenarios()
 	defer s.callAfterScenarios()
-	reporter.ScenarioOutline(outline)
+	_ = reporter.Report(outline)
 	for _, ex := range outline.Examples {
 		if len(ex.TableBody) == 0 {
 			continue
@@ -220,12 +231,6 @@ func (s *Suite) runScenarioOutline(outline *gherkin.ScenarioOutline, bkg *gherki
 
 		for _, group := range groups {
 			ctx := context.New()
-			if bkg != nil {
-				reporter.Background(bkg)
-				steps := s.getBackgroundSteps(bkg)
-				s.runSteps(ctx, reporter, steps)
-			}
-
 			steps := s.runOutlineStep(outline, placeholders, group)
 			s.runSteps(ctx, reporter, steps)
 		}
@@ -320,15 +325,13 @@ func (s *Suite) outlineDataTableArguments(t *gherkin.DataTable, placeholders []*
 	return tbl
 }
 
-func (s *Suite) runScenario(scenario *gherkin.Scenario, bkg *gherkin.Background, reporter reporter.Reporter) error {
+func (s *Suite) runScenario(ctx context.Context, scenario *gherkin.Scenario, bkg *gherkin.Background, reporter *reporter.Reporter) error {
 	s.callBeforeScenarios()
 
 	defer s.callAfterScenarios()
-	reporter.Scenario(scenario)
-	ctx := context.New()
+	_ = reporter.Report(scenario)
 
 	if bkg != nil {
-		reporter.Background(bkg)
 		steps := s.getBackgroundSteps(bkg)
 		s.runSteps(ctx, reporter, steps)
 	}
@@ -337,13 +340,13 @@ func (s *Suite) runScenario(scenario *gherkin.Scenario, bkg *gherkin.Background,
 	return nil
 }
 
-func (s *Suite) runSteps(ctx context.Context, reporter reporter.Reporter, steps []*gherkin.Step) {
+func (s *Suite) runSteps(ctx context.Context, reporter *reporter.Reporter, steps []*gherkin.Step) {
 	for _, step := range steps {
 		s.runStep(ctx, reporter, step)
 	}
 }
 
-func (s *Suite) runStep(ctx context.Context, reporter reporter.Reporter, step *gherkin.Step) {
+func (s *Suite) runStep(ctx context.Context, reporter *reporter.Reporter, step *gherkin.Step) {
 	defer func() {
 		if r := recover(); r != nil {
 			s.t.Error(r)
@@ -352,7 +355,7 @@ func (s *Suite) runStep(ctx context.Context, reporter reporter.Reporter, step *g
 
 	def, err := s.findStepDef(step.Text)
 	if err != nil {
-		reporter.UndefinedStep(step)
+		reporter.Undefined(step)
 		s.t.Errorf("cannot find step definition for step '%s'", step.Text)
 		return
 	}
@@ -361,10 +364,10 @@ func (s *Suite) runStep(ctx context.Context, reporter reporter.Reporter, step *g
 	ctx.SetParams(b[1:])
 	err = def.f(ctx)
 	if err != nil {
-		reporter.FailedStep(step, err)
+		reporter.Failed(step, err)
 		s.t.Error(err)
 	} else {
-		reporter.SucceededStep(step)
+		_ = reporter.Report(step)
 	}
 }
 
diff --git a/reporter/fmt.go b/reporter/fmt.go
index f40f286..bec3a44 100644
--- a/reporter/fmt.go
+++ b/reporter/fmt.go
@@ -2,104 +2,105 @@ package reporter
 
 import (
 	"fmt"
-	"time"
 
 	"github.com/cucumber/gherkin-go"
 	. "github.com/logrusorgru/aurora"
 )
 
-func NewFmt() *fmtReporter {
-	return &fmtReporter{
-		timer:          time.Now(),
-		scenarios:      []interface{}{},
-		undefinedSteps: []*gherkin.Step{},
-		succeededSteps: []*gherkin.Step{},
-		failedSteps:    []*gherkin.Step{},
-	}
+type fmtReporter struct {
 }
 
-type fmtReporter struct {
-	timer                   time.Time
-	scenarios               []interface{} // *gherkin.Scenario or *gherkin.ScenarioOutline
-	skippedScenarios        []*gherkin.Scenario
-	skippedScenarioOutlines []*gherkin.ScenarioOutline
-	undefinedSteps          []*gherkin.Step
-	succeededSteps          []*gherkin.Step
-	failedSteps             []*gherkin.Step
+func (r fmtReporter) Step(step *gherkin.Step) {
+	fmt.Printf("   %s %s\n", Yellow(step.Keyword), Green(step.Text))
 }
 
-func (r *fmtReporter) Scenario(scenario *gherkin.Scenario) {
+func (r fmtReporter) Scenario(scenario *gherkin.Scenario) {
 	if len(scenario.Tags) != 0 {
 		for _, tag := range scenario.Tags {
-			fmt.Printf("%s\n", Yellow(tag.Name))
+			fmt.Printf(" %s\n", Yellow(tag.Name))
 		}
 	}
-
-	fmt.Printf("%s: %s\n", scenario.Keyword, Gray(10, scenario.Name))
-	r.scenarios = append(r.scenarios, scenario)
+	fmt.Printf(" %s: %s\n", Yellow(scenario.Keyword), Green(scenario.Name))
 }
 
-func (r *fmtReporter) SkippedScenario(scenario *gherkin.Scenario) {
+func (r fmtReporter) ScenarioOutline(scenario *gherkin.ScenarioOutline) {
 	if len(scenario.Tags) != 0 {
 		for _, tag := range scenario.Tags {
-			fmt.Printf("%s\n", Yellow(tag.Name))
+			fmt.Printf(" %s\n", Yellow(tag.Name))
 		}
 	}
+	fmt.Printf(" %s: %s\n", Yellow(scenario.Keyword), Green(scenario.Name))
 
-	fmt.Printf("%s: %s\n", scenario.Keyword, Gray(10, scenario.Name))
-	r.skippedScenarios = append(r.skippedScenarios, scenario)
-}
+	for _, example := range scenario.Examples {
+		fmt.Printf(" %s:\n", Yellow(example.Keyword))
+	}
 
-func (r *fmtReporter) SkippedScenarioOutline(scenario *gherkin.ScenarioOutline) {
-	if len(scenario.Tags) != 0 {
-		for _, tag := range scenario.Tags {
-			fmt.Printf("%s\n", Yellow(tag.Name))
-		}
+	for _, step := range scenario.Steps {
+		fmt.Printf("     %s %s\n", Yellow(step.Keyword), Green(step.Text))
 	}
+}
 
-	fmt.Printf("%s: %s\n", scenario.Keyword, Blue(scenario.Name))
-	r.skippedScenarioOutlines = append(r.skippedScenarioOutlines, scenario)
+func (r fmtReporter) Undefined(s *gherkin.Step) {
+	fmt.Printf("   %s %s\n", Red("Undefined step"), Yellow(s.Text))
 }
 
-func (r *fmtReporter) Background(bkg *gherkin.Background) {
-	fmt.Printf("%s: %s\n", bkg.Keyword, Green(bkg.Name))
+func (r fmtReporter) Skip(s *gherkin.Step) {
+	fmt.Printf(" %s %s\n", s.Keyword, Gray(10, s.Text))
 }
 
-func (r *fmtReporter) UndefinedStep(step *gherkin.Step) {
-	fmt.Printf("  %s: %s\n", Red("Undefined step"), Yellow(step.Text))
-	r.undefinedSteps = append(r.undefinedSteps, step)
+func (r fmtReporter) Failed(step *gherkin.Step, e error) {
+	fmt.Printf("   %s %s\n", step.Keyword, Red(step.Text))
 }
 
-func (r *fmtReporter) SucceededStep(step *gherkin.Step) {
-	fmt.Printf("  %s: %s\n", Yellow(step.Keyword), Green(step.Text))
-	r.succeededSteps = append(r.succeededSteps, step)
+func (r fmtReporter) Background(background *gherkin.Background) {
+	fmt.Printf("  %s %s\n", Yellow(background.Keyword), Green(background.Name))
+	for _, s := range background.Steps {
+		r.Step(s)
+	}
 }
 
-func (r *fmtReporter) FailedStep(step *gherkin.Step, err error) {
-	fmt.Printf("  %s: %s\n", step.Keyword, Red(step.Text))
-	r.failedSteps = append(r.failedSteps, step)
+func (r fmtReporter) Feature(feature *gherkin.Feature) {
+	fmt.Printf("%s %s\n", Yellow(feature.Keyword), Green(feature.Name))
 }
 
-func (r *fmtReporter) ScenarioOutline(outline *gherkin.ScenarioOutline) {
-	if len(outline.Tags) != 0 {
-		for _, tag := range outline.Tags {
-			fmt.Printf("%s\n", Yellow(tag.Name))
+func (r fmtReporter) SkipScenario(s *gherkin.Scenario) {
+	if len(s.Tags) != 0 {
+		for _, tag := range s.Tags {
+			fmt.Printf(" %s\n", Yellow(tag.Name))
 		}
 	}
-	fmt.Printf("%s: %s\n", outline.Keyword, Green(outline.Name))
-	r.scenarios = append(r.scenarios, outline)
+	fmt.Printf(" %s: %s\n", Gray(10, s.Keyword), Gray(10, s.Name))
+	for _, step := range s.Steps {
+		r.Skip(step)
+	}
+}
+
+func (r fmtReporter) SkipScenarioOutline(s *gherkin.ScenarioOutline) {
+	if len(s.Tags) != 0 {
+		for _, tag := range s.Tags {
+			fmt.Printf(" %s\n", Yellow(tag.Name))
+		}
+	}
+	for _, example := range s.Examples {
+		fmt.Printf(" %s:\n", Gray(10, example.Keyword))
+	}
+
+	fmt.Printf(" %s: %s\n", Gray(10, s.Keyword), Gray(10, s.Name))
+	for _, step := range s.Steps {
+		r.Skip(step)
+	}
 }
 
-func (r fmtReporter) GenerateReport() {
-	fmt.Printf("%d scenarios\n", len(r.scenarios))
-	fmt.Printf("%d steps\n", len(r.succeededSteps))
-	if c := len(r.failedSteps); c > 0 {
-		fmt.Printf("%d failed steps\n", len(r.failedSteps))
+func (r fmtReporter) Report(report executionReport) {
+	fmt.Printf("%d scenarios\n", report.countScenarios)
+	fmt.Printf("%d steps\n", report.countSteps)
+	if c := report.countFailedSteps; c > 0 {
+		fmt.Printf("%d failed steps\n", report.countFailedSteps)
 	}
 
-	if c := len(r.undefinedSteps); c > 0 {
-		fmt.Printf("%d undefined steps\n", len(r.undefinedSteps))
+	if c := report.countUndefined; c > 0 {
+		fmt.Printf("%d undefined steps\n", report.countUndefined)
 	}
 
-	fmt.Printf("took %s\n", time.Since(r.timer).String())
+	fmt.Printf("took %s\n", report.timeTook.String())
 }
diff --git a/reporter/reporter.go b/reporter/reporter.go
index 81b3ec8..749850b 100644
--- a/reporter/reporter.go
+++ b/reporter/reporter.go
@@ -1,12 +1,135 @@
 package reporter
 
-import "github.com/cucumber/gherkin-go"
-
-type Reporter interface {
-	Scenario(scenario *gherkin.Scenario)
-	UndefinedStep(step *gherkin.Step)
-	SucceededStep(step *gherkin.Step)
-	FailedStep(step *gherkin.Step, err error)
-	ScenarioOutline(outline *gherkin.ScenarioOutline)
-	Background(bkg *gherkin.Background)
+import (
+	"fmt"
+	"time"
+
+	"github.com/cucumber/gherkin-go"
+)
+
+func NewReporter() *Reporter {
+	return &Reporter{
+		timer:          time.Now(),
+		scenarios:      []interface{}{},
+		undefinedSteps: []*gherkin.Step{},
+		succeededSteps: []*gherkin.Step{},
+		failedSteps:    []*gherkin.Step{},
+		skippedSteps:   []*gherkin.Step{},
+		backgrounds:    []*gherkin.Background{},
+	}
+}
+
+type Reporter struct {
+	timer            time.Time
+	output           fmtReporter
+	features         []*gherkin.Feature
+	scenarios        []interface{} // *gherkin.Scenario or *gherkin.ScenarioOutline
+	skippedScenarios []interface{} // *gherkin.Scenario or *gherkin.ScenarioOutline
+	undefinedSteps   []*gherkin.Step
+	succeededSteps   []*gherkin.Step
+	failedSteps      []*gherkin.Step
+	skippedSteps     []*gherkin.Step
+	backgrounds      []*gherkin.Background
+}
+
+type executionReport struct {
+	countScenarios   int
+	countSteps       int
+	countFailedSteps int
+	countUndefined   int
+	timeTook         time.Duration
+}
+
+func (r *Reporter) Report(reported interface{}) error {
+	switch reported.(type) {
+	case *gherkin.Step:
+		s := reported.(*gherkin.Step)
+		r.output.Step(s)
+
+		r.succeededSteps = append(r.succeededSteps, s)
+	case *gherkin.Scenario:
+		s := reported.(*gherkin.Scenario)
+		r.output.Scenario(s)
+		r.scenarios = append(r.scenarios, s)
+	case *gherkin.ScenarioOutline:
+		s := reported.(*gherkin.ScenarioOutline)
+		r.output.ScenarioOutline(s)
+		r.scenarios = append(r.scenarios, s)
+
+	case *gherkin.Feature:
+		f := reported.(*gherkin.Feature)
+		r.output.Feature(f)
+		r.features = append(r.features, f)
+	case *gherkin.Background:
+		s := reported.(*gherkin.Background)
+		r.output.Background(s)
+
+		r.backgrounds = append(r.backgrounds, s)
+	default:
+		return fmt.Errorf("%T", reported)
+	}
+
+	return nil
+}
+
+func (r *Reporter) Undefined(s *gherkin.Step) {
+	r.output.Undefined(s)
+	r.undefinedSteps = append(r.undefinedSteps, s)
+}
+
+func (r *Reporter) Skip(reported interface{}) {
+	switch reported.(type) {
+	case *gherkin.Step:
+		s := reported.(*gherkin.Step)
+		r.output.Skip(s)
+
+		r.skippedSteps = append(r.skippedSteps, s)
+	case *gherkin.Scenario:
+		s := reported.(*gherkin.Scenario)
+		r.output.SkipScenario(s)
+		r.skippedScenarios = append(r.skippedScenarios, s)
+	case *gherkin.ScenarioOutline:
+		s := reported.(*gherkin.ScenarioOutline)
+		r.output.SkipScenarioOutline(s)
+		r.skippedScenarios = append(r.skippedScenarios, s)
+	default:
+		panic("should never happen")
+	}
+}
+
+func (r *Reporter) Failed(s *gherkin.Step, err error) {
+	r.output.Failed(s, err)
+	r.failedSteps = append(r.failedSteps, s)
+}
+
+func (r Reporter) GenerateReport() {
+	er := executionReport{
+		countScenarios:   r.countScenarios(),
+		countSteps:       r.countSteps(),
+		countFailedSteps: r.countFailed(),
+		countUndefined:   r.countUndefined(),
+		timeTook:         time.Since(r.timer),
+	}
+
+	r.output.Report(er)
+}
+
+func (r Reporter) countScenarios() int {
+	return len(r.scenarios)
+}
+
+func (r Reporter) countSteps() int {
+	return len(r.succeededSteps)
+}
+
+func (r *Reporter) countUndefined() int {
+	return len(r.undefinedSteps)
+}
+
+func (r *Reporter) countFailed() int {
+	return len(r.failedSteps)
+}
+
+func (r *Reporter) countSkippedSteps() int {
+	return len(r.skippedSteps)
 }


Test patch:
diff --git a/reporter/reporter_test.go b/reporter/reporter_test.go
new file mode 100644
index 0000000..409fffa
--- /dev/null
+++ b/reporter/reporter_test.go
@@ -0,0 +1,45 @@
+package reporter
+
+import (
+	"errors"
+	"testing"
+
+	"github.com/cucumber/gherkin-go"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestReporter_Report(t *testing.T) {
+	step := &gherkin.Step{}
+	r := NewReporter()
+	err := r.Report(step)
+	assert.NoError(t, err)
+	assert.Equal(t, 1, r.countSteps())
+}
+
+func TestReporter_Report_Invalid_Type(t *testing.T) {
+	r := NewReporter()
+	err := r.Report("this shouldn't go here")
+	assert.Error(t, err)
+	assert.Equal(t, 0, r.countSteps())
+}
+
+func TestReporter_Undefined(t *testing.T) {
+	step := &gherkin.Step{}
+	r := NewReporter()
+	r.Undefined(step)
+	assert.Equal(t, 1, r.countUndefined())
+}
+
+func TestReporter_Failed(t *testing.T) {
+	step := &gherkin.Step{}
+	r := NewReporter()
+	r.Failed(step, errors.New("some error"))
+	assert.Equal(t, 1, r.countFailed())
+}
+
+func TestReporter_Skip_Step(t *testing.T) {
+	step := &gherkin.Step{}
+	r := NewReporter()
+	r.Skip(step)
+	assert.Equal(t, 1, r.countSkippedSteps())
+}