Skip to content

Commit 888fe3f

Browse files
authored
Improve ErrSkip handling, add test for Summary and operations order (#584)
1 parent 25274b0 commit 888fe3f

File tree

2 files changed

+163
-7
lines changed

2 files changed

+163
-7
lines changed

internal/formatters/fmt_base_test.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package formatters_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"errors"
7+
"fmt"
8+
"testing"
9+
10+
"github.com/cucumber/godog"
11+
"github.com/cucumber/godog/internal/flags"
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func TestBase_Summary(t *testing.T) {
16+
var features []flags.Feature
17+
18+
features = append(features,
19+
flags.Feature{Name: "f1", Contents: []byte(`
20+
Feature: f1
21+
22+
Scenario: f1s1
23+
When step passed f1s1:1
24+
Then step failed f1s1:2
25+
`)},
26+
flags.Feature{Name: "f2", Contents: []byte(`
27+
Feature: f2
28+
29+
Scenario: f2s1
30+
When step passed f2s1:1
31+
Then step passed f2s1:2
32+
33+
Scenario: f2s2
34+
When step failed f2s2:1
35+
Then step passed f2s2:2
36+
37+
Scenario: f2s3
38+
When step passed f2s3:1
39+
Then step skipped f2s3:2
40+
And step passed f2s3:3
41+
And step failed f2s3:4
42+
43+
Scenario: f2s4
44+
When step passed f2s4:1
45+
Then step is undefined f2s4:2
46+
And step passed f2s4:3
47+
`)},
48+
)
49+
50+
out := bytes.NewBuffer(nil)
51+
suite := godog.TestSuite{
52+
ScenarioInitializer: func(sc *godog.ScenarioContext) {
53+
sc.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
54+
if err != nil {
55+
_, _ = out.WriteString(fmt.Sprintf("scenario %q ended with error %q\n", sc.Name, err.Error()))
56+
} else {
57+
_, _ = out.WriteString(fmt.Sprintf("scenario %q passed\n", sc.Name))
58+
}
59+
60+
return ctx, nil
61+
})
62+
sc.StepContext().After(func(ctx context.Context, st *godog.Step, status godog.StepResultStatus, err error) (context.Context, error) {
63+
_, _ = out.WriteString(fmt.Sprintf("step %q finished with status %s\n", st.Text, status.String()))
64+
return ctx, nil
65+
})
66+
sc.Step("failed (.+)", func(s string) error {
67+
_, _ = out.WriteString(fmt.Sprintf("\nstep invoked: %q, failed\n", s))
68+
return errors.New("failed")
69+
})
70+
sc.Step("skipped (.+)", func(s string) error {
71+
_, _ = out.WriteString(fmt.Sprintf("\nstep invoked: %q, skipped\n", s))
72+
return godog.ErrSkip
73+
})
74+
sc.Step("passed (.+)", func(s string) {
75+
_, _ = out.WriteString(fmt.Sprintf("\nstep invoked: %q, passed\n", s))
76+
})
77+
},
78+
Options: &godog.Options{
79+
Output: out,
80+
NoColors: true,
81+
Strict: true,
82+
Format: "progress",
83+
FeatureContents: features,
84+
},
85+
}
86+
87+
assert.Equal(t, 1, suite.Run())
88+
assert.Equal(t, `
89+
step invoked: "f1s1:1", passed
90+
step "step passed f1s1:1" finished with status passed
91+
.
92+
step invoked: "f1s1:2", failed
93+
step "step failed f1s1:2" finished with status failed
94+
scenario "f1s1" ended with error "failed"
95+
F
96+
step invoked: "f2s1:1", passed
97+
step "step passed f2s1:1" finished with status passed
98+
.
99+
step invoked: "f2s1:2", passed
100+
step "step passed f2s1:2" finished with status passed
101+
scenario "f2s1" passed
102+
.
103+
step invoked: "f2s2:1", failed
104+
step "step failed f2s2:1" finished with status failed
105+
scenario "f2s2" ended with error "failed"
106+
F-step "step passed f2s2:2" finished with status skipped
107+
108+
step invoked: "f2s3:1", passed
109+
step "step passed f2s3:1" finished with status passed
110+
.
111+
step invoked: "f2s3:2", skipped
112+
step "step skipped f2s3:2" finished with status skipped
113+
--step "step passed f2s3:3" finished with status skipped
114+
-step "step failed f2s3:4" finished with status skipped
115+
scenario "f2s3" passed
116+
117+
step invoked: "f2s4:1", passed
118+
step "step passed f2s4:1" finished with status passed
119+
.Ustep "step is undefined f2s4:2" finished with status undefined
120+
scenario "f2s4" ended with error "step is undefined"
121+
-step "step passed f2s4:3" finished with status skipped
122+
13
123+
124+
125+
--- Failed steps:
126+
127+
Scenario: f1s1 # f1:4
128+
Then step failed f1s1:2 # f1:6
129+
Error: failed
130+
131+
Scenario: f2s2 # f2:8
132+
When step failed f2s2:1 # f2:9
133+
Error: failed
134+
135+
136+
5 scenarios (2 passed, 2 failed, 1 undefined)
137+
13 steps (5 passed, 2 failed, 1 undefined, 5 skipped)
138+
0s
139+
140+
You can implement step definitions for undefined steps with these snippets:
141+
142+
func stepIsUndefinedFS(arg1, arg2, arg3 int) error {
143+
return godog.ErrPending
144+
}
145+
146+
func InitializeScenario(ctx *godog.ScenarioContext) {
147+
ctx.Step(`+"`"+`^step is undefined f(\d+)s(\d+):(\d+)$`+"`"+`, stepIsUndefinedFS)
148+
}
149+
150+
`, out.String())
151+
}

