initial tests for event stream formatter

Этот коммит содержится в:
gedi 2016-05-22 17:40:42 +03:00
родитель e71d596404
коммит c50c2dc368
5 изменённых файлов: 163 добавлений и 13 удалений

78
features/formatter/events.feature Обычный файл
Просмотреть файл

@ -0,0 +1,78 @@
Feature: event stream formatter
In order to have universal cucumber formatter
As a test suite
I need to be able to support event stream formatter
Scenario: should fire only suite events without any scenario
Given a feature path "features/load.feature:4"
When I run feature suite with formatter "events"
Then the following events should be fired:
"""
TestRunStarted
TestSource
TestRunFinished
"""
Scenario: should process simple scenario
Given a feature path "features/load.feature:21"
When I run feature suite with formatter "events"
Then the following events should be fired:
"""
TestRunStarted
TestSource
TestCaseStarted
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
TestCaseFinished
TestRunFinished
"""
Scenario: should process outline scenario
Given a feature path "features/load.feature:29"
When I run feature suite with formatter "events"
Then the following events should be fired:
"""
TestRunStarted
TestSource
TestCaseStarted
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
TestCaseFinished
TestCaseStarted
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
TestCaseFinished
TestCaseStarted
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
StepDefinitionFound
TestStepStarted
TestStepFinished
TestCaseFinished
TestRunFinished
"""

Просмотреть файл

@ -8,10 +8,11 @@ Savybė: užkrauti savybes
Scenarijus: savybių užkrovimas iš aplanko
Duota savybių aplankas "features"
Kai aš išskaitau savybes
Tada aš turėčiau turėti 7 savybių failus:
Tada aš turėčiau turėti 8 savybių failus:
"""
features/background.feature
features/events.feature
features/formatter/events.feature
features/lang.feature
features/load.feature
features/outline.feature

Просмотреть файл

@ -6,10 +6,11 @@ Feature: load features
Scenario: load features within path
Given a feature path "features"
When I parse features
Then I should have 7 feature files:
Then I should have 8 feature files:
"""
features/background.feature
features/events.feature
features/formatter/events.feature
features/lang.feature
features/load.feature
features/outline.feature

Просмотреть файл

