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). | 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 | ``` gherkin | ||||||
| # file: $GOPATH/src/godogs/features/godogs.feature |  | ||||||
| Feature: eat godogs | Feature: eat godogs | ||||||
|   In order to be happy |   In order to be happy | ||||||
|   As a hungry gopher |   As a hungry gopher | ||||||
|  | @ -91,36 +102,111 @@ Feature: eat godogs | ||||||
|     Then there should be 7 remaining |     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. | 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 | ``` go | ||||||
| package main | package main | ||||||
| 
 | 
 | ||||||
|  | @ -130,17 +216,27 @@ var Godogs int | ||||||
| func main() { /* usual main func */ } | 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 | ``` go | ||||||
| package main | package main | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	 |  | ||||||
| 	messages "github.com/cucumber/messages-go/v10" // needed for godog v0.9.0 and earlier |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/cucumber/godog" | 	"github.com/cucumber/godog" | ||||||
| ) | ) | ||||||
|  | @ -165,20 +261,6 @@ func thereShouldBeRemaining(remaining int) error { | ||||||
| 	return nil | 	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) { | func InitializeTestSuite(ctx *godog.TestSuiteContext) { | ||||||
| 	ctx.BeforeSuite(func() { Godogs = 0 }) | 	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. | 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() | 	flag.Parse() | ||||||
| 	opts.Paths = flag.Args() | 	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{ | 	status := godog.TestSuite{ | ||||||
| 		Name: "godogs", | 		Name: "godogs", | ||||||
| 		TestSuiteInitializer: InitializeTestSuite, | 		TestSuiteInitializer: InitializeTestSuite, | ||||||
|  | @ -288,12 +379,6 @@ func TestMain(m *testing.M) { | ||||||
| 		Randomize: time.Now().UTC().UnixNano(), // randomize scenario execution order | 		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{ | 	status := godog.TestSuite{ | ||||||
| 		Name: "godogs", | 		Name: "godogs", | ||||||
| 		TestSuiteInitializer: InitializeTestSuite, | 		TestSuiteInitializer: InitializeTestSuite, | ||||||
|  | @ -325,12 +410,6 @@ func TestMain(m *testing.M) { | ||||||
| 		Paths:     []string{"features"}, | 		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{ | 	status := godog.TestSuite{ | ||||||
| 		Name: "godogs", | 		Name: "godogs", | ||||||
| 		TestSuiteInitializer: InitializeTestSuite, | 		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 КиБ | 
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Fredrik Lönnblad
						Fredrik Lönnblad