suite.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scena
101101
}
102102
}
103103

104-
earlyReturn := scenarioErr != nil || err == ErrUndefined
104+
earlyReturn := scenarioErr != nil || errors.Is(err, ErrUndefined)
105105

106106
switch {
107107
case errors.Is(err, ErrPending):
108108
sr.Status = StepPending
109-
case errors.Is(err, ErrSkip) || (err == nil && scenarioErr != nil):
109+
case errors.Is(err, ErrSkip), err == nil && scenarioErr != nil:
110110
sr.Status = StepSkipped
111111
case errors.Is(err, ErrUndefined):
112112
sr.Status = StepUndefined
@@ -130,17 +130,22 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scena
130130
return
131131
}
132132

133-
switch err {
134-
case nil:
133+
switch {
134+
case err == nil:
135135
sr.Status = models.Passed
136136
s.storage.MustInsertPickleStepResult(sr)
137137

138138
s.fmt.Passed(pickle, step, match.GetInternalStepDefinition())
139-
case ErrPending:
139+
case errors.Is(err, ErrPending):
140140
sr.Status = models.Pending
141141
s.storage.MustInsertPickleStepResult(sr)
142142

143143
s.fmt.Pending(pickle, step, match.GetInternalStepDefinition())
144+
case errors.Is(err, ErrSkip):
145+
sr.Status = models.Skipped
146+
s.storage.MustInsertPickleStepResult(sr)
147+
148+
s.fmt.Skipped(pickle, step, match.GetInternalStepDefinition())
144149
default:
145150
sr.Status = models.Failed
146151
sr.Err = err
@@ -481,11 +486,11 @@ func (s *suite) runSteps(ctx context.Context, pickle *Scenario, steps []*Step) (
481486
}
482487

483488
func (s *suite) shouldFail(err error) bool {
484-
if err == nil || err == ErrSkip {
489+
if err == nil || errors.Is(err, ErrSkip) {
485490
return false
486491
}
487492

488-
if err == ErrUndefined || err == ErrPending {
493+
if errors.Is(err, ErrUndefined) || errors.Is(err, ErrPending) {
489494
return s.strict
490495
}
491496

0 commit comments

Comments
 (0)