@ -1,12 +1,27 @@
package godog
import "github.com/DATA-DOG/godog/gherkin"
import (
"io"
"time"
"github.com/DATA-DOG/godog/gherkin"
)
type testFormatter struct {
basefmt
scenarios []interface{}
}
func testFormatterFunc(out io.Writer) Formatter {
return &testFormatter{
basefmt: basefmt{
started: time.Now(),
indent: 2,
out: out,
},
}
}
func (f *testFormatter) Node(node interface{}) {
f.basefmt.Node(node)
switch t := node.(type) {

Просмотреть файл

@ -1,6 +1,8 @@
package godog
import (
"bytes"
"encoding/json"
"fmt"
"path/filepath"
"strconv"
@ -18,6 +20,7 @@ func SuiteContext(s *Suite) {
s.Step(`^I parse features$`, c.parseFeatures)
s.Step(`^I'm listening to suite events$`, c.iAmListeningToSuiteEvents)
s.Step(`^I run feature suite$`, c.iRunFeatureSuite)
s.Step(`^I run feature suite with formatter "([^"]*)"$`, c.iRunFeatureSuiteWithFormatter)
s.Step(`^a feature "([^"]*)" file:$`, c.aFeatureFile)
s.Step(`^the suite should have (passed|failed)$`, c.theSuiteShouldHave)
@ -32,6 +35,9 @@ func SuiteContext(s *Suite) {
s.Step(`^the following steps? should be (passed|failed|skipped|undefined|pending):`, c.followingStepsShouldHave)
s.Step(`^the undefined step snippets should be:$`, c.theUndefinedStepSnippetsShouldBe)
// event stream
s.Step(`^the following events should be fired:$`, c.thereShouldBeEventsFired)
// lt
s.Step(`^savybių aplankas "([^"]*)"$`, c.featurePath)
s.Step(`^aš išskaitau savybes$`, c.parseFeatures)
@ -54,20 +60,59 @@ type suiteContext struct {
paths []string
testedSuite *Suite
events []*firedEvent
fmt *testFormatter
out bytes.Buffer
}
func (s *suiteContext) ResetBeforeEachScenario(interface{}) {
// reset whole suite with the state
s.fmt = &testFormatter{}
s.out.Reset()
s.paths = []string{}
s.testedSuite = &Suite{fmt: s.fmt}
s.testedSuite = &Suite{}
// our tested suite will have the same context registered
SuiteContext(s.testedSuite)
// reset all fired events
s.events = []*firedEvent{}
}
func (s *suiteContext) iRunFeatureSuiteWithFormatter(name string) error {
f, err := findFmt(name)
if err != nil {
return err
}
s.testedSuite.fmt = f(&s.out)
if err := s.parseFeatures(); err != nil {
return err
}
s.testedSuite.run()
s.testedSuite.fmt.Summary()
return nil
}
func (s *suiteContext) thereShouldBeEventsFired(doc *gherkin.DocString) error {
actual := strings.Split(strings.TrimSpace(s.out.String()), "\n")
expect := strings.Split(strings.TrimSpace(doc.Content), "\n")
if len(expect) != len(actual) {
return fmt.Errorf("expected %d events, but got %d", len(expect), len(actual))
}
type ev struct {
Event string
}
for i, event := range actual {
exp := strings.TrimSpace(expect[i])
var act ev
if err := json.Unmarshal([]byte(event), &act); err != nil {
return fmt.Errorf("failed to read event data: %v", err)
}
if act.Event != exp {
return fmt.Errorf(`expected event: "%s" at position: %d, but actual was "%s"`, exp, i, act.Event)
}
}
return nil
}
func (s *suiteContext) cleanupSnippet(snip string) string {
lines := strings.Split(strings.TrimSpace(snip), "\n")
for i := 0; i < len(lines); i++ {
@ -77,10 +122,14 @@ func (s *suiteContext) cleanupSnippet(snip string) string {
}
func (s *suiteContext) theUndefinedStepSnippetsShouldBe(body *gherkin.DocString) error {
actual := s.cleanupSnippet(s.fmt.snippets())
f, ok := s.testedSuite.fmt.(*testFormatter)
if !ok {
return fmt.Errorf("this step requires testFormatter, but there is: %T", s.testedSuite.fmt)
}
actual := s.cleanupSnippet(f.snippets())
expected := s.cleanupSnippet(body.Content)
if actual != expected {
return fmt.Errorf("snippets do not match actual: %s", s.fmt.snippets())
return fmt.Errorf("snippets do not match actual: %s", f.snippets())
}
return nil
}
@ -89,25 +138,29 @@ func (s *suiteContext) followingStepsShouldHave(status string, steps *gherkin.Do
var expected = strings.Split(steps.Content, "\n")
var actual, unmatched, matched []string
f, ok := s.testedSuite.fmt.(*testFormatter)
if !ok {
return fmt.Errorf("this step requires testFormatter, but there is: %T", s.testedSuite.fmt)
}
switch status {
case "passed":
for _, st := range s.fmt.passed {
for _, st := range f.passed {
actual = append(actual, st.step.Text)
}
case "failed":
for _, st := range s.fmt.failed {
for _, st := range f.failed {
actual = append(actual, st.step.Text)
}
case "skipped":
for _, st := range s.fmt.skipped {
for _, st := range f.skipped {
actual = append(actual, st.step.Text)
}
case "undefined":
for _, st := range s.fmt.undefined {
for _, st := range f.undefined {
actual = append(actual, st.step.Text)
}
case "pending":
for _, st := range s.fmt.pending {
for _, st := range f.pending {
actual = append(actual, st.step.Text)
}
default:
@ -231,7 +284,9 @@ func (s *suiteContext) iRunFeatureSuite() error {
if err := s.parseFeatures(); err != nil {
return err
}
s.testedSuite.fmt = testFormatterFunc(&s.out)
s.testedSuite.run()
s.testedSuite.fmt.Summary()
return nil
}