diff --git a/.circleci/config.yml b/.circleci/config.yml
index 3e99eb4..0c16440 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,6 +15,10 @@ executors:
- image: circleci/golang:1.13.7
commands:
+ install:
+ description: "Install dependencies"
+ steps:
+ - run: GO111MODULE=on go mod vendor -v
vet:
description: "Run go vet"
steps:
@@ -34,7 +38,7 @@ commands:
godog:
description: "Run godog"
steps:
- - run: GO111MODULE=off go install ./cmd/godog
+ - run: go install ./cmd/godog
- run: godog -f progress
go_test:
description: "Run go test"
@@ -49,6 +53,7 @@ commands:
description: "Run all commands against godog code"
steps:
- checkout
+ - install
- vet
- fmt
- lint
diff --git a/features/formatter/events.feature b/features/formatter/events.feature
index 0cb1876..525beb9 100644
--- a/features/formatter/events.feature
+++ b/features/formatter/events.feature
@@ -14,7 +14,7 @@ Feature: event stream formatter
"""
Scenario: should process simple scenario
- Given a feature path "features/load.feature:25"
+ Given a feature path "features/load.feature:26"
When I run feature suite with formatter "events"
Then the following events should be fired:
"""
@@ -35,7 +35,7 @@ Feature: event stream formatter
"""
Scenario: should process outline scenario
- Given a feature path "features/load.feature:33"
+ Given a feature path "features/load.feature:34"
When I run feature suite with formatter "events"
Then the following events should be fired:
"""
diff --git a/features/formatter/junit.feature b/features/formatter/junit.feature
new file mode 100644
index 0000000..68d9ff0
--- /dev/null
+++ b/features/formatter/junit.feature
@@ -0,0 +1,228 @@
+Feature: JUnit XML formatter
+ In order to support tools that import JUnit XML output
+ I need to be able to support junit formatted output
+
+ Scenario: Support of Feature Plus Scenario Node
+ Given a feature "features/simple.feature" file:
+ """
+ Feature: simple feature
+ simple feature description
+ Scenario: simple scenario
+ simple scenario description
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+ """
+
+ Scenario: Support of Feature Plus Scenario Node With Tags
+ Given a feature "features/simple.feature" file:
+ """
+ @TAG1
+ Feature: simple feature
+ simple feature description
+ @TAG2 @TAG3
+ Scenario: simple scenario
+ simple scenario description
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+ """
+ Scenario: Support of Feature Plus Scenario Outline
+ Given a feature "features/simple.feature" file:
+ """
+ Feature: simple feature
+ simple feature description
+
+ Scenario Outline: simple scenario
+ simple scenario description
+
+ Examples: simple examples
+ | status |
+ | pass |
+ | fail |
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+
+ """
+
+ Scenario: Support of Feature Plus Scenario Outline With Tags
+ Given a feature "features/simple.feature" file:
+ """
+ @TAG1
+ Feature: simple feature
+ simple feature description
+
+ @TAG2
+ Scenario Outline: simple scenario
+ simple scenario description
+
+ @TAG3
+ Examples: simple examples
+ | status |
+ | pass |
+ | fail |
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+
+ """
+ Scenario: Support of Feature Plus Scenario With Steps
+ Given a feature "features/simple.feature" file:
+ """
+ Feature: simple feature
+ simple feature description
+
+ Scenario: simple scenario
+ simple scenario description
+
+ Given passing step
+ Then a failing step
+
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+
+
+ """
+ Scenario: Support of Feature Plus Scenario Outline With Steps
+ Given a feature "features/simple.feature" file:
+ """
+ Feature: simple feature
+ simple feature description
+
+ Scenario Outline: simple scenario
+ simple scenario description
+
+ Given step
+
+ Examples: simple examples
+ | status |
+ | passing |
+ | failing |
+
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+
+
+
+ """
+
+ # Currently godog only supports comments on Feature and not
+ # scenario and steps.
+ Scenario: Support of Comments
+ Given a feature "features/simple.feature" file:
+ """
+ #Feature comment
+ Feature: simple feature
+ simple description
+
+ Scenario: simple scenario
+ simple feature description
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+ """
+ Scenario: Support of Docstrings
+ Given a feature "features/simple.feature" file:
+ """
+ Feature: simple feature
+ simple description
+
+ Scenario: simple scenario
+ simple feature description
+
+ Given passing step
+ \"\"\" content type
+ step doc string
+ \"\"\"
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+ """
+ Scenario: Support of Undefined, Pending and Skipped status
+ Given a feature "features/simple.feature" file:
+ """
+ Feature: simple feature
+ simple feature description
+
+ Scenario: simple scenario
+ simple scenario description
+
+ Given passing step
+ And pending step
+ And undefined
+ And passing step
+
+ """
+ When I run feature suite with formatter "junit"
+ Then the rendered xml will be as follows:
+ """ application/xml
+
+
+
+
+
+
+
+
+
+
+ """
diff --git a/features/formatter/pretty.feature b/features/formatter/pretty.feature
index 8fde85f..cdd538f 100644
--- a/features/formatter/pretty.feature
+++ b/features/formatter/pretty.feature
@@ -131,8 +131,8 @@ Feature: pretty formatter
simple feature description
Scenario: simple scenario # features/simple.feature:4
- Given passing step # suite_context.go:72 -> github.com/cucumber/godog.SuiteContext.func2
- Then a failing step # suite_context.go:318 -> *suiteContext
+ Given passing step # suite_context.go:0 -> SuiteContext.func2
+ Then a failing step # suite_context.go:0 -> *suiteContext
intentional failure
--- Failed steps:
@@ -170,7 +170,7 @@ Feature: pretty formatter
simple feature description
Scenario Outline: simple scenario # features/simple.feature:4
- Given step # suite_context.go:72 -> github.com/cucumber/godog.SuiteContext.func2
+ Given step # suite_context.go:0 -> SuiteContext.func2
Examples: simple examples
| status |
@@ -235,7 +235,7 @@ Feature: pretty formatter
simple description
Scenario: simple scenario # features/simple.feature:4
- Given passing step # suite_context.go:72 -> github.com/cucumber/godog.SuiteContext.func2
+ Given passing step # suite_context.go:0 -> SuiteContext.func2
\"\"\" content type
step doc string
\"\"\"
@@ -266,11 +266,11 @@ Feature: pretty formatter
simple feature description
Scenario: simple scenario # features/simple.feature:4
- Given passing step # suite_context.go:72 -> github.com/cucumber/godog.SuiteContext.func2
- And pending step # suite_context.go:69 -> github.com/cucumber/godog.SuiteContext.func1
+ Given passing step # suite_context.go:0 -> SuiteContext.func2
+ And pending step # suite_context.go:0 -> SuiteContext.func1
TODO: write pending definition
And undefined
- And passing step # suite_context.go:72 -> github.com/cucumber/godog.SuiteContext.func2
+ And passing step # suite_context.go:0 -> SuiteContext.func2
1 scenarios (1 pending, 1 undefined)
4 steps (1 passed, 1 pending, 1 undefined, 1 skipped)
diff --git a/features/lang.feature b/features/lang.feature
index 4081189..0b41014 100644
--- a/features/lang.feature
+++ b/features/lang.feature
@@ -8,12 +8,13 @@ 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 12 savybių failus:
+ Tada aš turėčiau turėti 13 savybių failus:
"""
features/background.feature
features/events.feature
features/formatter/cucumber.feature
features/formatter/events.feature
+ features/formatter/junit.feature
features/formatter/pretty.feature
features/lang.feature
features/load.feature
diff --git a/features/load.feature b/features/load.feature
index f4fb1e2..9425f61 100644
--- a/features/load.feature
+++ b/features/load.feature
@@ -6,12 +6,13 @@ Feature: load features
Scenario: load features within path
Given a feature path "features"
When I parse features
- Then I should have 12 feature files:
+ Then I should have 13 feature files:
"""
features/background.feature
features/events.feature
features/formatter/cucumber.feature
features/formatter/events.feature
+ features/formatter/junit.feature
features/formatter/pretty.feature
features/lang.feature
features/load.feature
diff --git a/fixtures/cucumber_output.json b/fixtures/cucumber_output.json
index 8a8ba16..9113b17 100644
--- a/fixtures/cucumber_output.json
+++ b/fixtures/cucumber_output.json
@@ -1470,7 +1470,7 @@
"steps": [
{
"keyword": "Given ",
- "name": "a feature path \"features/load.feature:25\"",
+ "name": "a feature path \"features/load.feature:26\"",
"line": 17,
"match": {
"location": "suite_context.go:0"
@@ -1521,7 +1521,7 @@
"steps": [
{
"keyword": "Given ",
- "name": "a feature path \"features/load.feature:33\"",
+ "name": "a feature path \"features/load.feature:34\"",
"line": 38,
"match": {
"location": "suite_context.go:0"
@@ -1564,6 +1564,530 @@
}
]
},
+ {
+ "uri": "features/formatter/junit.feature",
+ "id": "junit-xml-formatter",
+ "keyword": "Feature",
+ "name": "JUnit XML formatter",
+ "description": " In order to support tools that import JUnit XML output\n I need to be able to support junit formatted output",
+ "line": 1,
+ "comments": [
+ {
+ "value": "# Currently godog only supports comments on Feature and not",
+ "line": 154
+ },
+ {
+ "value": "# scenario and steps.",
+ "line": 155
+ }
+ ],
+ "elements": [
+ {
+ "id": "junit-xml-formatter;support-of-feature-plus-scenario-node",
+ "keyword": "Scenario",
+ "name": "Support of Feature Plus Scenario Node",
+ "description": "",
+ "line": 5,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 6,
+ "doc_string": {
+ "value": " Feature: simple feature\n simple feature description\n Scenario: simple scenario\n simple scenario description",
+ "content_type": "",
+ "line": 7
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 13,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 14,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 15
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-feature-plus-scenario-node-with-tags",
+ "keyword": "Scenario",
+ "name": "Support of Feature Plus Scenario Node With Tags",
+ "description": "",
+ "line": 24,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 25,
+ "doc_string": {
+ "value": " @TAG1\n Feature: simple feature\n simple feature description\n @TAG2 @TAG3\n Scenario: simple scenario\n simple scenario description",
+ "content_type": "",
+ "line": 26
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 34,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 35,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 36
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-feature-plus-scenario-outline",
+ "keyword": "Scenario",
+ "name": "Support of Feature Plus Scenario Outline",
+ "description": "",
+ "line": 44,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 45,
+ "doc_string": {
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario Outline: simple scenario\n simple scenario description\n\n Examples: simple examples\n | status |\n | pass |\n | fail |",
+ "content_type": "",
+ "line": 46
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 58,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 59,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"2\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"2\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario #1\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003ctestcase name=\"simple scenario #2\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 60
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-feature-plus-scenario-outline-with-tags",
+ "keyword": "Scenario",
+ "name": "Support of Feature Plus Scenario Outline With Tags",
+ "description": "",
+ "line": 70,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 71,
+ "doc_string": {
+ "value": " @TAG1\n Feature: simple feature\n simple feature description\n\n @TAG2\n Scenario Outline: simple scenario\n simple scenario description\n\n @TAG3\n Examples: simple examples\n | status |\n | pass |\n | fail |",
+ "content_type": "",
+ "line": 72
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 87,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 88,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"2\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"2\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario #1\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003ctestcase name=\"simple scenario #2\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 89
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-feature-plus-scenario-with-steps",
+ "keyword": "Scenario",
+ "name": "Support of Feature Plus Scenario With Steps",
+ "description": "",
+ "line": 98,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 99,
+ "doc_string": {
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario: simple scenario\n simple scenario description\n\n Given passing step\n Then a failing step\n",
+ "content_type": "",
+ "line": 100
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 111,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 112,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"1\" skipped=\"0\" failures=\"1\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"1\" skipped=\"0\" failures=\"1\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario\" status=\"failed\" time=\"0s\"\u003e\n \u003cfailure message=\"Step a failing step: intentional failure\"\u003e\u003c/failure\u003e\n \u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 113
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-feature-plus-scenario-outline-with-steps",
+ "keyword": "Scenario",
+ "name": "Support of Feature Plus Scenario Outline With Steps",
+ "description": "",
+ "line": 123,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 124,
+ "doc_string": {
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario Outline: simple scenario\n simple scenario description\n\n Given \u003cstatus\u003e step\n\n Examples: simple examples\n | status |\n | passing |\n | failing |\n",
+ "content_type": "",
+ "line": 125
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 140,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 141,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"2\" skipped=\"0\" failures=\"1\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"2\" skipped=\"0\" failures=\"1\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario #1\" status=\"passed\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003ctestcase name=\"simple scenario #2\" status=\"failed\" time=\"0s\"\u003e\n \u003cfailure message=\"Step failing step: intentional failure\"\u003e\u003c/failure\u003e\n \u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 142
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-comments",
+ "keyword": "Scenario",
+ "name": "Support of Comments",
+ "description": "",
+ "line": 156,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 157,
+ "doc_string": {
+ "value": " #Feature comment\n Feature: simple feature\n simple description\n\n Scenario: simple scenario\n simple feature description",
+ "content_type": "",
+ "line": 158
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 166,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 167,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario\" status=\"\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 168
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-docstrings",
+ "keyword": "Scenario",
+ "name": "Support of Docstrings",
+ "description": "",
+ "line": 176,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 177,
+ "doc_string": {
+ "value": " Feature: simple feature\n simple description\n\n Scenario: simple scenario\n simple feature description\n\n Given passing step\n \"\"\" content type\n step doc string\n \"\"\"",
+ "content_type": "",
+ "line": 178
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 190,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 191,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"0\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario\" status=\"passed\" time=\"0s\"\u003e\u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 192
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ },
+ {
+ "id": "junit-xml-formatter;support-of-undefined,-pending-and-skipped-status",
+ "keyword": "Scenario",
+ "name": "Support of Undefined, Pending and Skipped status",
+ "description": "",
+ "line": 200,
+ "type": "scenario",
+ "steps": [
+ {
+ "keyword": "Given ",
+ "name": "a feature \"features/simple.feature\" file:",
+ "line": 201,
+ "doc_string": {
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario: simple scenario\n simple scenario description\n\n Given passing step\n And pending step\n And undefined\n And passing step\n",
+ "content_type": "",
+ "line": 202
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "When ",
+ "name": "I run feature suite with formatter \"junit\"",
+ "line": 215,
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ },
+ {
+ "keyword": "Then ",
+ "name": "the rendered xml will be as follows:",
+ "line": 216,
+ "doc_string": {
+ "value": " \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n \u003ctestsuites name=\"godog\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"1\" time=\"0s\"\u003e\n \u003ctestsuite name=\"simple feature\" tests=\"1\" skipped=\"0\" failures=\"0\" errors=\"1\" time=\"0s\"\u003e\n \u003ctestcase name=\"simple scenario\" status=\"undefined\" time=\"0s\"\u003e\n \u003cerror message=\"Step pending step: TODO: write pending definition\" type=\"pending\"\u003e\u003c/error\u003e\n \u003cerror message=\"Step undefined\" type=\"undefined\"\u003e\u003c/error\u003e\n \u003cerror message=\"Step passing step\" type=\"skipped\"\u003e\u003c/error\u003e\n \u003c/testcase\u003e\n \u003c/testsuite\u003e\n \u003c/testsuites\u003e",
+ "content_type": "application/xml",
+ "line": 217
+ },
+ "match": {
+ "location": "suite_context.go:0"
+ },
+ "result": {
+ "status": "passed",
+ "duration": 0
+ }
+ }
+ ]
+ }
+ ]
+ },
{
"uri": "features/formatter/pretty.feature",
"id": "pretty-formatter",
@@ -1848,7 +2372,7 @@
"name": "the rendered output will be as follows:",
"line": 128,
"doc_string": {
- "value": " Feature: simple feature\n simple feature description\n\n Scenario: simple scenario # features/simple.feature:4\n Given passing step # suite_context.go:0 -\u003e github.com/cucumber/godog.SuiteContext.func2\n Then a failing step # suite_context.go:0 -\u003e *suiteContext\n intentional failure\n\n --- Failed steps:\n\n Scenario: simple scenario # features/simple.feature:4\n Then a failing step # features/simple.feature:8\n Error: intentional failure\n\n\n 1 scenarios (1 failed)\n 2 steps (1 passed, 1 failed)\n 0s",
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario: simple scenario # features/simple.feature:4\n Given passing step # suite_context.go:0 -\u003e SuiteContext.func2\n Then a failing step # suite_context.go:0 -\u003e *suiteContext\n intentional failure\n\n --- Failed steps:\n\n Scenario: simple scenario # features/simple.feature:4\n Then a failing step # features/simple.feature:8\n Error: intentional failure\n\n\n 1 scenarios (1 failed)\n 2 steps (1 passed, 1 failed)\n 0s",
"content_type": "",
"line": 129
},
@@ -1904,7 +2428,7 @@
"name": "the rendered output will be as follows:",
"line": 167,
"doc_string": {
- "value": " Feature: simple feature\n simple feature description\n\n Scenario Outline: simple scenario # features/simple.feature:4\n Given \u003cstatus\u003e step # suite_context.go:0 -\u003e github.com/cucumber/godog.SuiteContext.func2\n\n Examples: simple examples\n | status |\n | passing |\n | failing |\n intentional failure\n\n --- Failed steps:\n\n Scenario Outline: simple scenario # features/simple.feature:4\n Given failing step # features/simple.feature:7\n Error: intentional failure\n\n\n 2 scenarios (1 passed, 1 failed)\n 2 steps (1 passed, 1 failed)\n 0s",
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario Outline: simple scenario # features/simple.feature:4\n Given \u003cstatus\u003e step # suite_context.go:0 -\u003e SuiteContext.func2\n\n Examples: simple examples\n | status |\n | passing |\n | failing |\n intentional failure\n\n --- Failed steps:\n\n Scenario Outline: simple scenario # features/simple.feature:4\n Given failing step # features/simple.feature:7\n Error: intentional failure\n\n\n 2 scenarios (1 passed, 1 failed)\n 2 steps (1 passed, 1 failed)\n 0s",
"content_type": "",
"line": 168
},
@@ -2016,7 +2540,7 @@
"name": "the rendered output will be as follows:",
"line": 232,
"doc_string": {
- "value": " Feature: simple feature\n simple description\n\n Scenario: simple scenario # features/simple.feature:4\n Given passing step # suite_context.go:0 -\u003e github.com/cucumber/godog.SuiteContext.func2\n \"\"\" content type\n step doc string\n \"\"\"\n\n 1 scenarios (1 passed)\n 1 steps (1 passed)\n 0s",
+ "value": " Feature: simple feature\n simple description\n\n Scenario: simple scenario # features/simple.feature:4\n Given passing step # suite_context.go:0 -\u003e SuiteContext.func2\n \"\"\" content type\n step doc string\n \"\"\"\n\n 1 scenarios (1 passed)\n 1 steps (1 passed)\n 0s",
"content_type": "",
"line": 233
},
@@ -2072,7 +2596,7 @@
"name": "the rendered output will be as follows:",
"line": 263,
"doc_string": {
- "value": " Feature: simple feature\n simple feature description\n\n Scenario: simple scenario # features/simple.feature:4\n Given passing step # suite_context.go:0 -\u003e github.com/cucumber/godog.SuiteContext.func2\n And pending step # suite_context.go:0 -\u003e github.com/cucumber/godog.SuiteContext.func1\n TODO: write pending definition\n And undefined\n And passing step # suite_context.go:0 -\u003e github.com/cucumber/godog.SuiteContext.func2\n\n 1 scenarios (1 pending, 1 undefined)\n 4 steps (1 passed, 1 pending, 1 undefined, 1 skipped)\n 0s\n\n You can implement step definitions for undefined steps with these snippets:\n\n func undefined() error {\n return godog.ErrPending\n }\n\n func FeatureContext(s *godog.Suite) {\n s.Step(`^undefined$`, undefined)\n }",
+ "value": " Feature: simple feature\n simple feature description\n\n Scenario: simple scenario # features/simple.feature:4\n Given passing step # suite_context.go:0 -\u003e SuiteContext.func2\n And pending step # suite_context.go:0 -\u003e SuiteContext.func1\n TODO: write pending definition\n And undefined\n And passing step # suite_context.go:0 -\u003e SuiteContext.func2\n\n 1 scenarios (1 pending, 1 undefined)\n 4 steps (1 passed, 1 pending, 1 undefined, 1 skipped)\n 0s\n\n You can implement step definitions for undefined steps with these snippets:\n\n func undefined() error {\n return godog.ErrPending\n }\n\n func FeatureContext(s *godog.Suite) {\n s.Step(`^undefined$`, undefined)\n }",
"content_type": "",
"line": 264
},
@@ -2142,10 +2666,10 @@
},
{
"keyword": "Tada ",
- "name": "aš turėčiau turėti 12 savybių failus:",
+ "name": "aš turėčiau turėti 13 savybių failus:",
"line": 11,
"doc_string": {
- "value": "features/background.feature\nfeatures/events.feature\nfeatures/formatter/cucumber.feature\nfeatures/formatter/events.feature\nfeatures/formatter/pretty.feature\nfeatures/lang.feature\nfeatures/load.feature\nfeatures/multistep.feature\nfeatures/outline.feature\nfeatures/run.feature\nfeatures/snippets.feature\nfeatures/tags.feature",
+ "value": "features/background.feature\nfeatures/events.feature\nfeatures/formatter/cucumber.feature\nfeatures/formatter/events.feature\nfeatures/formatter/junit.feature\nfeatures/formatter/pretty.feature\nfeatures/lang.feature\nfeatures/load.feature\nfeatures/multistep.feature\nfeatures/outline.feature\nfeatures/run.feature\nfeatures/snippets.feature\nfeatures/tags.feature",
"content_type": "",
"line": 12
},
@@ -2203,10 +2727,10 @@
},
{
"keyword": "Then ",
- "name": "I should have 12 feature files:",
+ "name": "I should have 13 feature files:",
"line": 9,
"doc_string": {
- "value": "features/background.feature\nfeatures/events.feature\nfeatures/formatter/cucumber.feature\nfeatures/formatter/events.feature\nfeatures/formatter/pretty.feature\nfeatures/lang.feature\nfeatures/load.feature\nfeatures/multistep.feature\nfeatures/outline.feature\nfeatures/run.feature\nfeatures/snippets.feature\nfeatures/tags.feature",
+ "value": "features/background.feature\nfeatures/events.feature\nfeatures/formatter/cucumber.feature\nfeatures/formatter/events.feature\nfeatures/formatter/junit.feature\nfeatures/formatter/pretty.feature\nfeatures/lang.feature\nfeatures/load.feature\nfeatures/multistep.feature\nfeatures/outline.feature\nfeatures/run.feature\nfeatures/snippets.feature\nfeatures/tags.feature",
"content_type": "",
"line": 10
},
@@ -2225,13 +2749,13 @@
"keyword": "Scenario",
"name": "load a specific feature file",
"description": "",
- "line": 25,
+ "line": 26,
"type": "scenario",
"steps": [
{
"keyword": "Given ",
"name": "a feature path \"features/load.feature\"",
- "line": 26,
+ "line": 27,
"match": {
"location": "suite_context.go:0"
},
@@ -2243,7 +2767,7 @@
{
"keyword": "When ",
"name": "I parse features",
- "line": 27,
+ "line": 28,
"match": {
"location": "suite_context.go:0"
},
@@ -2255,11 +2779,11 @@
{
"keyword": "Then ",
"name": "I should have 1 feature file:",
- "line": 28,
+ "line": 29,
"doc_string": {
"value": "features/load.feature",
"content_type": "",
- "line": 29
+ "line": 30
},
"match": {
"location": "suite_context.go:0"
@@ -2276,13 +2800,13 @@
"keyword": "Scenario Outline",
"name": "loaded feature should have a number of scenarios",
"description": "",
- "line": 40,
+ "line": 41,
"type": "scenario",
"steps": [
{
"keyword": "Given ",
"name": "a feature path \"features/load.feature:3\"",
- "line": 40,
+ "line": 41,
"match": {
"location": "suite_context.go:0"
},
@@ -2294,7 +2818,7 @@
{
"keyword": "When ",
"name": "I parse features",
- "line": 40,
+ "line": 41,
"match": {
"location": "suite_context.go:0"
},
@@ -2306,7 +2830,7 @@
{
"keyword": "Then ",
"name": "I should have 0 scenario registered",
- "line": 40,
+ "line": 41,
"match": {
"location": "suite_context.go:0"
},
@@ -2322,13 +2846,13 @@
"keyword": "Scenario Outline",
"name": "loaded feature should have a number of scenarios",
"description": "",
- "line": 41,
+ "line": 42,
"type": "scenario",
"steps": [
{
"keyword": "Given ",
"name": "a feature path \"features/load.feature:6\"",
- "line": 41,
+ "line": 42,
"match": {
"location": "suite_context.go:0"
},
@@ -2340,7 +2864,7 @@
{
"keyword": "When ",
"name": "I parse features",
- "line": 41,
+ "line": 42,
"match": {
"location": "suite_context.go:0"
},
@@ -2352,7 +2876,7 @@
{
"keyword": "Then ",
"name": "I should have 1 scenario registered",
- "line": 41,
+ "line": 42,
"match": {
"location": "suite_context.go:0"
},
@@ -2368,13 +2892,13 @@
"keyword": "Scenario Outline",
"name": "loaded feature should have a number of scenarios",
"description": "",
- "line": 42,
+ "line": 43,
"type": "scenario",
"steps": [
{
"keyword": "Given ",
"name": "a feature path \"features/load.feature\"",
- "line": 42,
+ "line": 43,
"match": {
"location": "suite_context.go:0"
},
@@ -2386,7 +2910,7 @@
{
"keyword": "When ",
"name": "I parse features",
- "line": 42,
+ "line": 43,
"match": {
"location": "suite_context.go:0"
},
@@ -2398,7 +2922,7 @@
{
"keyword": "Then ",
"name": "I should have 4 scenario registered",
- "line": 42,
+ "line": 43,
"match": {
"location": "suite_context.go:0"
},
@@ -2414,13 +2938,13 @@
"keyword": "Scenario",
"name": "load a number of feature files",
"description": "",
- "line": 44,
+ "line": 45,
"type": "scenario",
"steps": [
{
"keyword": "Given ",
"name": "a feature path \"features/load.feature\"",
- "line": 45,
+ "line": 46,
"match": {
"location": "suite_context.go:0"
},
@@ -2432,7 +2956,7 @@
{
"keyword": "And ",
"name": "a feature path \"features/events.feature\"",
- "line": 46,
+ "line": 47,
"match": {
"location": "suite_context.go:0"
},
@@ -2444,7 +2968,7 @@
{
"keyword": "When ",
"name": "I parse features",
- "line": 47,
+ "line": 48,
"match": {
"location": "suite_context.go:0"
},
@@ -2456,11 +2980,11 @@
{
"keyword": "Then ",
"name": "I should have 2 feature files:",
- "line": 48,
+ "line": 49,
"doc_string": {
"value": "features/events.feature\nfeatures/load.feature",
"content_type": "",
- "line": 49
+ "line": 50
},
"match": {
"location": "suite_context.go:0"
diff --git a/fixtures/junit_output.xml b/fixtures/junit_output.xml
index 92327ed..c1f0d80 100644
--- a/fixtures/junit_output.xml
+++ b/fixtures/junit_output.xml
@@ -1,5 +1,16 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fixtures/progress_output.txt b/fixtures/progress_output.txt
index eb351bb..2d2565d 100644
--- a/fixtures/progress_output.txt
+++ b/fixtures/progress_output.txt
@@ -1,9 +1,10 @@
...................................................................... 70
...................................................................... 140
...................................................................... 210
-.................................................................. 276
+...................................................................... 280
+....................... 303
-69 scenarios (69 passed)
-276 steps (276 passed)
+78 scenarios (78 passed)
+303 steps (303 passed)
0s
\ No newline at end of file
diff --git a/run_test.go b/run_test.go
index 6156c4c..bce07ff 100644
--- a/run_test.go
+++ b/run_test.go
@@ -277,7 +277,7 @@ func testSucceedRun(t *testing.T, format string, concurrency int, expectedOutput
}
status := RunWithOptions("succeed", func(s *Suite) { SuiteContext(s) }, opt)
- require.Equal(t, exitSuccess, status)
+ assert.Equal(t, exitSuccess, status)
b, err := ioutil.ReadAll(output)
require.NoError(t, err)
diff --git a/suite_context.go b/suite_context.go
index a6162e8..e4cc1c3 100644
--- a/suite_context.go
+++ b/suite_context.go
@@ -3,6 +3,7 @@ package godog
import (
"bytes"
"encoding/json"
+ "encoding/xml"
"fmt"
"io"
"path/filepath"
@@ -78,6 +79,9 @@ func SuiteContext(s *Suite, additionalContextInitializers ...func(suite *Suite))
// Introduced to test formatter/pretty.feature
s.Step(`^the rendered output will be as follows:$`, c.theRenderOutputWillBe)
+ // Introduced to test formatter/junit.feature
+ s.Step(`^the rendered xml will be as follows:$`, c.theRenderXMLWillBe)
+
s.Step(`^(?:a )?failing multistep$`, func() Steps {
return Steps{"passing step", "failing step"}
})
@@ -463,38 +467,67 @@ func (s *suiteContext) theseEventsHadToBeFiredForNumberOfTimes(tbl *gherkin.Data
func (s *suiteContext) theRenderJSONWillBe(docstring *gherkin.DocString) error {
suiteCtxReg := regexp.MustCompile(`suite_context.go:\d+`)
+
+ expectedString := docstring.Content
+ expectedString = suiteCtxReg.ReplaceAllString(expectedString, `suite_context.go:0`)
+ actualString := s.out.String()
+ actualString = suiteCtxReg.ReplaceAllString(actualString, `suite_context.go:0`)
+
var expected []cukeFeatureJSON
- if err := json.Unmarshal([]byte(suiteCtxReg.ReplaceAllString(docstring.Content, `suite_context.go:0`)), &expected); err != nil {
+ if err := json.Unmarshal([]byte(expectedString), &expected); err != nil {
return err
}
var actual []cukeFeatureJSON
- replaced := suiteCtxReg.ReplaceAllString(s.out.String(), `suite_context.go:0`)
- if err := json.Unmarshal([]byte(replaced), &actual); err != nil {
+ if err := json.Unmarshal([]byte(actualString), &actual); err != nil {
return err
}
if !reflect.DeepEqual(expected, actual) {
- return fmt.Errorf("expected json does not match actual: %s", replaced)
+ return fmt.Errorf("expected json does not match actual: %s", actualString)
}
return nil
}
func (s *suiteContext) theRenderOutputWillBe(docstring *gherkin.DocString) error {
suiteCtxReg := regexp.MustCompile(`suite_context.go:\d+`)
+ suiteCtxFuncReg := regexp.MustCompile(`github.com/cucumber/godog.SuiteContext.func(\d+)`)
expected := trimAllLines(strings.TrimSpace(docstring.Content))
- expected = suiteCtxReg.ReplaceAllString(expected, `suite_context.go:0`)
- actual := trimAllLines(strings.TrimSpace(s.out.String()))
- actual = suiteCtxReg.ReplaceAllString(actual, `suite_context.go:0`)
+ expected = suiteCtxReg.ReplaceAllString(expected, "suite_context.go:0")
+ expected = suiteCtxFuncReg.ReplaceAllString(expected, "SuiteContext.func$1")
- if expected != actual {
- return fmt.Errorf("expected output\n%s\ndoes not match actual:\n%s\n", expected, actual)
+ actual := trimAllLines(strings.TrimSpace(s.out.String()))
+ actual = suiteCtxReg.ReplaceAllString(actual, "suite_context.go:0")
+ actual = suiteCtxFuncReg.ReplaceAllString(actual, "SuiteContext.func$1")
+
+ if err := match(expected, actual); err != nil {
+ return err
}
return nil
}
+func (s *suiteContext) theRenderXMLWillBe(docstring *gherkin.DocString) error {
+ expectedString := docstring.Content
+ actualString := s.out.String()
+
+ var expected junitPackageSuite
+ if err := xml.Unmarshal([]byte(expectedString), &expected); err != nil {
+ return err
+ }
+
+ var actual junitPackageSuite
+ if err := xml.Unmarshal([]byte(actualString), &actual); err != nil {
+ return err
+ }
+
+ if !reflect.DeepEqual(expected, actual) {
+ return fmt.Errorf("expected xml does not match actual: %s", actualString)
+ }
+ return nil
+}
+
type testFormatter struct {
basefmt
scenarios []interface{}
@@ -521,3 +554,32 @@ func (f *testFormatter) Node(node interface{}) {
}
func (f *testFormatter) Summary() {}
+
+func match(expected, actual string) error {
+ act := []byte(actual)
+ exp := []byte(expected)
+
+ if len(act) != len(exp) {
+ return fmt.Errorf("content lengths do not match, expected: %d, actual %d, expected output:\n%s, actual output:\n%s", len(exp), len(act), expected, actual)
+ }
+
+ for i := 0; i < len(exp); i++ {
+ if act[i] == exp[i] {
+ continue
+ }
+
+ cpe := make([]byte, len(exp))
+ copy(cpe, exp)
+ e := append(exp[:i], '^')
+ e = append(e, cpe[i:]...)
+
+ cpa := make([]byte, len(act))
+ copy(cpa, act)
+ a := append(act[:i], '^')
+ a = append(a, cpa[i:]...)
+
+ return fmt.Errorf("expected output does not match:\n%s\n\n%s", string(a), string(e))
+ }
+
+ return nil
+}