github.com/data-DOG/godog@v0.7.9/README.md (about)

     1  [![Build Status](https://travis-ci.org/DATA-DOG/godog.svg?branch=master)](https://travis-ci.org/DATA-DOG/godog)
     2  [![GoDoc](https://godoc.org/github.com/DATA-DOG/godog?status.svg)](https://godoc.org/github.com/DATA-DOG/godog)
     3  [![codecov.io](https://codecov.io/github/DATA-DOG/godog/branch/master/graph/badge.svg)](https://codecov.io/github/DATA-DOG/godog)
     4  
     5  # Godog
     6  
     7  <p align="center"><img src="/logo.png" alt="Godog logo" style="width:250px;" /></p>
     8  
     9  **The API is likely to change a few times before we reach 1.0.0**
    10  
    11  Please read all the README, you may find it very useful. And do not forget
    12  to peek into the
    13  [CHANGELOG](https://github.com/DATA-DOG/godog/blob/master/CHANGELOG.md)
    14  from time to time.
    15  
    16  Package godog is the official Cucumber BDD framework for Golang, it merges
    17  specification and test documentation into one cohesive whole. The author
    18  is a member of [cucumber team](https://github.com/cucumber).
    19  
    20  The project is inspired by [behat][behat] and [cucumber][cucumber] and is
    21  based on cucumber [gherkin3 parser][gherkin].
    22  
    23  **Godog** does not intervene with the standard **go test** command
    24  behavior. You can leverage both frameworks to functionally test your
    25  application while maintaining all test related source code in **_test.go**
    26  files.
    27  
    28  **Godog** acts similar compared to **go test** command, by using go
    29  compiler and linker tool in order to produce test executable. Godog
    30  contexts need to be exported the same way as **Test** functions for go
    31  tests. Note, that if you use **godog** command tool, it will use `go`
    32  executable to determine compiler and linker.
    33  
    34  **Godog** ships gherkin parser dependency as a subpackage. This will
    35  ensure that it is always compatible with the installed version of godog.
    36  So in general there are no vendor dependencies needed for installation.
    37  
    38  The following about section was taken from
    39  [cucumber](https://cucumber.io/) homepage.
    40  
    41  ## About
    42  
    43  #### A single source of truth
    44  
    45  Cucumber merges specification and test documentation into one cohesive whole.
    46  
    47  #### Living documentation
    48  
    49  Because they're automatically tested by Cucumber, your specifications are
    50  always bang up-to-date.
    51  
    52  #### Focus on the customer
    53  
    54  Business and IT don't always understand each other. Cucumber's executable
    55  specifications encourage closer collaboration, helping teams keep the
    56  business goal in mind at all times.
    57  
    58  #### Less rework
    59  
    60  When automated testing is this much fun, teams can easily protect
    61  themselves from costly regressions.
    62  
    63  ## Install
    64  
    65      go get github.com/DATA-DOG/godog/cmd/godog
    66  
    67  ## Example
    68  
    69  The following example can be [found
    70  here](/examples/godogs).
    71  
    72  ### Step 1
    73  
    74  Given we create a new go package **$GOPATH/src/godogs**. From now on, this
    75  is our work directory `cd $GOPATH/src/godogs`.
    76  
    77  Imagine we have a **godog cart** to serve godogs for lunch. First of all,
    78  we describe our feature in plain text - `vim
    79  $GOPATH/src/godogs/features/godogs.feature`:
    80  
    81  ``` gherkin
    82  # file: $GOPATH/src/godogs/features/godogs.feature
    83  Feature: eat godogs
    84    In order to be happy
    85    As a hungry gopher
    86    I need to be able to eat godogs
    87  
    88    Scenario: Eat 5 out of 12
    89      Given there are 12 godogs
    90      When I eat 5
    91      Then there should be 7 remaining
    92  ```
    93  
    94  **NOTE:** same as **go test** godog respects package level isolation. All
    95  your step definitions should be in your tested package root directory. In
    96  this case - `$GOPATH/src/godogs`
    97  
    98  ### Step 2
    99  
   100  If godog is installed in your GOPATH. We can run `godog` inside the
   101  **$GOPATH/src/godogs** directory. You should see that the steps are
   102  undefined:
   103  
   104  ![Undefined step snippets](/screenshots/undefined.png?raw=true)
   105  
   106  If we wish to vendor godog dependency, we can do it as usual, using tools
   107  you prefer:
   108  
   109      git clone https://github.com/DATA-DOG/godog.git $GOPATH/src/godogs/vendor/github.com/DATA-DOG/godog
   110  
   111  It gives you undefined step snippets to implement in your test context.
   112  You may copy these snippets into your `godogs_test.go` file.
   113  
   114  Our directory structure should now look like:
   115  
   116  ![Directory layout](/screenshots/dir-tree.png?raw=true)
   117  
   118  If you copy the snippets into our test file and run godog again. We should
   119  see the step definition is now pending:
   120  
   121  ![Pending step definition](/screenshots/pending.png?raw=true)
   122  
   123  You may change **ErrPending** to **nil** and the scenario will
   124  pass successfully.
   125  
   126  Since we need a working implementation, we may start by implementing only what is necessary.
   127  
   128  ### Step 3
   129  
   130  We only need a number of **godogs** for now. Lets keep it simple.
   131  
   132  ``` go
   133  /* file: $GOPATH/src/godogs/godogs.go */
   134  package main
   135  
   136  // Godogs available to eat
   137  var Godogs int
   138  
   139  func main() { /* usual main func */ }
   140  ```
   141  
   142  ### Step 4
   143  
   144  Now lets implement our step definitions, which we can copy from generated
   145  console output snippets in order to test our feature requirements:
   146  
   147  ``` go
   148  /* file: $GOPATH/src/godogs/godogs_test.go */
   149  package main
   150  
   151  import (
   152  	"fmt"
   153  
   154  	"github.com/DATA-DOG/godog"
   155  )
   156  
   157  func thereAreGodogs(available int) error {
   158  	Godogs = available
   159  	return nil
   160  }
   161  
   162  func iEat(num int) error {
   163  	if Godogs < num {
   164  		return fmt.Errorf("you cannot eat %d godogs, there are %d available", num, Godogs)
   165  	}
   166  	Godogs -= num
   167  	return nil
   168  }
   169  
   170  func thereShouldBeRemaining(remaining int) error {
   171  	if Godogs != remaining {
   172  		return fmt.Errorf("expected %d godogs to be remaining, but there is %d", remaining, Godogs)
   173  	}
   174  	return nil
   175  }
   176  
   177  func FeatureContext(s *godog.Suite) {
   178  	s.Step(`^there are (\d+) godogs$`, thereAreGodogs)
   179  	s.Step(`^I eat (\d+)$`, iEat)
   180  	s.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
   181  
   182  	s.BeforeScenario(func(interface{}) {
   183  		Godogs = 0 // clean the state before every scenario
   184  	})
   185  }
   186  ```
   187  
   188  Now when you run the `godog` again, you should see:
   189  
   190  ![Passed suite](/screenshots/passed.png?raw=true)
   191  
   192  We have hooked to **BeforeScenario** event in order to reset application
   193  state before each scenario. You may hook into more events, like
   194  **AfterStep** to print all state in case of an error. Or
   195  **BeforeSuite** to prepare a database.
   196  
   197  By now, you should have figured out, how to use **godog**. Another advice
   198  is to make steps orthogonal, small and simple to read for an user. Whether
   199  the user is a dumb website user or an API developer, who may understand
   200  a little more technical context - it should target that user.
   201  
   202  When steps are orthogonal and small, you can combine them just like you do
   203  with Unix tools. Look how to simplify or remove ones, which can be
   204  composed.
   205  
   206  ### References and Tutorials
   207  
   208  - [cucumber-html-reporter](https://github.com/gkushang/cucumber-html-reporter)
   209    may be used in order to generate **html** reports together with
   210    **cucumber** output formatter. See the [following docker
   211    image](https://github.com/myie/cucumber-html-reporter) for usage
   212    details.
   213  - [how to use godog by semaphoreci](https://semaphoreci.com/community/tutorials/how-to-use-godog-for-behavior-driven-development-in-go)
   214  - see [examples](https://github.com/DATA-DOG/godog/tree/master/examples)
   215  - see extension [AssistDog](https://github.com/hellomd/assistdog), which
   216    may have useful **gherkin.DataTable** transformations or comparison
   217    methods for assertions.
   218  
   219  ### Documentation
   220  
   221  See [godoc][godoc] for general API details.
   222  See **.travis.yml** for supported **go** versions.
   223  See `godog -h` for general command options.
   224  
   225  See implementation examples:
   226  
   227  - [rest API server](/examples/api)
   228  - [rest API with Database](/examples/db)
   229  - [godogs](/examples/godogs)
   230  
   231  ## FAQ
   232  
   233  ### Running Godog with go test
   234  
   235  You may integrate running **godog** in your **go test** command. You can
   236  run it using go [TestMain](https://golang.org/pkg/testing/#hdr-Main) func
   237  available since **go 1.4**. In this case it is not necessary to have
   238  **godog** command installed. See the following examples.
   239  
   240  The following example binds **godog** flags with specified prefix `godog`
   241  in order to prevent flag collisions.
   242  
   243  ``` go
   244  var opt = godog.Options{
   245  	Output: colors.Colored(os.Stdout),
   246  	Format: "progress", // can define default values
   247  }
   248  
   249  func init() {
   250  	godog.BindFlags("godog.", flag.CommandLine, &opt)
   251  }
   252  
   253  func TestMain(m *testing.M) {
   254  	flag.Parse()
   255  	opt.Paths = flag.Args()
   256  
   257  	status := godog.RunWithOptions("godogs", func(s *godog.Suite) {
   258  		FeatureContext(s)
   259  	}, opt)
   260  
   261  	if st := m.Run(); st > status {
   262  		status = st
   263  	}
   264  	os.Exit(status)
   265  }
   266  ```
   267  
   268  Then you may run tests with by specifying flags in order to filter
   269  features.
   270  
   271  ```
   272  go test -v --godog.random --godog.tags=wip
   273  go test -v --godog.format=pretty --godog.random -race -coverprofile=coverage.txt -covermode=atomic
   274  ```
   275  
   276  The following example does not bind godog flags, instead manually
   277  configuring needed options.
   278  
   279  ``` go
   280  func TestMain(m *testing.M) {
   281  	status := godog.RunWithOptions("godog", func(s *godog.Suite) {
   282  		FeatureContext(s)
   283  	}, godog.Options{
   284  		Format:    "progress",
   285  		Paths:     []string{"features"},
   286  		Randomize: time.Now().UTC().UnixNano(), // randomize scenario execution order
   287  	})
   288  
   289  	if st := m.Run(); st > status {
   290  		status = st
   291  	}
   292  	os.Exit(status)
   293  }
   294  ```
   295  
   296  You can even go one step further and reuse **go test** flags, like
   297  **verbose** mode in order to switch godog **format**. See the following
   298  example:
   299  
   300  ``` go
   301  func TestMain(m *testing.M) {
   302  	format := "progress"
   303  	for _, arg := range os.Args[1:] {
   304  		if arg == "-test.v=true" { // go test transforms -v option
   305  			format = "pretty"
   306  			break
   307  		}
   308  	}
   309  	status := godog.RunWithOptions("godog", func(s *godog.Suite) {
   310  		godog.SuiteContext(s)
   311  	}, godog.Options{
   312  		Format: format,
   313  		Paths:     []string{"features"},
   314  	})
   315  
   316  	if st := m.Run(); st > status {
   317  		status = st
   318  	}
   319  	os.Exit(status)
   320  }
   321  ```
   322  
   323  Now when running `go test -v` it will use **pretty** format.
   324  
   325  ### Configure common options for godog CLI
   326  
   327  There are no global options or configuration files. Alias your common or
   328  project based commands: `alias godog-wip="godog --format=progress
   329  --tags=@wip"`
   330  
   331  ### Testing browser interactions
   332  
   333  **godog** does not come with builtin packages to connect to the browser.
   334  You may want to look at [selenium](http://www.seleniumhq.org/) and
   335  probably [phantomjs](http://phantomjs.org/). See also the following
   336  components:
   337  
   338  1. [browsersteps](https://github.com/llonchj/browsersteps) - provides
   339     basic context steps to start selenium and navigate browser content.
   340  2. You may wish to have [goquery](https://github.com/PuerkitoBio/goquery)
   341     in order to work with HTML responses like with JQuery.
   342  
   343  ### Concurrency
   344  
   345  In order to support concurrency well, you should reset the state and
   346  isolate each scenario. They should not share any state. It is suggested to
   347  run the suite concurrently in order to make sure there is no state
   348  corruption or race conditions in the application.
   349  
   350  It is also useful to randomize the order of scenario execution, which you
   351  can now do with **--random** command option.
   352  
   353  **NOTE:** if suite runs with concurrency option, it concurrently runs
   354  every feature, not scenario per different features. This gives
   355  a flexibility to isolate state per feature. For example using
   356  **BeforeFeature** hook, it is possible to spin up costly service and shut
   357  it down only in **AfterFeature** hook and share the service between all
   358  scenarios in that feature. It is not advisable though, because you are
   359  risking having a state dependency.
   360  
   361  ## Contributions
   362  
   363  Feel free to open a pull request. Note, if you wish to contribute an extension to public (exported methods or types) -
   364  please open an issue before to discuss whether these changes can be accepted. All backward incompatible changes are
   365  and will be treated cautiously.
   366  
   367  ## License
   368  
   369  **Godog** is licensed under the [three clause BSD license][license]
   370  
   371  **Gherkin** is licensed under the [MIT][gherkin-license] and developed as
   372  a part of the [cucumber project][cucumber]
   373  
   374  [godoc]: http://godoc.org/github.com/DATA-DOG/godog "Documentation on godoc"
   375  [golang]: https://golang.org/  "GO programming language"
   376  [behat]: http://docs.behat.org/ "Behavior driven development framework for PHP"
   377  [cucumber]: https://cucumber.io/ "Behavior driven development framework"
   378  [gherkin]: https://github.com/cucumber/gherkin-go "Gherkin3 parser for GO"
   379  [gherkin-license]: https://en.wikipedia.org/wiki/MIT_License "The MIT license"
   380  [license]: http://en.wikipedia.org/wiki/BSD_licenses "The three clause BSD license"