* Pretty Print when using rules (#440) * Pretty Print when using rules (#440) * fix a few formatting mistakes (#440) * added test with rule and scenario outline (#440)
Этот коммит содержится в:
родитель
c5a86a4e56
коммит
5d705e5b8e
8 изменённых файлов: 368 добавлений и 19 удалений
|
@ -449,3 +449,102 @@ Feature: pretty formatter
|
||||||
16 steps (16 passed)
|
16 steps (16 passed)
|
||||||
0s
|
0s
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
Scenario: Support of Feature Plus Rule
|
||||||
|
Given a feature "features/simple.feature" file:
|
||||||
|
"""
|
||||||
|
Feature: simple feature with a rule
|
||||||
|
simple feature description
|
||||||
|
Rule: simple rule
|
||||||
|
simple rule description
|
||||||
|
Example: simple scenario
|
||||||
|
simple scenario description
|
||||||
|
Given passing step
|
||||||
|
"""
|
||||||
|
When I run feature suite with formatter "pretty"
|
||||||
|
Then the rendered output will be as follows:
|
||||||
|
"""
|
||||||
|
Feature: simple feature with a rule
|
||||||
|
simple feature description
|
||||||
|
|
||||||
|
Example: simple scenario # features/simple.feature:5
|
||||||
|
Given passing step # suite_context.go:0 -> SuiteContext.func2
|
||||||
|
|
||||||
|
1 scenarios (1 passed)
|
||||||
|
1 steps (1 passed)
|
||||||
|
0s
|
||||||
|
"""
|
||||||
|
|
||||||
|
Scenario: Support of Feature Plus Rule with Background
|
||||||
|
Given a feature "features/simple.feature" file:
|
||||||
|
"""
|
||||||
|
Feature: simple feature with a rule with Background
|
||||||
|
simple feature description
|
||||||
|
Rule: simple rule
|
||||||
|
simple rule description
|
||||||
|
Background:
|
||||||
|
Given passing step
|
||||||
|
Example: simple scenario
|
||||||
|
simple scenario description
|
||||||
|
Given passing step
|
||||||
|
"""
|
||||||
|
When I run feature suite with formatter "pretty"
|
||||||
|
Then the rendered output will be as follows:
|
||||||
|
"""
|
||||||
|
Feature: simple feature with a rule with Background
|
||||||
|
simple feature description
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given passing step # suite_context.go:0 -> SuiteContext.func2
|
||||||
|
|
||||||
|
Example: simple scenario # features/simple.feature:7
|
||||||
|
Given passing step # suite_context.go:0 -> SuiteContext.func2
|
||||||
|
|
||||||
|
1 scenarios (1 passed)
|
||||||
|
2 steps (2 passed)
|
||||||
|
0s
|
||||||
|
"""
|
||||||
|
|
||||||
|
Scenario: Support of Feature Plus Rule with Scenario Outline
|
||||||
|
Given a feature "features/simple.feature" file:
|
||||||
|
"""
|
||||||
|
Feature: simple feature with a rule with Scenario Outline
|
||||||
|
simple feature description
|
||||||
|
Rule: simple rule
|
||||||
|
simple rule description
|
||||||
|
Scenario Outline: simple scenario
|
||||||
|
simple scenario description
|
||||||
|
|
||||||
|
Given <status> step
|
||||||
|
|
||||||
|
Examples: simple examples
|
||||||
|
| status |
|
||||||
|
| passing |
|
||||||
|
| failing |
|
||||||
|
"""
|
||||||
|
When I run feature suite with formatter "pretty"
|
||||||
|
Then the rendered output will be as follows:
|
||||||
|
"""
|
||||||
|
Feature: simple feature with a rule with Scenario Outline
|
||||||
|
simple feature description
|
||||||
|
|
||||||
|
Scenario Outline: simple scenario # features/simple.feature:5
|
||||||
|
Given <status> step # suite_context.go:0 -> SuiteContext.func2
|
||||||
|
|
||||||
|
Examples: simple examples
|
||||||
|
| status |
|
||||||
|
| passing |
|
||||||
|
| failing |
|
||||||
|
intentional failure
|
||||||
|
|
||||||
|
--- Failed steps:
|
||||||
|
|
||||||
|
Scenario Outline: simple scenario # features/simple.feature:5
|
||||||
|
Given failing step # features/simple.feature:8
|
||||||
|
Error: intentional failure
|
||||||
|
|
||||||
|
|
||||||
|
2 scenarios (1 passed, 1 failed)
|
||||||
|
2 steps (1 passed, 1 failed)
|
||||||
|
0s
|
||||||
|
"""
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/cucumber/godog/colors"
|
"github.com/cucumber/godog/colors"
|
||||||
"github.com/cucumber/godog/formatters"
|
"github.com/cucumber/godog/formatters"
|
||||||
|
"github.com/cucumber/godog/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -350,15 +351,38 @@ func (f *Pretty) printTableHeader(row *messages.TableRow, max []int) {
|
||||||
f.printTableRow(row, max, cyan)
|
f.printTableRow(row, max, cyan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isFirstScenarioInRule(rule *messages.Rule, scenario *messages.Scenario) bool {
|
||||||
|
if rule == nil || scenario == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var firstScenario *messages.Scenario
|
||||||
|
for _, c := range rule.Children {
|
||||||
|
if c.Scenario != nil {
|
||||||
|
firstScenario = c.Scenario
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstScenario != nil && firstScenario.Id == scenario.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFirstPickleAndNoRule(feature *models.Feature, pickle *messages.Pickle, rule *messages.Rule) bool {
|
||||||
|
if rule != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return feature.Pickles[0].Id == pickle.Id
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
func (f *Pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
||||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
|
astRule := feature.FindRule(pickle.AstNodeIds[0])
|
||||||
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
var astBackgroundStep bool
|
var astBackgroundStep bool
|
||||||
var firstExecutedBackgroundStep bool
|
var firstExecutedBackgroundStep bool
|
||||||
var backgroundSteps int
|
var backgroundSteps int
|
||||||
|
|
||||||
if astBackground != nil {
|
if astBackground != nil {
|
||||||
backgroundSteps = len(astBackground.Steps)
|
backgroundSteps = len(astBackground.Steps)
|
||||||
|
|
||||||
|
@ -371,7 +395,7 @@ func (f *Pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstPickle := feature.Pickles[0].Id == pickle.Id
|
firstPickle := isFirstPickleAndNoRule(feature, pickle, astRule) || isFirstScenarioInRule(astRule, astScenario)
|
||||||
|
|
||||||
if astBackgroundStep && !firstPickle {
|
if astBackgroundStep && !firstPickle {
|
||||||
return
|
return
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
Feature: rules with examples with backgrounds
|
||||||
|
|
||||||
|
Rule: first rule
|
||||||
|
|
||||||
|
Background: for first rule
|
||||||
|
Given passing step
|
||||||
|
And passing step
|
||||||
|
|
||||||
|
Example: rule 1 example 1
|
||||||
|
When passing step
|
||||||
|
Then passing step
|
||||||
|
|
||||||
|
Example: rule 1 example 2
|
||||||
|
When passing step
|
||||||
|
Then passing step
|
||||||
|
|
||||||
|
|
||||||
|
Rule: second rule
|
||||||
|
|
||||||
|
Background: for second rule
|
||||||
|
Given passing step
|
||||||
|
And passing step
|
||||||
|
|
||||||
|
Example: rule 1 example 1
|
||||||
|
When passing step
|
||||||
|
Then passing step
|
||||||
|
|
||||||
|
Example: rule 2 example 2
|
||||||
|
When passing step
|
||||||
|
Then passing step
|
|
@ -0,0 +1,29 @@
|
||||||
|
<bold-white>Feature:</bold-white> rules with examples with backgrounds
|
||||||
|
|
||||||
|
<bold-white>Background:</bold-white> for first rule
|
||||||
|
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
|
||||||
|
<bold-white>Example:</bold-white> rule 1 example 1 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:9</bold-black>
|
||||||
|
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
|
||||||
|
<bold-white>Example:</bold-white> rule 1 example 2 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:13</bold-black>
|
||||||
|
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
|
||||||
|
<bold-white>Background:</bold-white> for second rule
|
||||||
|
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
|
||||||
|
<bold-white>Example:</bold-white> rule 1 example 1 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:24</bold-black>
|
||||||
|
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
|
||||||
|
<bold-white>Example:</bold-white> rule 2 example 2 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:28</bold-black>
|
||||||
|
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||||
|
|
||||||
|
4 scenarios (<green>4 passed</green>)
|
||||||
|
16 steps (<green>16 passed</green>)
|
||||||
|
0s
|
|
@ -13,12 +13,35 @@ type Feature struct {
|
||||||
Content []byte
|
Content []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindScenario ...
|
// FindRule returns the rule to which the given scenario belongs
|
||||||
|
func (f Feature) FindRule(astScenarioID string) *messages.Rule {
|
||||||
|
for _, child := range f.GherkinDocument.Feature.Children {
|
||||||
|
if ru := child.Rule; ru != nil {
|
||||||
|
if rc := child.Rule; rc != nil {
|
||||||
|
for _, rcc := range rc.Children {
|
||||||
|
if sc := rcc.Scenario; sc != nil && sc.Id == astScenarioID {
|
||||||
|
return ru
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindScenario returns the scenario in the feature or in a rule in the feature
|
||||||
func (f Feature) FindScenario(astScenarioID string) *messages.Scenario {
|
func (f Feature) FindScenario(astScenarioID string) *messages.Scenario {
|
||||||
for _, child := range f.GherkinDocument.Feature.Children {
|
for _, child := range f.GherkinDocument.Feature.Children {
|
||||||
if sc := child.Scenario; sc != nil && sc.Id == astScenarioID {
|
if sc := child.Scenario; sc != nil && sc.Id == astScenarioID {
|
||||||
return sc
|
return sc
|
||||||
}
|
}
|
||||||
|
if rc := child.Rule; rc != nil {
|
||||||
|
for _, rcc := range rc.Children {
|
||||||
|
if sc := rcc.Scenario; sc != nil && sc.Id == astScenarioID {
|
||||||
|
return sc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -36,6 +59,18 @@ func (f Feature) FindBackground(astScenarioID string) *messages.Background {
|
||||||
if sc := child.Scenario; sc != nil && sc.Id == astScenarioID {
|
if sc := child.Scenario; sc != nil && sc.Id == astScenarioID {
|
||||||
return bg
|
return bg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ru := child.Rule; ru != nil {
|
||||||
|
for _, rc := range ru.Children {
|
||||||
|
if tmp := rc.Background; tmp != nil {
|
||||||
|
bg = tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
if sc := rc.Scenario; sc != nil && sc.Id == astScenarioID {
|
||||||
|
return bg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -53,6 +88,19 @@ func (f Feature) FindExample(exampleAstID string) (*messages.Examples, *messages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ru := child.Rule; ru != nil {
|
||||||
|
for _, rc := range ru.Children {
|
||||||
|
if sc := rc.Scenario; sc != nil {
|
||||||
|
for _, example := range sc.Examples {
|
||||||
|
for _, row := range example.TableBody {
|
||||||
|
if row.Id == exampleAstID {
|
||||||
|
return example, row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -61,6 +109,27 @@ func (f Feature) FindExample(exampleAstID string) (*messages.Examples, *messages
|
||||||
// FindStep ...
|
// FindStep ...
|
||||||
func (f Feature) FindStep(astStepID string) *messages.Step {
|
func (f Feature) FindStep(astStepID string) *messages.Step {
|
||||||
for _, child := range f.GherkinDocument.Feature.Children {
|
for _, child := range f.GherkinDocument.Feature.Children {
|
||||||
|
|
||||||
|
if ru := child.Rule; ru != nil {
|
||||||
|
for _, ch := range ru.Children {
|
||||||
|
if sc := ch.Scenario; sc != nil {
|
||||||
|
for _, step := range sc.Steps {
|
||||||
|
if step.Id == astStepID {
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if bg := ch.Background; bg != nil {
|
||||||
|
for _, step := range bg.Steps {
|
||||||
|
if step.Id == astStepID {
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sc := child.Scenario; sc != nil {
|
if sc := child.Scenario; sc != nil {
|
||||||
for _, step := range sc.Steps {
|
for _, step := range sc.Steps {
|
||||||
if step.Id == astStepID {
|
if step.Id == astStepID {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package models_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cucumber/godog/internal/models"
|
||||||
"github.com/cucumber/godog/internal/testutils"
|
"github.com/cucumber/godog/internal/testutils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -32,11 +33,57 @@ func Test_Find(t *testing.T) {
|
||||||
assert.NotNilf(t, step, "expected step to not be nil")
|
assert.NotNilf(t, step, "expected step to not be nil")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("rule", func(t *testing.T) {
|
||||||
|
sc := ft.FindRule(ft.Pickles[0].AstNodeIds[0])
|
||||||
|
assert.Nilf(t, sc, "expected rule to be nil")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_FindInRule(t *testing.T) {
|
||||||
|
|
||||||
|
ft := testutils.BuildTestFeatureWithRules(t)
|
||||||
|
|
||||||
|
t.Run("rule", func(t *testing.T) {
|
||||||
|
sc := ft.FindRule(ft.Pickles[0].AstNodeIds[0])
|
||||||
|
assert.NotNilf(t, sc, "expected rule to not be nil")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("scenario", func(t *testing.T) {
|
||||||
|
sc := ft.FindScenario(ft.Pickles[0].AstNodeIds[0])
|
||||||
|
assert.NotNilf(t, sc, "expected scenario to not be nil")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("background", func(t *testing.T) {
|
||||||
|
bg := ft.FindBackground(ft.Pickles[0].AstNodeIds[0])
|
||||||
|
assert.NotNilf(t, bg, "expected background to not be nil")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("example", func(t *testing.T) {
|
||||||
|
example, row := ft.FindExample(ft.Pickles[1].AstNodeIds[1])
|
||||||
|
assert.NotNilf(t, example, "expected example to not be nil")
|
||||||
|
assert.NotNilf(t, row, "expected table row to not be nil")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("step", func(t *testing.T) {
|
||||||
|
for _, ps := range ft.Pickles[0].Steps {
|
||||||
|
step := ft.FindStep(ps.AstNodeIds[0])
|
||||||
|
assert.NotNilf(t, step, "expected step to not be nil")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_NotFind(t *testing.T) {
|
func Test_NotFind(t *testing.T) {
|
||||||
ft := testutils.BuildTestFeature(t)
|
testCases := []struct {
|
||||||
|
Feature models.Feature
|
||||||
|
}{
|
||||||
|
{testutils.BuildTestFeature(t)},
|
||||||
|
{testutils.BuildTestFeatureWithRules(t)},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
|
||||||
|
ft := tc.Feature
|
||||||
t.Run("scenario", func(t *testing.T) {
|
t.Run("scenario", func(t *testing.T) {
|
||||||
sc := ft.FindScenario("-")
|
sc := ft.FindScenario("-")
|
||||||
assert.Nilf(t, sc, "expected scenario to be nil")
|
assert.Nilf(t, sc, "expected scenario to be nil")
|
||||||
|
@ -58,3 +105,4 @@ func Test_NotFind(t *testing.T) {
|
||||||
assert.Nilf(t, step, "expected step to be nil")
|
assert.Nilf(t, step, "expected step to be nil")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -58,3 +58,53 @@ Scenario Outline: Eat <dec> out of <beginning>
|
||||||
Examples:
|
Examples:
|
||||||
| begin | dec | remain |
|
| begin | dec | remain |
|
||||||
| 12 | 5 | 7 |`
|
| 12 | 5 | 7 |`
|
||||||
|
|
||||||
|
// BuildTestFeature creates a feature with rules for testing purpose.
|
||||||
|
//
|
||||||
|
// The created feature includes:
|
||||||
|
// - a background
|
||||||
|
// - one normal scenario with three steps
|
||||||
|
// - one outline scenario with one example and three steps
|
||||||
|
func BuildTestFeatureWithRules(t *testing.T) models.Feature {
|
||||||
|
newIDFunc := (&messages.Incrementing{}).NewId
|
||||||
|
|
||||||
|
gherkinDocument, err := gherkin.ParseGherkinDocument(strings.NewReader(featureWithRuleContent), newIDFunc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
path := t.Name()
|
||||||
|
gherkinDocument.Uri = path
|
||||||
|
pickles := gherkin.Pickles(*gherkinDocument, path, newIDFunc)
|
||||||
|
|
||||||
|
ft := models.Feature{GherkinDocument: gherkinDocument, Pickles: pickles, Content: []byte(featureWithRuleContent)}
|
||||||
|
require.Len(t, ft.Pickles, 2)
|
||||||
|
|
||||||
|
require.Len(t, ft.Pickles[0].AstNodeIds, 1)
|
||||||
|
require.Len(t, ft.Pickles[0].Steps, 3)
|
||||||
|
|
||||||
|
require.Len(t, ft.Pickles[1].AstNodeIds, 2)
|
||||||
|
require.Len(t, ft.Pickles[1].Steps, 3)
|
||||||
|
|
||||||
|
return ft
|
||||||
|
}
|
||||||
|
|
||||||
|
const featureWithRuleContent = `Feature: eat godogs
|
||||||
|
In order to be happy
|
||||||
|
As a hungry gopher
|
||||||
|
I need to be able to eat godogs
|
||||||
|
|
||||||
|
Rule: eating godogs
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given there are <begin> godogs
|
||||||
|
|
||||||
|
Scenario: Eat 5 out of 12
|
||||||
|
When I eat 5
|
||||||
|
Then there should be 7 remaining
|
||||||
|
|
||||||
|
Scenario Outline: Eat <dec> out of <beginning>
|
||||||
|
When I eat <dec>
|
||||||
|
Then there should be <remain> remaining
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| begin | dec | remain |
|
||||||
|
| 12 | 5 | 7 |`
|
||||||
|
|
12
run_test.go
12
run_test.go
|
@ -432,11 +432,11 @@ func Test_AllFeaturesRun(t *testing.T) {
|
||||||
...................................................................... 140
|
...................................................................... 140
|
||||||
...................................................................... 210
|
...................................................................... 210
|
||||||
...................................................................... 280
|
...................................................................... 280
|
||||||
........................................ 320
|
................................................. 329
|
||||||
|
|
||||||
|
|
||||||
83 scenarios (83 passed)
|
86 scenarios (86 passed)
|
||||||
320 steps (320 passed)
|
329 steps (329 passed)
|
||||||
0s
|
0s
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -459,11 +459,11 @@ func Test_AllFeaturesRunAsSubtests(t *testing.T) {
|
||||||
...................................................................... 140
|
...................................................................... 140
|
||||||
...................................................................... 210
|
...................................................................... 210
|
||||||
...................................................................... 280
|
...................................................................... 280
|
||||||
........................................ 320
|
................................................. 329
|
||||||
|
|
||||||
|
|
||||||
83 scenarios (83 passed)
|
86 scenarios (86 passed)
|
||||||
320 steps (320 passed)
|
329 steps (329 passed)
|
||||||
0s
|
0s
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче