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,18 +216,28 @@ 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 КиБ | 
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Fredrik Lönnblad
						Fredrik Lönnblad