Removed $GOPATH from the README.md and updated the example (#349)
* Removed /Users/fredrik/Projects/go from the README.md and updated the example * made some more improvements
Этот коммит содержится в:
родитель
5e994943b3
коммит
ae808ea89b
5 изменённых файлов: 136 добавлений и 57 удалений
193
README.md
193
README.md
|
@ -72,14 +72,25 @@ Join [here](https://cucumberbdd-slack-invite.herokuapp.com/).
|
|||
|
||||
The following example can be [found here](/_examples/godogs).
|
||||
|
||||
### Step 1
|
||||
### Step 1 - Setup a go module
|
||||
|
||||
Given we create a new go package **$GOPATH/src/godogs**. From now on, this is our work directory `cd $GOPATH/src/godogs`.
|
||||
Given we create a new go module **godogs** in your normal go workspace. - `mkdir godogs`
|
||||
|
||||
Imagine we have a **godog cart** to serve godogs for lunch. First of all, we describe our feature in plain text - `vim $GOPATH/src/godogs/features/godogs.feature`:
|
||||
From now on, this is our work directory - `cd godogs`
|
||||
|
||||
Initiate the go module - `go mod init godogs`
|
||||
|
||||
### Step 2 - Install godog
|
||||
|
||||
Install the godog binary - `go get github.com/cucumber/godog/cmd/godog`
|
||||
|
||||
### Step 3 - Create gherkin feature
|
||||
|
||||
Imagine we have a **godog cart** to serve godogs for lunch.
|
||||
|
||||
First of all, we describe our feature in plain text - `vim features/godogs.feature`
|
||||
|
||||
``` gherkin
|
||||
# file: $GOPATH/src/godogs/features/godogs.feature
|
||||
Feature: eat godogs
|
||||
In order to be happy
|
||||
As a hungry gopher
|
||||
|
@ -91,36 +102,111 @@ Feature: eat godogs
|
|||
Then there should be 7 remaining
|
||||
```
|
||||
|
||||
**NOTE:** same as **go test** godog respects package level isolation. All your step definitions should be in your tested package root directory. In this case - `$GOPATH/src/godogs`
|
||||
### Step 4 - Create godog step definitions
|
||||
|
||||
### Step 2
|
||||
**NOTE:** same as **go test** godog respects package level isolation. All your step definitions should be in your tested package root directory. In this case: **godogs**.
|
||||
|
||||
If godog is installed in your GOPATH. We can run `godog` inside the **$GOPATH/src/godogs** directory. You should see that the steps are undefined:
|
||||
If we run godog inside the module: - `godog`
|
||||
|
||||

|
||||
You should see that the steps are undefined:
|
||||
```
|
||||
Feature: eat godogs
|
||||
In order to be happy
|
||||
As a hungry gopher
|
||||
I need to be able to eat godogs
|
||||
|
||||
If we wish to vendor godog dependency, we can do it as usual, using tools you prefer:
|
||||
Scenario: Eat 5 out of 12 # features/godogs.feature:6
|
||||
Given there are 12 godogs
|
||||
When I eat 5
|
||||
Then there should be 7 remaining
|
||||
|
||||
git clone https://github.com/cucumber/godog.git $GOPATH/src/godogs/vendor/github.com/cucumber/godog
|
||||
1 scenarios (1 undefined)
|
||||
3 steps (3 undefined)
|
||||
220.129µs
|
||||
|
||||
It gives you undefined step snippets to implement in your test context. You may copy these snippets into your `godogs_test.go` file.
|
||||
You can implement step definitions for undefined steps with these snippets:
|
||||
|
||||
Our directory structure should now look like:
|
||||
func iEat(arg1 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||

|
||||
func thereAreGodogs(arg1 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
If you copy the snippets into our test file and run godog again. We should see the step definition is now pending:
|
||||
func thereShouldBeRemaining(arg1 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||

|
||||
func FeatureContext(s *godog.Suite) {
|
||||
s.Step(`^I eat (\d+)$`, iEat)
|
||||
s.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
||||
s.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
|
||||
}
|
||||
```
|
||||
|
||||
You may change **ErrPending** to **nil** and the scenario will pass successfully.
|
||||
Create and copy the step definitions into a new file - `vim godogs_test.go`
|
||||
``` go
|
||||
package main
|
||||
|
||||
Since we need a working implementation, we may start by implementing only what is necessary.
|
||||
import "github.com/cucumber/godog"
|
||||
|
||||
### Step 3
|
||||
func iEat(arg1 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func thereAreGodogs(arg1 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func thereShouldBeRemaining(arg1 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func FeatureContext(s *godog.Suite) {
|
||||
s.Step(`^I eat (\d+)$`, iEat)
|
||||
s.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
||||
s.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
|
||||
}
|
||||
```
|
||||
|
||||
Our module should now look like this:
|
||||
```
|
||||
godogs
|
||||
- features
|
||||
- godogs.feature
|
||||
- go.mod
|
||||
- go.sum
|
||||
- godogs_test.go
|
||||
```
|
||||
|
||||
Run godog again - `godog`
|
||||
|
||||
You should now see that the scenario is pending with one step pending and two steps skipped:
|
||||
```
|
||||
Feature: eat godogs
|
||||
In order to be happy
|
||||
As a hungry gopher
|
||||
I need to be able to eat godogs
|
||||
|
||||
Scenario: Eat 5 out of 12 # features/godogs.feature:6
|
||||
Given there are 12 godogs # godogs_test.go:10 -> thereAreGodogs
|
||||
TODO: write pending definition
|
||||
When I eat 5 # godogs_test.go:6 -> iEat
|
||||
Then there should be 7 remaining # godogs_test.go:14 -> thereShouldBeRemaining
|
||||
|
||||
1 scenarios (1 pending)
|
||||
3 steps (1 pending, 2 skipped)
|
||||
282.123µs
|
||||
```
|
||||
|
||||
You may change **return godog.ErrPending** to **return nil** in the three step definitions and the scenario will pass successfully.
|
||||
|
||||
### Step 5 - Create the main program to test
|
||||
|
||||
We only need a number of **godogs** for now. Lets keep it simple.
|
||||
|
||||
Create and copy the code into a new file - `vim godogs.go`
|
||||
``` go
|
||||
package main
|
||||
|
||||
|
@ -130,17 +216,27 @@ var Godogs int
|
|||
func main() { /* usual main func */ }
|
||||
```
|
||||
|
||||
### Step 4
|
||||
Our module should now look like this:
|
||||
```
|
||||
godogs
|
||||
- features
|
||||
- godogs.feature
|
||||
- go.mod
|
||||
- go.sum
|
||||
- godogs.go
|
||||
- godogs_test.go
|
||||
```
|
||||
|
||||
Now lets implement our step definitions, which we can copy from generated console output snippets in order to test our feature requirements:
|
||||
### Step 6 - Add some logic to the step defintions
|
||||
|
||||
Now lets implement our step definitions to test our feature requirements:
|
||||
|
||||
Replace the contents of `godogs_test.go` with the code below - `vim godogs_test.go`
|
||||
``` go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
messages "github.com/cucumber/messages-go/v10" // needed for godog v0.9.0 and earlier
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
)
|
||||
|
@ -165,20 +261,6 @@ func thereShouldBeRemaining(remaining int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// godog v0.9.0 and earlier
|
||||
func FeatureContext(s *godog.Suite) {
|
||||
s.BeforeSuite(func() { Godogs = 0 })
|
||||
|
||||
s.BeforeScenario(func(*messages.Pickle) {
|
||||
Godogs = 0 // clean the state before every scenario
|
||||
})
|
||||
|
||||
s.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
||||
s.Step(`^I eat (\d+)$`, iEat)
|
||||
s.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
|
||||
}
|
||||
|
||||
// godog v0.10.0 (latest)
|
||||
func InitializeTestSuite(ctx *godog.TestSuiteContext) {
|
||||
ctx.BeforeSuite(func() { Godogs = 0 })
|
||||
}
|
||||
|
@ -194,11 +276,26 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
|
|||
}
|
||||
```
|
||||
|
||||
Now when you run the `godog` again, you should see:
|
||||
When you run godog again - `godog`
|
||||
|
||||

|
||||
You should see a passing run:
|
||||
```
|
||||
Feature: eat godogs
|
||||
In order to be happy
|
||||
As a hungry gopher
|
||||
I need to be able to eat godogs
|
||||
|
||||
We have hooked to **BeforeScenario** event in order to reset application state before each scenario. You may hook into more events, like **AfterStep** to print all state in case of an error. Or **BeforeSuite** to prepare a database.
|
||||
Scenario: Eat 5 out of 12 # features/godogs.feature:6
|
||||
Given there are 12 godogs # godogs_test.go:10 -> thereAreGodogs
|
||||
When I eat 5 # godogs_test.go:14 -> iEat
|
||||
Then there should be 7 remaining # godogs_test.go:22 -> thereShouldBeRemaining
|
||||
|
||||
1 scenarios (1 passed)
|
||||
3 steps (3 passed)
|
||||
258.302µs
|
||||
```
|
||||
|
||||
We have hooked to **BeforeScenario** event in order to reset the application state before each scenario. You may hook into more events, like **AfterStep** to print all state in case of an error. Or **BeforeSuite** to prepare a database.
|
||||
|
||||
By now, you should have figured out, how to use **godog**. Another advice is to make steps orthogonal, small and simple to read for a user. Whether the user is a dumb website user or an API developer, who may understand a little more technical context - it should target that user.
|
||||
|
||||
|
@ -251,12 +348,6 @@ func TestMain(m *testing.M) {
|
|||
flag.Parse()
|
||||
opts.Paths = flag.Args()
|
||||
|
||||
// godog v0.9.0 and earlier
|
||||
status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
|
||||
FeatureContext(s)
|
||||
}, opts)
|
||||
|
||||
// godog v0.10.0 (latest)
|
||||
status := godog.TestSuite{
|
||||
Name: "godogs",
|
||||
TestSuiteInitializer: InitializeTestSuite,
|
||||
|
@ -288,12 +379,6 @@ func TestMain(m *testing.M) {
|
|||
Randomize: time.Now().UTC().UnixNano(), // randomize scenario execution order
|
||||
}
|
||||
|
||||
// godog v0.9.0 and earlier
|
||||
status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
|
||||
FeatureContext(s)
|
||||
}, opts)
|
||||
|
||||
// godog v0.10.0 (latest)
|
||||
status := godog.TestSuite{
|
||||
Name: "godogs",
|
||||
TestSuiteInitializer: InitializeTestSuite,
|
||||
|
@ -325,12 +410,6 @@ func TestMain(m *testing.M) {
|
|||
Paths: []string{"features"},
|
||||
}
|
||||
|
||||
// godog v0.9.0 and earlier
|
||||
status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
|
||||
FeatureContext(s)
|
||||
}, opts)
|
||||
|
||||
// godog v0.10.0 (latest)
|
||||
status := godog.TestSuite{
|
||||
Name: "godogs",
|
||||
TestSuiteInitializer: InitializeTestSuite,
|
||||
|
|
Двоичные данные
screenshots/dir-tree.png
Двоичные данные
screenshots/dir-tree.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 25 КиБ |
Двоичные данные
screenshots/passed.png
Двоичные данные
screenshots/passed.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 58 КиБ |
Двоичные данные
screenshots/pending.png
Двоичные данные
screenshots/pending.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 56 КиБ |
Двоичные данные
screenshots/undefined.png
Двоичные данные
screenshots/undefined.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 91 КиБ |
Загрузка…
Создание таблицы
Сослаться в новой задаче