github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/docs/index.md (about)

     1  ---
     2  layout: default
     3  title: Ginkgo
     4  ---
     5  {% raw  %}
     6  ![Ginkgo](./images/ginkgo.png)
     7  
     8  [Ginkgo](https://github.com/onsi/ginkgo) is a testing framework for Go designed to help you write expressive tests.  It is best paired with the [Gomega](https://github.com/onsi/gomega) matcher library.  When combined, Ginkgo and Gomega provide a rich and expressive DSL ([Domain-specific Language](https://en.wikipedia.org/wiki/Domain-specific_language)) for writing tests.
     9  
    10  Ginkgo is sometimes described as a "Behavior Driven Development" (BDD) framework.  In reality, Ginkgo is a general purpose testing framework in active use across a wide variety of testing contexts: unit tests, integration tests, acceptance test, performance tests, etc.
    11  
    12  The narrative docs you are reading here are supplemented by the [godoc](https://pkg.go.dev/github.com/onsi/ginkgo) API-level docs.  We suggest starting here to build a mental model for how Ginkgo works and understand how the Ginkgo DSL can be used to solve real-world testing scenarios.  These docs are written assuming you are familiar with Go and the Go toolchain and that you are using Ginkgo V2 (V1 is no longer supported - see [here](https://onsi.github.com/ginkgo/MIGRATING_TO_V2) for the migration guide).
    13  
    14  ## Why Ginkgo?
    15  
    16  This section captures some of Ginkgo's history and motivation.  If you just want to dive straight in, feel free to [jump ahead](#getting-started)!
    17  
    18  Like all software projects, Ginkgo was written at a particular time and place to solve a particular set of problems.
    19  
    20  The first commit to Ginkgo was made by [@onsi](https://github.com/onsi/) on August 19th, 2013 (to put that timeframe in perspective, it's roughly three months before [Go 1.2](https://golang.org/doc/go1.2) was released!)  Ginkgo came together in the highly collaborative environment fostered by Pivotal, a software company and consultancy that advocated for outcome-oriented software development built by balanced teams that embrace test-driven development.
    21  
    22  Specifically, Pivotal was one of the lead contributors to Cloud Foundry.  A sprawling distributed system, originally written in Ruby, that was slowly migrating towards the emerging distributed systems language of choice: Go.  At the time (and, arguably, to this day) the landscape of Go's testing infrastructure was somewhat anemic.  For engineers coming from the rich ecosystems of testing frameworks such as [Jasmine](https://jasmine.github.io), [rspec](https://rspec.info), and [Cedar](https://github.com/cedarbdd/cedar) there was a need for a comprehensive testing framework with a mature set of matchers in Go.
    23  
    24  The need was twofold: organizational and technical. As a growing organization Pivotal woudl benefit from a shared testing framework to be used across its many teams writing Go.  Engineers jumping from one team to another needed to be able to hit the ground running; we needed fewer testing bikesheds and more shared testing patterns.  And our test-driven development culture put a premium on tests as first-class citizens: they needed to be easy to write, easy to read, and easy to maintain.
    25  
    26  Moreover, the _nature_ of the code being built - complex distributed systems - required a testing framework that could provide for the needs unique to unit-testing and integration-testing such a system.  We needed to make testing [asynchronous behavior](https://onsi.github.io/gomega/#making-asynchronous-assertions) ubiquitous and straightforward.  We needed to have [parallelizable integration tests](#spec-parallelization) to ensure our test run-times didn't get out of control.  We needed a test framework that helped us [suss out](#spec-randomization) flaky tests and fix them.
    27  
    28  This was the context that led to Ginkgo.  Over the years the Go testing ecosystem has grown and evolved - sometimes [bringing](https://go.dev/blog/subtests) it [closer](https://golang.org/doc/go1.17#testing) to Ginkgo.  Throughout, the community's reactions to Ginkgo have been... interesting.  Some enjoy the expressive framework and rich set of matchers - for many the DSL is familiar and the CLI is productive.  Others have found the DSL off-putting, arguing that Ginkgo is not "the Go way" and that Go developers should eschew third party libraries in general.  That's OK; the world is plenty large enough for options to abound :)
    29  
    30  Happy Testing!
    31  
    32  ## Getting Started
    33  
    34  In this section we  cover installing Ginkgo, Gomega, and the `ginkgo` CLI.  We bootstrap a Ginkgo suite, write our first spec, and run it.
    35  
    36  ### Installing Ginkgo
    37  
    38  Ginkgo uses [go modules](https://go.dev/blog/using-go-modules).  To add Ginkgo to your project, assuming you have a `go.mod` file setup, just `go get` it:
    39  
    40  ```bash
    41  go get github.com/onsi/ginkgo/ginkgo
    42  go get github.com/onsi/gomega/...
    43  ```
    44  
    45  This fetches Ginkgo and installs the `ginkgo` executable under `$GOBIN` - you'll want that on your `$PATH`.  It also fetches the core Gomega matcher library and its set of supporting libraries.
    46  
    47  You should now be able to run `ginkgo version` at the command line and see the Ginkgo CLI emit a version number.
    48  
    49  ### Your First Ginkgo Suite
    50  
    51  Ginkgo hooks into Go's existing `testing` infrastructure.  That means that Ginkgo specs live in `*_test.go` files, just like standard go tests.  However, instead of using `func TestX(t *testing.T) {}` to write your tests you use the Ginkgo and Gomega DSLs.  
    52  
    53  We call a collection of Ginkgo specs in a given package a **Ginkgo suite**; and we use the word **spec** to talk about individual Ginkgo tests contained in the suite.  Though they're functionally interchangeable, we'll use the word "spec" instead of "test" to make a distinction between Ginkgo tests and traditional `testing` tests.
    54  
    55  In most Ginkgo suites there is only one `TestX` function - the entry point for Ginkgo.  Let's bootstrap a Ginkgo suite to see what that looks like.
    56  
    57  ### Bootstrapping a Suite
    58  
    59  Say you have a package named `books` that you'd like to add a Ginkgo suite to.  To bootstrap the suite run:
    60  
    61  ```bash
    62  cd path/to/books
    63  ginkgo bootstrap
    64  Generating ginkgo test suite bootstrap for books in:
    65    books_suite_test.go
    66  ```
    67  
    68  This will generate a file named `books_suite_test.go` in the `books` directory containing:
    69  
    70  ```go
    71  package books_test
    72  
    73  import (
    74    . "github.com/onsi/ginkgo/v2"
    75    . "github.com/onsi/gomega"
    76    "testing"
    77  )
    78  
    79  func TestBooks(t *testing.T) {
    80    RegisterFailHandler(Fail)
    81    RunSpecs(t, "Books Suite")
    82  }
    83  ```
    84  
    85  Let's break this down:
    86  
    87  First, `ginkgo bootstrap` generates a new test file and places it in the `books_test` package.  That small detail is actually quite important so let's take a brief detour to discuss how Go organizes code in general, and test packages in particular.
    88  
    89  #### Mental Model: Go modules, packages, and tests
    90  
    91  Go code is organized into [**modules**](https://go.dev/blog/using-go-modules).  A module is typically associated with a version controlled repository and is comprised of a series of versioned **packages**.  Each package is typically associated with a single directory within the module's file tree containing a series of source code files.  When testing Go code, unit tests for a package typically reside within the same directory as the package and are named `*_test.go`.  Ginkgo follows this convention.  It's also possible to construct test-only packages comprised solely of `*_test.go` files.  For example, module-level integration tests typically live in their own test-only package directory and exercise the various packages of the module as a whole.  As Ginkgo simply builds on top of Go's existing test infrastructure, this usecase is supported and encouraged as well.
    92  
    93  Normally, Go only allows one package to live in a given directory (in our case, it would be a package named `books`).  There is, however, one exception to this rule: a package ending in `_test` is allowed to live in the same directory as the package being tested.  Doing so instructs Go to compile the package's test suite as a **separate package**.  This means your test suite will **not** have access to the internals of the `books` package and will need to `import` the `books` package to access its external interface.  Ginkgo defaults to setting up the suite as a `*_test` package to encourage you to only test the external behavior of your package, not its internal implementation details.
    94  
    95  OK back to our bootstrap file.  After the `package books_test` declaration we import the `ginkgo` and `gomega` packages into the test's top-level namespace by performing a `.` dot-import.  Since Ginkgo and Gomega are DSLs this makes the tests more natural to read.  If you prefer, you can avoid the dot-import via `ginkgo bootstrap --nodot`.  Throughout this documentation we'll assume dot-imports.
    96  
    97  Next we define a single `testing` test: `func TestBooks(t *testing.T)`.  This is the entry point for Ginkgo - the go test runner will run this function when you run `go test` or `ginkgo`.
    98  
    99  Inside the `TestBooks` function are two lines:
   100  
   101  `RegisterFailHandler(Fail)` is the single line of glue code connecting Ginkgo to Gomega.  If we were to avoid dot-imports this would read as `gomega.RegisterFailHandler(ginkgo.Fail)` - what we're doing here is telling our matcher library (Gomega) which function to call (Ginkgo's `Fail`) in the event a failure is detected.
   102  
   103  Finally the `RunSpecs()` call tells Ginkgo to start the test suite, passing it the `*testing.T` instance and a description of the suite.  You should only ever call `RunSpecs` once and you can let Ginkgo worry about calling `*testing.T` for you.
   104  
   105  With the bootstrap file in place, you can now run your suite using the `ginkgo` command:
   106  
   107  ```bash
   108  ginkgo
   109  
   110  Running Suite: Books Suite - path/to/books
   111  ==========================================================
   112  Random Seed: 1634745148
   113  
   114  Will run 0 of 0 specs
   115  
   116  Ran 0 of 0 Specs in 0.000 seconds
   117  SUCCESS! -- 0 Passed | 0 Failed | 0 Pending | 0 Skipped
   118  PASS
   119  
   120  Ginkgo ran 1 suite in Xs
   121  Test Suite Passed
   122  ```
   123  
   124  Under the hood, `ginkgo` is simply calling `go test`.  While you _can_ run `go test` instead of the `ginkgo` CLI, Ginkgo has several capabilities that can only be accessed via `ginkgo`.  We generally recommend users embrace the `ginkgo` CLI and treat it as a first-class member of their testing toolchain.
   125  
   126  Alright, we've successfully set up and run our first suite.  Of course that suite is empty, which isn't very interesting.  Let's add some specs.
   127  
   128  #### Adding Specs to a Suite
   129  While you can add all your specs directly into `books_suite_test.go` you'll generally prefer to place your specs in separate files.  This is particularly true if you have packages with multiple files that need to be tested.  Let's say our `book` package includes a `book.go` model and we'd like to test its behavior.  We can generate a test file like so:
   130  
   131  ```bash
   132  ginkgo generate book
   133  Generating ginkgo test for Book in:
   134    book_test.go
   135  ```
   136  
   137  This will generate a test file named `book_test.go` containing:
   138  
   139  ```go
   140  package books_test
   141  
   142  import (
   143    . "github.com/onsi/ginkgo/v2"
   144    . "github.com/onsi/gomega"
   145  
   146    "path/to/books"
   147  )
   148  
   149  var _ = Describe("Books", func() {
   150  
   151  })
   152  ```
   153  
   154  As with the bootstrapped suite file, this test file is in the separate `books_test` package and dot-imports both `ginkgo` and `gomega`.  Since we're testing the external interface of `books` Ginkgo adds an `import` statement to pull the `books` package into the test.
   155  
   156  Ginkgo then adds an empty top-level `Describe` container node.  `Describe` is part of the Ginkgo DSL and takes a description and a closure function. `Describe("book", func() { })` generates a container that will contain specs that describe the behavior of `"Books"`.
   157  
   158  > By default, Go does not allow you to invoke bare functions at the top-level of a file.  Ginkgo gets around this by having its node DSL functions return a value that is intended to be discarded.  This allows us to write `var _ = Describe(...)` at the top-level which satisfies Go's top-level policies.
   159  
   160  Let's add a few specs, now, to describe our book model's ability to categorize books:
   161  
   162  ```go
   163  var _ = Describe("Books", func() {
   164    var foxInSocks, lesMis *books.Book
   165  
   166    BeforeEach(func() {
   167      lesMis = &books.Book{
   168        Title:  "Les Miserables",
   169        Author: "Victor Hugo",
   170        Pages:  2783,
   171      }
   172  
   173      foxInSocks = &books.Book{
   174        Title:  "Fox In Socks",
   175        Author: "Dr. Seuss",
   176        Pages:  24,
   177      }
   178    })
   179  
   180    Describe("Categorizing books", func() {
   181      Context("with more than 300 pages", func() {
   182        It("should be a novel", func() {
   183          Expect(lesMis.Category()).To(Equal(books.CategoryNovel))
   184        })
   185      })
   186  
   187      Context("with fewer than 300 pages", func() {
   188        It("should be a short story", func() {
   189          Expect(foxInSocks.Category()).To(Equal(books.CategoryShortStory))
   190        })
   191      })
   192    })
   193  })
   194  ```
   195  
   196  There's a lot going on here so let's break it down.
   197  
   198  Ginkgo makes extensive use of closures to allow us to build a descriptive spec hierarchy.  This hierarchy is constructed using three kinds of **nodes**:
   199  
   200  We use **container nodes** like `Describe` and `Context` to organize the different aspects of code that we are testing hierarchically.  In this case we are describing our book model's ability to categorize books across two different contexts - the behavior for large books `"With more than 300 pages"` and small books `"With fewer than 300 pages"`.
   201  
   202  We use **setup nodes** like `BeforeEach` to set up the state of our specs.  In this case, we are instantiating two new book models: `lesMis` and `foxInSocks`.
   203  
   204  Finally, we use **subject nodes** like `It` to write a spec that makes assertions about the subject under test.  In this case, we are ensuring that `book.Category()` returns the correct category `enum` based on the length of the book.  We make these assertions using Gomega's `Equal` matcher and `Expect` syntax.  You can learn much more about [Gomega here](https://onsi.github.io/gomega/#making-assertions) - the examples used throughout these docs should be self-explanatory.
   205  
   206  The container, setup, and subject nodes form a **spec tree**.  Ginkgo uses the tree to construct a flattened list of specs where each spec can have multiple setup nodes but will only have one subject node.
   207  
   208  Because there are two subject nodes, Ginkgo will identify two specs to run.  For each spec, Ginkgo will run the closures attached to any associated setup nodes and then run the closure attached to the subject node.  In order to share state between the setup node and subject node we define closure variables like `lesMis` and `foxInSocks`.  This is a common pattern and the main way that tests are organized in Ginkgo.
   209  
   210  Assuming a `book.Book` model with this behavior we can run the tests:
   211  
   212  ```bash
   213  ginkgo
   214  Running Suite: Books Suite - path/to/books
   215  ==========================================================
   216  Random Seed: 1634748172
   217  
   218  Will run 2 of 2 specs
   219  ••
   220  
   221  Ran 2 of 2 Specs in 0.000 seconds
   222  SUCCESS! -- 2 Passed | 0 Failed | 0 Pending | 0 Skipped
   223  PASS
   224  
   225  Ginkgo ran 1 suite in Xs
   226  Test Suite Passed
   227  ```
   228  
   229  Success!  We've written and run our first Ginkgo suite.  From here we can grow our test suite as we iterate on our code.
   230  
   231  The next sections will delve into the many mechanisms Ginkgo provides for writing and running specs.
   232  
   233  ## Writing Specs
   234  
   235  Ginkgo makes it easy to write expressive specs that describe the behavior of your code in an organized manner.  We've seen that Ginkgo suites are hierarchical collections of specs comprised of container nodes, setup nodes, and subject nodes organized into a spec tree.  In this section we dig into the various kinds of nodes available in Ginkgo and their properties.
   236  
   237  ### Spec Subjects: It
   238  Every Ginkgo spec has exactly one subject node.  You can add a single spec to a suite by adding a new subject node using `It(<description>, <closure>)`.  Here's a spec to validate that we can extract the author's last name from a `Book` model:
   239  
   240  ```go
   241  var _ = Describe("Books", func() {
   242    It("can extract the author's last name", func() {
   243      book = &books.Book{
   244        Title: "Les Miserables",
   245        Author: "Victor Hugo",
   246        Pages: 2783,
   247      }
   248  
   249      Expect(book.AuthorLastName()).To(Equal("Hugo"))
   250    })
   251  })
   252  ```
   253  
   254  As you can see, the description documents the intent of the spec while the closure includes assertions about our code's behavior.
   255  
   256  Ginkgo provides an alias for `It` called `Specify`.  `Specify` is functionally identical to `It` but can help your specs read more naturally.
   257  
   258  ### Extracting Common Setup: BeforeEach
   259  You can remove duplication and share common setup across specs using `BeforeEach(<closure>)` setup nodes.  Let's add specs to our `Book` suite that cover extracting the author's first name and a few natural edge cases:
   260  
   261  ```go
   262  var _ = Describe("Books", func() {
   263    var book *books.Book
   264  
   265    BeforeEach(func() {
   266      book = &books.Book{
   267        Title: "Les Miserables",
   268        Author: "Victor Hugo",
   269        Pages: 2783,
   270      }
   271      Expect(book.IsValid()).To(BeTrue())
   272    })
   273  
   274    It("can extract the author's last name", func() {
   275      Expect(book.AuthorLastName()).To(Equal("Hugo"))
   276    })
   277  
   278    It("interprets a single author name as a last name", func() {
   279      book.Author = "Hugo"
   280      Expect(book.AuthorLastName()).To(Equal("Hugo"))
   281    })
   282  
   283    It("can extract the author's first name", func() {
   284      Expect(book.AuthorFirstName()).To(Equal("Victor"))
   285    })
   286  
   287    It("returns no first name when there is a single author name", func() {
   288      book.Author = "Hugo"
   289      Expect(book.AuthorFirstName()).To(BeZero()) //BeZero asserts the value is the zero-value for its type.  In this case: ""
   290    })
   291  })
   292  ```
   293  
   294  We now have four subject nodes so Ginkgo will run four specs.  The common setup for each spec is captured in the `BeforeEach` node.  When running each spec Ginkgo will first run the `BeforeEach` closure and then the subject closure.
   295  
   296  Information is shared between closures via closure variables. It is idiomatic for these closure variables to be declared within the container node closure and initialized in the setup node closure.  Doing so ensures that each spec has a pristine, correctly initialized, copy of the shared variable.
   297  
   298  In this example, the `single author name` specs _mutate_ the shared `book` closure variable.  These mutations do not pollute the other specs because the `BeforeEach` closure reinitializes `book`.
   299  
   300  This detail is really important.  Ginkgo requires, by default, that specs be fully **independent**.  This allows Ginkgo to shuffle the order of specs and run specs in parallel.  We'll cover this in more detail later on but for now embrace this takeaway: **"Declare in container nodes, initialize in setup nodes"**.
   301  
   302  One last point - Ginkgo allows assertions to be made in both setup nodes and subject nodes.  In fact, it's a common pattern to make assertions in setup nodes to validate that the spec setup is correct _before_ making behavioral assertions in subject nodes.  In our (admittedly contrived) example here, we are asserting that the `book` we've instantiated is valid with `Expect(book.IsValid()).To(BeTrue())`.
   303  
   304  ### Organizing Specs With Container Nodes
   305  Ginkgo allows you to hierarchically organize the specs in your suite using container nodes.  Ginkgo provides three synonymous nouns for creating container nodes: `Describe`, `Context`, and `When`.  These three are functionally identical and are provided to help the spec narrative flow.  You usually `Describe` different capabilities of your code and explore the behavior of each capability across different `Context`s.
   306  
   307  Our `book` suite is getting longer and would benefit from some hierarchical organization.  Let's organize what we have so far using container nodes:
   308  
   309  ```go
   310  var _ = Describe("Books", func() {
   311    var book *books.Book
   312  
   313    BeforeEach(func() {
   314      book = &books.Book{
   315        Title: "Les Miserables",
   316        Author: "Victor Hugo",
   317        Pages: 2783,
   318      }
   319      Expect(book.IsValid()).To(BeTrue())
   320    })
   321  
   322    Describe("Extracting the author's first and last name", func() {
   323      Context("When the author has both names", func() {
   324        It("can extract the author's last name", func() {        
   325          Expect(book.AuthorLastName()).To(Equal("Hugo"))
   326        })
   327  
   328        It("can extract the author's first name", func() {
   329          Expect(book.AuthorFirstName()).To(Equal("Victor"))
   330        })      
   331      })
   332  
   333      Context("When the author only has one name", func() {
   334        BeforeEach(func() {
   335          book.Author = "Hugo"
   336        })  
   337  
   338        It("interprets the single author name as a last name", func() {
   339          Expect(book.AuthorLastName()).To(Equal("Hugo"))
   340        })
   341  
   342        It("returns empty for the first name", func() {
   343          Expect(book.AuthorFirstName()).To(BeZero())
   344        })
   345      })
   346  
   347    })
   348  })
   349  ```
   350  
   351  Using container nodes helps clarify the intent behind our suite.  The author name specs are now clearly grouped together and we're exploring the behavior of our code in different contexts.  Most importantly, we're able to scope additional setup nodes to those contexts to refine our spec setup.
   352  
   353  When Ginkgo runs a spec it runs through all the `BeforeEach` closures that appear in that spec's hierarchy from the outer-most to the inner-most.  For the `both names` specs, Ginkgo will run the outermost `BeforeEach` closure before the subject node closure.  For the `one name` specs, Ginkgo will run the outermost `BeforeEach` closure and then the innermost `BeforeEach` closure which sets `book.Author = "Hugo"`.
   354  
   355  Organizing our specs in this way can also help us reason about our spec coverage.  What additional contexts are we missing?  What edge cases should we worry about?  Let's add a few:
   356  
   357  ```go
   358  var _ = Describe("Books", func() {
   359    var book *books.Book
   360  
   361    BeforeEach(func() {
   362      book = &books.Book{
   363        Title: "Les Miserables",
   364        Author: "Victor Hugo",
   365        Pages: 2783,
   366      }
   367      Expect(book.IsValid()).To(BeTrue())
   368    })
   369  
   370    Describe("Extracting the author's first and last name", func() {
   371      Context("When the author has both names", func() {
   372        It("can extract the author's last name", func() {        
   373          Expect(book.AuthorLastName()).To(Equal("Hugo"))
   374        })
   375  
   376        It("can extract the author's first name", func() {
   377          Expect(book.AuthorFirstName()).To(Equal("Victor"))
   378        })      
   379      })
   380  
   381      Context("When the author only has one name", func() {
   382        BeforeEach(func() {
   383          book.Author = "Hugo"
   384        })  
   385  
   386        It("interprets the single author name as a last name", func() {
   387          Expect(book.AuthorLastName()).To(Equal("Hugo"))
   388        })
   389  
   390        It("returns empty for the first name", func() {
   391          Expect(book.AuthorFirstName()).To(BeZero())
   392        })
   393      })
   394  
   395      Context("When the author has a middle name", func() {
   396        BeforeEach(func() {
   397          book.Author = "Victor Marie Hugo"
   398        })  
   399  
   400        It("can extract the author's last name", func() {        
   401          Expect(book.AuthorLastName()).To(Equal("Victor"))
   402        })
   403  
   404        It("can extract the author's first name", func() {
   405          Expect(book.AuthorFirstName()).To(Equal("Victor"))
   406        })      
   407      })
   408  
   409      Context("When the author has no name", func() {
   410        It("should not be a valid book and returns empty for first and last name", func() {
   411          book.Author = ""
   412          Expect(book.IsValid()).To(BeFalse())
   413          Expect(book.AuthorLastName()).To(BeZero())
   414          Expect(book.AuthorFirstName()).To(BeZero())
   415        })
   416      })
   417    })
   418  })
   419  ```
   420  
   421  That should cover most edge cases.  As you can see we have flexibility in how we structure our specs.  Some developers prefer single assertions in `It` nodes where possible.  Others prefer consolidating multiple assertions into a single `It` as we do in the `no name` context.  Both approaches are supported and perfectly reasonable.
   422  
   423  Let's keep going and add spec out some additional behavior.  Let's test how our `book` model handles JSON encoding/decoding.  Since we're describing new behavior we'll add a new `Describe` container node:
   424  
   425  
   426  ```go
   427  var _ = Describe("Books", func() {
   428    var book *books.Book
   429  
   430    BeforeEach(func() {
   431      book = &books.Book{
   432        Title: "Les Miserables",
   433        Author: "Victor Hugo",
   434        Pages: 2783,
   435      }
   436      Expect(book.IsValid()).To(BeTrue())
   437    })
   438  
   439    Describe("Extracting the author's first and last name", func() { ... })
   440  
   441    Describe("JSON encoding and decoding", func() {
   442      It("survives the round trip", func() {
   443        encoded, err := book.AsJSON()
   444        Expect(err).NotTo(HaveOccurred())
   445  
   446        decoded, err := books.NewBookFromJSON(encoded)
   447        Expect(err).NotTo(HaveOccurred())
   448  
   449        Expect(decoded).To(Equal(book))
   450      })
   451  
   452      Describe("some JSON decoding edge cases", func() {
   453        var err error
   454  
   455        When("the JSON fails to parse", func() {
   456          BeforeEach(func() {
   457            book, err = NewBookFromJSON(`{
   458              "title":"Les Miserables",
   459              "author":"Victor Hugo",
   460              "pages":2783oops
   461            }`)
   462          })
   463  
   464          It("returns a nil book", func() {
   465            Expect(book).To(BeNil())
   466          })
   467  
   468          It("errors", func() {
   469            Expect(err).To(MatchError(books.ErrInvalidJSON))
   470          })
   471        })
   472  
   473        When("the JSON is incomplete", func() {
   474          BeforeEach(func() {
   475            book, err = NewBookFromJSON(`{
   476              "title":"Les Miserables",
   477              "author":"Victor Hugo",
   478            }`)
   479          })
   480  
   481          It("returns a nil book", func() {
   482            Expect(book).To(BeNil())
   483          })
   484  
   485          It("errors", func() {
   486            Expect(err).To(MatchError(books.ErrIncompleteJSON))
   487          })
   488        })      
   489      })
   490    })
   491  })
   492  ```
   493  
   494  In this way we can continue to grow our suite while clearly delineating the structure of our specs using a spec tree hierarchy.  Note that we use the `When` container variant in this example as it reads cleanly.  Remember that `Describe`, `Context`, and `When` are functionally equivalent aliases.
   495  
   496  ### Mental Model: How Ginkgo Traverses the Spec Hierarchy 
   497  
   498  We've delved into the three basic Ginkgo node types: container nodes, setup nodes, and subject nodes.  Before we move on let's build a mental model for how Ginkgo traverses and runs specs in a little more detail.
   499  
   500  When Ginkgo runs a suite it does so in _two phases_.  The **Tree Construction Phase** followed by the **Run Phase**.
   501  
   502  During the Tree Construction Phase Ginkgo enters all container nodes by invoking their closures to construct the spec tree.  During this phase Ginkgo is capturing and saving off the various setup and subject node closures it encounters in the tree _without running them_.  Only container node closures run during this phase and Ginkgo does not expect to encounter any assertions as no specs are running yet.
   503  
   504  Let's paint a picture of what that looks like in practice.  Consider the following set of book specs:
   505  
   506  ```go
   507  var _ = Describe("Books", func() {
   508    var book *books.Book
   509  
   510    BeforeEach(func() {
   511      //Closure A
   512      book = &books.Book{
   513        Title: "Les Miserables",
   514        Author: "Victor Hugo",
   515        Pages: 2783,
   516      }
   517      Expect(book.IsValid()).To(BeTrue())
   518    })
   519  
   520    Describe("Extracting names", func() {
   521      When("author has both names", func() {
   522        It("extracts the last name", func() {        
   523          //Closure B
   524          Expect(book.AuthorLastName()).To(Equal("Hugo"))
   525        })
   526  
   527        It("extracts the first name", func() {
   528          //Closure C
   529          Expect(book.AuthorFirstName()).To(Equal("Victor"))
   530        })      
   531      })
   532  
   533      When("author has one name", func() {
   534        BeforeEach(func() {
   535          //Closure D
   536          book.Author = "Hugo"
   537        })  
   538  
   539        It("extracts the last name", func() {
   540          //Closure E
   541          Expect(book.AuthorLastName()).To(Equal("Hugo"))
   542        })
   543  
   544        It("returns empty first name", func() {
   545          //Closure F
   546          Expect(book.AuthorFirstName()).To(BeZero())
   547        })
   548      })
   549  
   550    })
   551  })
   552  ```
   553  
   554  We could represent the spec tree that Ginkgo generates as follows:
   555  
   556  ```
   557  Describe: "Books"
   558    |_BeforeEach: <Closure-A>
   559    |_Describe: "Extracting names"
   560    |_When: "author has both names"
   561      |_It: "extracts the last name", <Closure-B>
   562      |_It: "extracts the first name", <Closure-C>
   563    |_When: "author has one name"
   564      |_BeforeEach: <Closure-D>
   565      |_It: "extracts the last name", <Closure-E>
   566      |_It: "returns empty first name", <Closure-F>
   567  ```
   568  
   569  Note that Ginkgo is saving off just the setup and subject node closures.
   570  
   571  Once the spec tree is constructed Ginkgo walks the tree to generate a flattened list of specs.  For our example, the resulting spec list would look a bit like:
   572  
   573  ```
   574  {
   575    Texts: ["Books", "Extracting names", "author has both names", "extracts the last name"],
   576    Closures: <BeforeEach-Closure-A>, <It-Closure-B>
   577  },
   578  {
   579    Texts: ["Books", "Extracting names", "author has both names", "extracts the first name"],
   580    Closures: <BeforeEach-Closure-A>, <It-Closure-C>
   581  },
   582  {
   583    Texts: ["Books", "Extracting names", "author has one name", "extracts the last name"],
   584    Closures: <BeforeEach-Closure-A>, <BeforeEach-Closure-D>, <It-Closure-E>
   585  },
   586  {
   587    Texts: ["Books", "Extracting names", "author has one name", "returns empty first name"],
   588    Closures: <BeforeEach-Closure-A>, <BeforeEach-Closure-D>, <It-Closure-F>
   589  }
   590  ```
   591  
   592  As you can see each generated spec has exactly one subject node, and the appropriate set of setup nodes.  During the Run Phase Ginkgo runs through each spec in the spec list sequentially.  When running a spec Ginkgo invokes the setup and subject nodes closures in the correct order and tracks any failed assertions.  Note that container node closures are _never_ invoked during the run phase.
   593  
   594  Given this mental model, here are a few common gotchas to avoid:
   595  
   596  #### Nodes only belong in Container Nodes
   597  
   598  Since the spec tree is constructed by traversing container nodes all Ginkgo nodes **must** only appear at the top-level of the suite _or_ nested within a container node.  They cannot appear within a subject node or setup node.  The following is invalid:
   599  
   600  ```go
   601  /* === INVALID === */
   602  var _ = It("has a color", func() {
   603    Context("when blue", func() { // NO! Nodes can only be nested in containers
   604      It("is blue", func() { // NO! Nodes can only be nested in containers
   605  
   606      })
   607    })
   608  })
   609  ```
   610  
   611  Ginkgo will emit a warning if it detects this.
   612  
   613  #### No Assertions in Container Nodes
   614  
   615  Because container nodes are invoked to construct the spec tree, but never when running specs, assertions _must_ be in subject nodes or setup nodes.  Never in container nodes.  The following is invalid:
   616  
   617  ```go
   618  /* === INVALID === */
   619  var _ = Describe("book", func() {
   620    var book *Book
   621    Expect(book.Title()).To(BeFalse()) // NO!  Place in a setup node instead.
   622  
   623    It("tests something", func() {...})
   624  })
   625  ```
   626  
   627  Ginkgo will emit a warning if it detects this.
   628  
   629  #### Avoid Spec Pollution: Don't Initialize Variables in Container Nodes
   630  
   631  We've covered this already but it bears repeating: **"Declare in container nodes, initialize in setup nodes"**.  Since container nodes are only invoked once during the tree construction phase you should declare closure variables in container nodes but always initialize them in setup nodes.  The following is 
   632  invalid can potentially infuriating to debug:
   633  
   634  ```go
   635  /* === INVALID === */
   636  var _ = Describe("book", func() {
   637    book := &book.Book{ // No!
   638      Title:  "Les Miserables",
   639      Author: "Victor Hugo",
   640      Pages:  2783,
   641    }
   642  
   643    It("is invalid with no author", func() {
   644      book.Author = "" // bam! we've changed the closure variable and it will never be reset.
   645      Expect(book.IsValid()).To(BeFalse())
   646    })
   647  
   648    It("is valid with an author", func() {
   649      Expect(book.IsValid()).To(BeTrue()) // this will fail if it runs after the previous test
   650    })
   651  })
   652  ```
   653  
   654  you should do this instead:
   655  
   656  ```go
   657  var _ = Describe("book", func() {
   658    var book *books.Book // declare in container nodes
   659  
   660    BeforeEach(func() {
   661      book = &books.Book {  //initialize in setup nodes
   662        Title:  "Les Miserables",
   663        Author: "Victor Hugo",
   664        Pages:  2783,
   665      }    
   666    })
   667  
   668    It("is invalid with no author", func() {
   669      book.Author = ""
   670      Expect(book.IsValid()).To(BeFalse())
   671    })
   672  
   673    It("is valid with an author", func() {
   674      Expect(book.IsValid()).To(BeTrue())
   675    })
   676  })
   677  
   678  ```
   679  
   680  Ginkgo currently has no mechanism in place to detect this failure mode, you'll need to stick to "declare in container nodes, initialize in setup nodes" to avoid spec pollution.
   681  
   682  ### Separating Creation and Configuration: JustBeforeEach
   683  
   684  Let's get back to our growing Book suite and explore a few more Ginkgo nodes.  So far we've met the `BeforeEach` setup node, let's introduce its closely related cousin: `JustBeforeEach`.
   685  
   686  `JustBeforeEach` is intended to solve a very specific problem but should be used with care as it can add complexity to a test suite.  Consider the following section of our JSON decoding book tests:
   687  
   688  ```go
   689  Describe("some JSON decoding edge cases", func() {
   690    var book *books.Book
   691    var err error
   692  
   693    When("the JSON fails to parse", func() {
   694      BeforeEach(func() {
   695        book, err = NewBookFromJSON(`{
   696          "title":"Les Miserables",
   697          "author":"Victor Hugo",
   698          "pages":2783oops
   699        }`)
   700      })
   701  
   702      It("returns a nil book", func() {
   703        Expect(book).To(BeNil())
   704      })
   705  
   706      It("errors", func() {
   707        Expect(err).To(MatchError(books.ErrInvalidJSON))
   708      })
   709    })
   710  
   711    When("the JSON is incomplete", func() {
   712      BeforeEach(func() {
   713        book, err = NewBookFromJSON(`{
   714          "title":"Les Miserables",
   715          "author":"Victor Hugo",
   716        }`)
   717      })
   718  
   719      It("returns a nil book", func() {
   720        Expect(book).To(BeNil())
   721      })
   722  
   723      It("errors", func() {
   724        Expect(err).To(MatchError(books.ErrIncompleteJSON))
   725      })
   726    })      
   727  })
   728  ```
   729  
   730  In each case we're creating a new `book` from an invalid snippet of JSON, ensuring the `book` is `nil` and checking that the correct error was returned.  There's some degree of deduplication that could be attained here.  We could try to pull out a shared `BeforeEach` like so:
   731  
   732  ```go
   733  /* === INVALID === */
   734  Describe("some JSON decoding edge cases", func() {
   735    var book *books.Book
   736    var err error
   737    BeforeEach(func() {
   738      book, err = NewBookFromJSON(???)
   739      Expect(book).To(BeNil())
   740    })
   741  
   742    When("the JSON fails to parse", func() {
   743      It("errors", func() {
   744        Expect(err).To(MatchError(books.ErrInvalidJSON))
   745      })
   746    })
   747  
   748    When("the JSON is incomplete", func() {
   749      It("errors", func() {
   750        Expect(err).To(MatchError(books.ErrIncompleteJSON))
   751      })
   752    })      
   753  })
   754  ```
   755  
   756  but there's no way using `BeforeEach` and `It` nodes to configure the json we use to create the book differently for each `When` container _before_ we invoke `NewBookFromJSON`.  That's where `JustBeforeEach` comes in.  As the name suggests, `JustBeforeEach` nodes run _just before_ the subject node but _after_ any other `BeforeEach` nodes.  We can leverage this behavior to write:
   757  
   758  ```go
   759  Describe("some JSON decoding edge cases", func() {
   760    var book *books.Book
   761    var err error
   762    var json string
   763    JustBeforeEach(func() {
   764      book, err = NewBookFromJSON(json)
   765      Expect(book).To(BeNil())
   766    })
   767  
   768    When("the JSON fails to parse", func() {
   769      BeforeEach(func() {
   770        json = `{
   771          "title":"Les Miserables",
   772          "author":"Victor Hugo",
   773          "pages":2783oops
   774        }`
   775      })
   776  
   777      It("errors", func() {
   778        Expect(err).To(MatchError(books.ErrInvalidJSON))
   779      })
   780    })
   781  
   782    When("the JSON is incomplete", func() {
   783      BeforeEach(func() {
   784        json = `{
   785          "title":"Les Miserables",
   786          "author":"Victor Hugo",
   787        }`
   788      })
   789      
   790      It("errors", func() {
   791        Expect(err).To(MatchError(books.ErrIncompleteJSON))
   792      })
   793    })      
   794  })
   795  ```
   796  
   797  When Ginkgo runs these specs it will _first_ run the `BeforeEach` setup closures, thereby population the `json` variable, and _then_ run the `JustBeforeEach` setup closure, thereby decoding the correct JSON string.
   798  
   799  Abstractly, `JustBeforeEach` allows you to decouple **creation** from **configuration**.  Creation occurs in the `JustBeforeEach` using configuration specified and modified by a chain of `BeforeEach`s.
   800  
   801  As with `BeforeEach` you can have multiple `JustBeforeEach` nodes at different levels of container nesting.  Ginkgo will first run all the `BeforeEach` closures from the outside in, then all the `JustBeforeEach` closures from the outside in.  While powerful and flexible overuse of `JustBeforeEach` (and nest `JustBeforeEach`es in particular!) can lead to confusing suites to be sure to use `JustBeforeEach` judiciously!d
   802  
   803  ### Spec Cleanup: AfterEach and DeferCleanup
   804  
   805  The setup nodes we've seen so far all run _before_ the spec's subject closure.  Ginkgo also provides setup nodes that run _after_ the spec's subject: `AfterEach` and `JustAfterEach`.  These are used to clean up after specs and can be particularly helpful in complex integration suites where some external system must be restored to its original state after each spec.
   806  
   807  Here's a simple (if contrived!) example to get us started.  Let's suspend disbelief and imagine that our `book` model tracks the weight of books... and that the units used to display the weight can be specified with an environment variable.  Let's spec this out:
   808  
   809  ```go
   810  Describe("Reporting book weight", func() {
   811    var book *books.Book
   812  
   813    BeforeEach(func() {
   814      book = &books.Book{
   815        Title: "Les Miserables",
   816        Author: "Victor Hugo",
   817        Pages: 2783,
   818        Weight: 500,
   819      }
   820    })
   821  
   822    Context("with no WEIGHT_UNITS environment set", func() {
   823      BeforeEach(func() {
   824        err := os.Clearenv("WEIGHT_UNITS")
   825        Expect(err).NotTo(HaveOccurred())
   826      })
   827  
   828      It("reports the weight in grams", func() {
   829        Expect(book.HumanReadableWeight()).To(Equal("500g"))
   830      })
   831    })
   832  
   833    Context("when WEIGHT_UNITS is set to oz", func() {
   834      BeforeEach(func() {
   835        err := os.Setenv("WEIGHT_UNITS", "oz")      
   836        Expect(err).NotTo(HaveOccurred())
   837      })
   838  
   839      It("reports the weight in ounces", func() {
   840        Expect(book.HumanReadableWeight()).To(Equal("17.6oz"))
   841      })
   842    })
   843  
   844    Context("when WEIGHT_UNITS is invalid", func() {
   845      BeforeEach(func() {
   846        err := os.Setenv("WEIGHT_UNITS", "smoots")
   847        Expect(err).NotTo(HaveOccurred())
   848      })
   849  
   850      It("errors", func() {
   851        weight, err := book.HumanReadableWeight()
   852        Expect(weight).To(BeZero())
   853        Expect(err).To(HaveOccurred())
   854      })
   855    })
   856  })
   857  ```
   858  
   859  These specs are... _OK_.  But we've got a subtle issue: we're not cleaning up when we override the value of `WEIGHT_UNITS`.  This is an example of spec pollution and can lead to subtle failures in unrelated specs.
   860  
   861  Let's fix this up using an `AfterEach`:
   862  
   863  ```go
   864  Describe("Reporting book weight", func() {
   865    var book *books.Book
   866  
   867    BeforeEach(func() {
   868      book = &books.Book{
   869        Title: "Les Miserables",
   870        Author: "Victor Hugo",
   871        Pages: 2783,
   872        Weight: 500,
   873      }
   874    })
   875  
   876    AfterEach(func() {
   877      err := os.Clearenv("WEIGHT_UNITS")
   878      Expect(err).NotTo(HaveOccurred())
   879    })
   880  
   881    Context("with no WEIGHT_UNITS environment set", func() {
   882      BeforeEach(func() {
   883        err := os.Clearenv("WEIGHT_UNITS")
   884        Expect(err).NotTo(HaveOccurred())
   885      })
   886  
   887      It("reports the weight in grams", func() {
   888        Expect(book.HumanReadableWeight()).To(Equal("500g"))
   889      })
   890    })
   891  
   892    Context("when WEIGHT_UNITS is set to oz", func() {
   893      BeforeEach(func() {
   894        err := os.Setenv("WEIGHT_UNITS", "oz")      
   895        Expect(err).NotTo(HaveOccurred())
   896      })
   897  
   898      It("reports the weight in ounces", func() {
   899        Expect(book.HumanReadableWeight()).To(Equal("17.6oz"))
   900      })
   901    })
   902  
   903    Context("when WEIGHT_UNITS is invalid", func() {
   904      BeforeEach(func() {
   905        err := os.Setenv("WEIGHT_UNITS", "smoots")
   906        Expect(err).NotTo(HaveOccurred())
   907      })
   908  
   909      It("errors", func() {
   910        weight, err := book.HumanReadableWeight()
   911        Expect(weight).To(BeZero())
   912        Expect(err).To(HaveOccurred())
   913      })
   914    })
   915  })
   916  ```
   917  
   918  Now we're guaranteed to clear out `WEIGHT_UNITS` after each spec as Ginkgo will run the `AfterEach` node's closure after the subject node for each spec... 
   919  
   920  ...but we've still got a subtle issue.  By clearing it out in our `AfterEach` we're assuming that `WEIGHT_UNITS` is not set when the specs run.  But perhaps it is?  What we really want to do is restore `WEIGHT_UNITS` to its original value.  We can solve this by recording the original value first:
   921  
   922  ```go
   923  Describe("Reporting book weight", func() {
   924    var book *books.Book
   925    var originalWeightUnits string
   926  
   927    BeforeEach(func() {
   928      book = &books.Book{
   929        Title: "Les Miserables",
   930        Author: "Victor Hugo",
   931        Pages: 2783,
   932        Weight: 500,
   933      }
   934      originalWeightUnits = os.Getenv("WEIGHT_UNITS")
   935    })
   936  
   937    AfterEach(func() {
   938      err := os.Setenv("WEIGHT_UNITS", originalWeightUnits)
   939      Expect(err).NotTo(HaveOccurred())
   940    })
   941    ...
   942  })
   943  ```
   944  
   945  That's better.  The specs will now clean up after themselves correctly.
   946  
   947  One quick note before we move on, you may have caught that `book.HumanReadableWeight()` returns _two_ values - a `weight` string and an `error`.  This is common pattern and Gomega has first class support for it.  The assertion:
   948  
   949  ```go
   950  Expect(book.HumanReadableWeight()).To(Equal("17.6oz"))
   951  ```
   952  
   953  is actually making two assertions under the hood.  That the first value returned by `book.HumanReadableWeight` is equal to `"17.6oz"` and that any subsequent values (i.e. the returned `error`) are `nil`.  This elegantly inlines error handling and can make your specs more readable.
   954  
   955  #### Cleaning up our Cleanup code: DeferCleanup
   956  
   957  Setup and cleanup patterns like the one above are common in Ginkgo suites.  While powerful, however, `AfterEach` nodes have a tendency to separate cleanup code from setup code.  We had to create an `originalWeightUnits` closure variable to keep track of the original environment variable in the `BeforeEach` and pass it to the `AfterEach` - this feels noisy and potential error-prone.
   958  
   959  Ginkgo provides the `DeferCleanup()` function to help solve for this usecase and bring spec setup closer to spec cleanup.  Here's what our example looks like with `DeferCleanup()`:
   960  
   961  ```go
   962  Describe("Reporting book weight", func() {
   963    var book *books.Book
   964  
   965    BeforeEach(func() {
   966      ...
   967      originalWeightUnits := os.Getenv("WEIGHT_UNITS")
   968      DeferCleanup(func() {      
   969        err := os.Setenv("WEIGHT_UNITS", originalWeightUnits)
   970        Expect(err).NotTo(HaveOccurred())
   971      })
   972    })
   973    ...
   974  })
   975  ```
   976  
   977  As you can see, `DeferCleanup()` can be called inside any setup or subject nodes.  This allows us to bring our intended cleanup closer to our setup code and avoid extracting a separate closure variable.  At first glance this code might seem confusing - as we discussed [above](#nodes-only-belong-in-container-nodes) Ginkgo does not allow you to define nodes within setup or subject nodes.  `DeferCleanup` is not a Ginkgo node, however, but rather a convenience function that knows how to track cleanup code and run it at the right time in the spec's lifecycle.
   978  
   979  > Under the hood `DeferCleanup` is generating a dynamic `AfterEach` node and adding it to the running spec.  This detail isn't important - you can simply assume that code in `DeferCleanup` has the identical runtime semantics to code in an `AfterEach`.
   980  
   981  `DeferCleanup` has a few more tricks up its sleeve.
   982  
   983  As shown above `DeferCleanup` can be passed a function that takes no arguments and returns no value.  You can also pass a function that returns a single value.  `DeferCleanup` interprets this value as an error and fails the spec if the error is non-nil - a common go pattern.  This allows us to rewrite our example as:
   984  
   985  ```go
   986  Describe("Reporting book weight", func() {
   987    var book *books.Book
   988  
   989    BeforeEach(func() {
   990      ...
   991      originalWeightUnits := os.Getenv("WEIGHT_UNITS")
   992      DeferCleanup(func() error {      
   993        return os.Setenv("WEIGHT_UNITS", originalWeightUnits)
   994      })
   995    })
   996    ...
   997  })
   998  ```
   999  
  1000  You can also pass in a function that accepts arguments, then pass those arguments in directly to `DeferCleanup`. These arguments will be captured and passed to the function when cleanup is invoked.  This allows us to rewrite our example once more as:
  1001  
  1002  ```go
  1003  Describe("Reporting book weight", func() {
  1004    var book *books.Book
  1005  
  1006    BeforeEach(func() {
  1007      ...
  1008      DeferCleanup(os.Setenv, "WEIGHT_UNITS", os.Getenv("WEIGHT_UNITS"))
  1009    })
  1010    ...
  1011  })
  1012  ```
  1013  
  1014  here `DeferCleanup` is capturing the original value of `WEIGHT_UNITS` as returned by `os.Getenv("WEIGHT_UNITS")` then passing both it into `os.Setenv` when cleanup is triggered after each spec and asserting that the error returned by `os.Setenv` is `nil`.  We've reduced our cleanup code to a single line!
  1015  
  1016  #### Separating Diagnostics Collection and Teardown: JustAfterEach
  1017  
  1018  We haven't discussed it but Ginkgo also provides a `JustAfterEach` setup node.  `JustAfterEach` closures runs _just after_ the subject node and before any `AfterEach` closures.  This can be useful if you need to collect diagnostic information about your spec _before_ invoking the clean up code in `AfterEach`.  Here's a quick example:
  1019  
  1020  ```go
  1021  Describe("Saving books to a database", func() {
  1022    AfterEach(func() {
  1023      dbClient.Clear() //clear out the database between tests
  1024    })
  1025  
  1026    JustAfterEach(func() {
  1027      if CurrentSpecReport().Failed() {
  1028        AddReportEntry("db-dump", dbClient.Dump())
  1029      }
  1030    })
  1031  
  1032    It("saves the book", func() {
  1033      err := dbClient.Save(book)
  1034      Expect(err).NotTo(HaveOccurred())
  1035    })
  1036  
  1037  })
  1038  ```
  1039  
  1040  We're, admittedly, jumping ahead a bit here by introducing a few new concepts that we'll dig into more later.  The `JustAfterEach` closure in this container will always run after the subject closure but before the `AfterEach` closure.  When it runs it will check if the current spec has failed (`CurrentSpecReport().Failed()`) and, if a failure was detected, it will download a dump of the database `dbClient.Dump()` and attach it to the spec's report `AddReportEntry()`.  It's important that this runs before the `dbClient.Clear()` invocation in `AfterEach` - so we use a `JustAfterEach`.  Of course, we could have inlined this diagnostic behavior into our `AfterEach`.
  1041  
  1042  As with `JustBeforeEach`, `JustAfterEach` can be nested in multiple containers.  Doing so can have powerful results but might lead to confusing test suites -- so use nested `JustAfterEach`es judiciously.
  1043  
  1044  ### Suite Setup and Cleanup: BeforeSuite and AfterSuite
  1045  
  1046  The setup nodes we've explored so far have all applied at the spec level.  They run Before**Each** or After**Each** spec in their associated container node.
  1047  
  1048  It is common, however, to need to perform setup and cleanup at the level of the Ginkgo suite.  This is setup that should be performed just once - before any specs run, and cleanup that should be performed just once, when all the specs have finished.  Such code is particularly common in integration tests that need to prepare environments or spin up external resources.
  1049  
  1050  Ginkgo supports suite-level setup and cleanup through two specialized **suite setup** nodes: `BeforeSuite` and `AfterSuite`.  These suite setup nodes **must** be called at the top-level of the suite and cannot be nested in containers.  Also there can be at most one `BeforeSuite` node and one `AfterSuite` node per suite.  It is idiomatic to place the suite setup nodes in the Ginkgo bootstrap suite file.
  1051  
  1052  Let's continue to build out our book tests.  Books can be stored and retrieved from an external database and we'd like to test this behavior.  To do that, we'll need to spin up a database and set up a client to access it.  We can do that `BeforeEach` spec - but doing so would be prohibitively expensive and slow.  Instead, it would be more efficient to spin up the database just once when the suite starts.  Here's how we'd do it in our `books_suite_test.go` file:
  1053  
  1054  ```go
  1055  package books_test
  1056  
  1057  import (
  1058    . "github.com/onsi/ginkgo"
  1059    . "github.com/onsi/gomega"
  1060  
  1061    "path/to/db"
  1062  
  1063    "testing"
  1064  )
  1065  
  1066  var dbRunner *db.Runner
  1067  var dbClient *db.Client
  1068  
  1069  func TestBooks(t *testing.T) {
  1070    RegisterFailHandler(Fail)
  1071    RunSpecs(t, "Books Suite")
  1072  }
  1073  
  1074  var _ = BeforeSuite(func() {
  1075    dbRunner = db.NewRunner()
  1076    Expect(dbRunner.Start()).To(Succeed())
  1077  
  1078    dbClient = db.NewClient()
  1079    Expect(dbClient.Connect(dbRunner.Address())).To(Succeed())
  1080  })
  1081  
  1082  var _ = AfterSuite(func() {
  1083    Expect(dbRunner.Stop()).To(Succeed())
  1084  })
  1085  
  1086  var _ = AfterEach(func() {
  1087     Expect(dbClient.Clear()).To(Succeed())
  1088  })
  1089  ```
  1090  
  1091  Ginkgo will run our `BeforeSuite` closure at the beginning of the [run phase](Mental Model: How Ginkgo Traverses the Spec Hierarchy) - i.e. after the spec tree has been constructed but before any specs have run.  This closure will instantiate a new `*db.Runner` - this is hypothetical code that knows how to spin up an instance of a database - and ask the runner to `Start()` a database.
  1092  
  1093  It will then instantiate a `*db.Client` and connect it to the database.  Since `dbRunner` and `dbClient` are closure variables defined at the top-level all specs in our suite will have access to them and can trust that they have been correctly initialized.
  1094  
  1095  Our specs will be manipulating the database in all sorts of ways.  However, since we're only spinning the database up once we run the risk of spec pollution if one spec does something that puts the database in a state that will influence an independent spec.  To avoid that, it's a common pattern to introduce a top-level `AfterEach` to clear out our database.  This `AfterEach` closure will run after each spec and clear out the database ensuring a pristine state for the spec.  This is often much faster than instantiating a new copy of the database!
  1096  
  1097  Finally, the `AfterSuite` closure will run after all the tests to tear down the running database via `dbRunner.Stop()`.  We can, alternatively, use `DeferCleanup` to achieve the same effect:
  1098  
  1099  ```go
  1100  var _ = BeforeSuite(func() {
  1101    dbRunner = db.NewRunner()
  1102    Expect(dbRunner.Start()).To(Succeed())
  1103    DeferCleanup(dbRunner.Stop)
  1104  
  1105    dbClient = db.NewClient()
  1106    Expect(dbClient.Connect(dbRunner.Address())).To(Succeed())
  1107  })
  1108  ```
  1109  
  1110  `DeferCleanup` is context-aware and knows that it's being called in a `BeforeSuite`.  The registered cleanup code will only run after all the specs have completed, just like `AfterSuite`.
  1111  
  1112  One quick note before we move on.  We've introduced Gomega's [`Succeed()`](https://onsi.github.io/gomega/#handling-errors) matcher here.  `Succeed()` simply asserts that a passed-in error is `nil`.  The following two assertions are equivalent:
  1113  
  1114  ```go
  1115  err := dbRunner.Start()
  1116  Expect(err).NotTo(HaveOccurred())
  1117  
  1118  /* is equivalent to */
  1119  
  1120  Expect(dbRunner.Start()).To(Succeed())
  1121  ```
  1122  
  1123  The `Succeed()` form is more succinct and reads clearly.
  1124  
  1125  > We won't get into it here but make sure to keep reading to understand how Ginkgo manages [suite parallelism](#spec-parallelization) and provides [SynchronizedBeforeSuite and SynchronizedAfterSuite](#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite) suite setup nodes.
  1126  
  1127  ### Mental Model: How Ginkgo Handles Failure
  1128  So far we've focused on how Ginkgo specs are constructed using nested nodes and how node closures are called in order when specs run.
  1129  
  1130  ...but Ginkgo is a testing framework.  And tests fail!  Let's delve into how Ginkgo handles failure.
  1131  
  1132  You typically use a matcher library, like [Gomega](https://github.com/onsi/gomega) to make assertions in your spec.  When a Gomega assertion fails, Gomega generates a failure message and passes it to Ginkgo to signal that the spec has failed.  It does this via Ginkgo's global `Fail` function.  Of course, you're allowed to call this function directly yourself:
  1133  
  1134  ```
  1135  It("can read books", func() {
  1136    if book.Title == "Les Miserables" && user.Age <= 3 {
  1137      Fail("User is too young for this book")
  1138    }
  1139    user.Read(book)
  1140  })
  1141  ```
  1142  
  1143  whether in a setup or subject node, whenever `Fail` is called Ginkgo will mark the spec as failed and record and display the message passed to `Fail`.
  1144  
  1145  But there's more.  The `Fail` function **panics** when it is called.  This allows Ginkgo to stop the current closure in its tracks - no subsequent assertions or code in the closure will run.  Ginkgo is quite opinionated about this behavior - if an assertion has failed then the current spec is not in an expected state and subsequent assertions will likely fail.  This fast-fail approach is especially useful when running slow complex integration tests.  It cannot be disabled.
  1146  
  1147  When a failure occurs in a `BeforeEach`, `JustBeforeEach`, or `It` closure Ginkgo halts execution of the current spec and cleans up by invoking any registered `AfterEach` or `JustAfterEach` closures (and any registered `DeferCleanup` closures if applicable).  This is important to ensure the spec state is cleaned up.  
  1148  
  1149  Ginkgo orchestrates this behavior by rescuing the panic thrown by `Fail` and unwinding the spec.  However, if your spec launches a **goroutine** that calls `Fail` (or, equivalently, invokes a failing Gomega assertion), there's no way for Ginkgo to rescue the panic that `Fail` throws.  This will cause the suite to panic and no subsequent specs will run.  To get around this you must rescue the panic using `defer GinkgoRecover()`.  Here's an example:
  1150  
  1151  ```go
  1152  It("panics in a goroutine", func() {
  1153    var c chan interface{}
  1154    go func() {
  1155      defer GinkgoRecover()
  1156      Fail("boom")
  1157      close(c)
  1158    }()
  1159    <-c
  1160  })
  1161  ```
  1162  
  1163  You must remember follow this pattern when making assertions in goroutines - however, if uncaught, Ginkgo's panic will include a helpful error to remind you to add `defer GinkgoRecover()` to your goroutine.
  1164  
  1165  When a failure occurs Ginkgo marks the current spec as failed and moves on to the next spec.  If, however, you'd like to stop the entire suite when the first failure occurs you can run `ginkgo --fail-fast`.
  1166  
  1167  ### Logging Output
  1168  As outlined above, when a spec fails - say via a failed Gomega assertion - Ginkgo will the failure message passed to the `Fail`  handler.  Often times the failure message generated by Gomega gives you enough information to understand and resolve the spec failure.
  1169  
  1170  But there are several contexts, particularly when running large complex integration suites, where additional debugging information is necessary to understand the root cause of a failed spec.  You'll typically only want to see this information if a spec has failed - and hide it if the spec succeeds.
  1171  
  1172  Ginkgo provides a globally available `io.Writer` called `GinkgoWriter` that solves for this usecase.  `GinkgoWriter` aggregates everything written to it while a spec is running and only emits to stdout if the test fails or is interrupted (via `^C`).
  1173  
  1174  `GinkgoWriter` includes three convenience methods:
  1175  
  1176  - `GinkgoWriter.Print(a ...interface{})` is equivalent to `fmt.Fprint(GinkgoWriter, a...)`
  1177  - `GinkgoWriter.Println(a ...interface{})` is equivalent to `fmt.Fprintln(GinkgoWriter, a...)`
  1178  - `GinkgoWriter.Printf(format string, a ...interface{})` is equivalent to `fmt.Fprintf(GinkgoWriter, format, a...)`
  1179  
  1180  You can also attach additional `io.Writer`s for `GinkgoWriter` to tee to via `GinkgoWriter.TeeTo(writer)`.  Any data written to `GinkgoWriter` will immediately be sent to attached tee writers.  All attached Tee writers can be cleared with `GinkgoWriter.ClearTeeWriters()`.
  1181  
  1182  Finally - when running in verbose mode via `ginkgo -v` anything written to `GinkgoWriter` will be immediately streamed to stdout.  This can help shorten the feedback loop when debugging a complex spec.
  1183  
  1184  ### Documenting Complex Specs: By
  1185  
  1186  As a rule, you should try to keep your subject and setup closures short and to the point.  Sometimes this is not possible, particularly when testing complex workflows in integration-style tests.  In these cases your test blocks begin to hide a narrative that is hard to glean by looking at code alone.  Ginkgo provides `By` to help in these situations.  Here's an example:
  1187  
  1188  ```go
  1189  var _ = Describe("Browsing the library", func() {
  1190    BeforeEach(func() {
  1191      By("Fetching a token and logging in")
  1192  
  1193      authToken, err := authClient.GetToken("gopher", "literati")
  1194      Expect(err).NotTo(HaveOccurred())
  1195  
  1196      Expect(libraryClient.Login(authToken)).To(Succeed())
  1197    })
  1198  
  1199    It("should be a pleasant experience", func() {
  1200      By("Entering an aisle")
  1201      aisle, err := libraryClient.EnterAisle()
  1202      Expect(err).NotTo(HaveOccurred())
  1203  
  1204      By("Browsing for books")
  1205      books, err := aisle.GetBooks()
  1206      Expect(err).NotTo(HaveOccurred())
  1207      Expect(books).To(HaveLen(7))
  1208  
  1209      By("Finding a particular book")
  1210      book, err := books.FindByTitle("Les Miserables")
  1211      Expect(err).NotTo(HaveOccurred())
  1212      Expect(book.Title).To(Equal("Les Miserables"))
  1213  
  1214      By("Checking a book out")
  1215      Expect(libraryClient.CheckOut(book)).To(Succeed())
  1216      books, err = aisle.GetBooks()
  1217      Expect(err).NotTo(HaveOccurred())
  1218      Expect(books).To(HaveLen(6))
  1219      Expect(books).NotTo(ContainElement(book))
  1220    })
  1221  })
  1222  ```
  1223  
  1224  The string passed to `By` is emitted via the [`GinkgoWriter`](#logging-output).  If a test succeeds you won't see any output beyond Ginkgo's green dot.  If a test fails, however, you will see each step printed out up to the step immediately preceding the failure.  Running with `ginkgo -v` always emits all steps.
  1225  
  1226  `By` takes an optional function of type `func()`.  When passed such a function `By` will immediately call the function.  This allows you to organize your `It`s into groups of steps but is purely optional.  
  1227  
  1228  We haven't discussed [Report Entries](#attaching-data-to-reports) yet but we'll also mention that `By` also adds a `ReportEntry` to the running spec.  This ensures that the steps outlined in `By` appear in the structure JSON and JUnit reports that Ginkgo can generate.  If passed a function `By` will measure the runtime of the function and attach the resulting duration to the report as well.
  1229  
  1230  `By` doesn't affect the structure of your specs - it's simply syntactic sugar to help you document long and complex specs.  Ginkgo has additional mechanisms to break specs up into more granular subunits with guaranteed ordering - we'll discuss [Ordered containers](#ordered-containers) in detail later.
  1231  
  1232  ### Table Specs
  1233  
  1234  We'll round out this chapter on [Writing Specs](#writing-specs) with one last topic.  Ginkgo provides an expressive DSL for writing table driven specs.  This DSL is a simple wrapper around concepts you've already met - container nodes like `Describe` and subject nodes like `It`.
  1235  
  1236  Let's write a table spec to describe the Author name functions we tested earlier:
  1237  
  1238  ```go
  1239  DescribeTable("Extracting the author's first and last name",
  1240    func(author string, isValid bool, firstName string, lastName string) {
  1241      book := &books.Book{
  1242        Title: "My Book"
  1243        Author: author,
  1244        Pages: 10,
  1245      }
  1246      Expect(book.IsValid()).To(Equal(isValid))
  1247      Expect(book.AuthorFirstName()).To(Equal(firstName))
  1248      Expect(book.AuthorLastName()).To(Equal(lastName))
  1249    },
  1250    Entry("When author has both names", "Victor Hugo", true, "Victor", "Hugo"),
  1251    Entry("When author has one name", "Hugo", true, "", "Hugo"),
  1252    Entry("When author has a middle name", "Victor Marie Hugo", true, "Victor", "Hugo"),
  1253    Entry("When author has no name", "", false, "", ""),
  1254  )
  1255  ```
  1256  
  1257  `DescribeTable` takes a string description, a **spec closure** to run for each table entry, and a set of entries.  Each `Entry` takes a string description, followed by a list of parameters.  `DescribeTable` will generate a spec for each `Entry` and when the specs run, the `Entry` parameters will be passed to the spec closure and must match the types expected by the the spec closure.
  1258  
  1259  You'll be notified with a clear message at runtime if the parameter types don't match the spec closure signature.
  1260  
  1261  #### Mental Model: Table Specs are just Syntactic Sugar
  1262  `DescribeTable` is simply providing syntactic sugar to convert its inputs into a set of standard Ginkgo nodes.  During the [Tree Construction Phase](#mental-model-how-ginkgo-traverses-the-spec-hierarchy) `DescribeTable` is generating a single container node that contains one subject node per table entry.  The description for the container node will be the description passed to `DescribeTable` and the descriptions for the subject nodes will be the descriptions passed to the `Entry`s.  During the Run Phase, when specs run, each subject node will simply invoke the spec closure passed to `DescribeTable`, passing in the parameters associated with the `Entry`.
  1263  
  1264  To put it another way, the table test above is equivalent to:
  1265  
  1266  ```go
  1267  Describe("Extracting the author's first and last name", func() {
  1268    It("When author has both names", func() {
  1269      book := &books.Book{
  1270        Title: "My Book"
  1271        Author: "Victor Hugo",
  1272        Pages: 10,
  1273      }
  1274      Expect(book.IsValid()).To(Equal(true))
  1275      Expect(book.AuthorFirstName()).To(Equal("Victor"))
  1276      Expect(book.AuthorLastName()).To(Equal("Hugo"))
  1277    })
  1278  
  1279    It("When author has one name", func() {
  1280      book := &books.Book{
  1281        Title: "My Book"
  1282        Author: "Hugo",
  1283        Pages: 10,
  1284      }
  1285      Expect(book.IsValid()).To(Equal(true))
  1286      Expect(book.AuthorFirstName()).To(Equal(""))
  1287      Expect(book.AuthorLastName()).To(Equal("Hugo"))
  1288    })
  1289  
  1290    It("When author has a middle name", func() {
  1291      book := &books.Book{
  1292        Title: "My Book"
  1293        Author: "Victor Marie Hugo",
  1294        Pages: 10,
  1295      }
  1296      Expect(book.IsValid()).To(Equal(true))
  1297      Expect(book.AuthorFirstName()).To(Equal("Victor"))
  1298      Expect(book.AuthorLastName()).To(Equal("Hugo"))
  1299    })  
  1300  
  1301    It("When author has no name", func() {
  1302      book := &books.Book{
  1303        Title: "My Book"
  1304        Author: "",
  1305        Pages: 10,
  1306      }
  1307      Expect(book.IsValid()).To(Equal(false))
  1308      Expect(book.AuthorFirstName()).To(Equal(""))
  1309      Expect(book.AuthorLastName()).To(Equal(""))
  1310    })  
  1311  })
  1312  ```
  1313  
  1314  As you can see - the table spec can capture this sort of repetitive testing much more concisely!
  1315  
  1316  Since `DescribeTable` is simply generating a container node you can nest it within other containers and surround it with setup nodes like so:
  1317  
  1318  ```go
  1319  Describe("book", func() {
  1320    var book *books.Book
  1321  
  1322    BeforeEach(func() {
  1323      book = &books.Book{
  1324        Title: "Les Miserables",
  1325        Author: "Victor Hugo",
  1326        Pages: 2783,
  1327      }
  1328      Expect(book.IsValid()).To(BeTrue())
  1329    })
  1330  
  1331    DescribeTable("Extracting the author's first and last name",
  1332      func(author string, isValid bool, firstName string, lastName string) {
  1333        book.Author = author
  1334        Expect(book.IsValid()).To(Equal(isValid))
  1335        Expect(book.AuthorFirstName()).To(Equal(firstName))
  1336        Expect(book.AuthorLastName()).To(Equal(lastName))
  1337      },
  1338      Entry("When author has both names", "Victor Hugo", true, "Victor", "Hugo"),
  1339      Entry("When author has one name", "Hugo", true, "", "Hugo"),
  1340      Entry("When author has a middle name", "Victor Marie Hugo", true, "Victor", "Hugo"),
  1341      Entry("When author has no name", "", false, "", ""),
  1342    )
  1343  
  1344  })
  1345  ```
  1346  
  1347  the `BeforeEach` closure will run before each table entry spec and set up a fresh copy of `book` for the spec closure to manipulate and assert against.
  1348  
  1349  The fact that `DescribeTable` is constructed during the Tree Construction Phase can trip users up sometimes.  Specifically, variables declared in container nodes have not been initialized yet during the Tree Construction Phase.  Because of this, the following will not work:
  1350  
  1351  ```go
  1352  /* === INVALID === */
  1353  Describe("book", func() {
  1354    var shelf map[string]*books.Book //Shelf is declared here
  1355  
  1356    BeforeEach(func() {
  1357      shelf = map[string]*books.Book{ //...and initialized here
  1358        "Les Miserables": &books.Book{Title: "Les Miserables", Author: "Victor Hugo", Pages: 2783},
  1359        "Fox In Socks": &books.Book{Title: "Fox In Socks", Author: "Dr. Seuss", Pages: 24},
  1360      }
  1361    })
  1362  
  1363    DescribeTable("Categorizing books",
  1364      func(book *books.Book, category books.Category) {
  1365        Expect(book.Category()).To(Equal(category))
  1366      },
  1367      Entry("Novels", shelf["Les Miserables"], books.CategoryNovel),
  1368      Entry("Novels", shelf["Fox in Socks"], books.CategoryShortStory),
  1369    )
  1370  })
  1371  ```
  1372  
  1373  These specs will fail.  When `DescribeTable` and `Entry` are invoked during the Tree Construction Phase `shelf` will have been declared but uninitialized.  So `shelf["Les Miserables"]` will return a `nil` pointer and the spec will fail.
  1374  
  1375  To get around this we must move access of the `shelf` variable into the body of the spec closure so that it can run at the appropriate time during the Run Phase.  We can do this like so:
  1376  
  1377  ```go
  1378  Describe("book", func() {
  1379    var shelf map[string]*books.Book //Shelf is declared here
  1380  
  1381    BeforeEach(func() {
  1382      shelf = map[string]*books.Book{ //...and initialized here
  1383        "Les Miserables": &books.Book{Title: "Les Miserables", Author: "Victor Hugo", Pages: 2783},
  1384        "Fox In Socks": &books.Book{Title: "Fox In Socks", Author: "Dr. Seuss", Pages: 24},
  1385      }
  1386    })
  1387  
  1388    DescribeTable("Categorizing books",
  1389      func(key string, category books.Category) {
  1390        Expect(shelf[key]).To(Equal(category))
  1391      },
  1392      Entry("Novels", "Les Miserables", books.CategoryNovel),
  1393      Entry("Novels", "Fox in Socks", books.CategoryShortStory),
  1394    )
  1395  })
  1396  ```
  1397  
  1398  we're now accessing the `shelf` variable in the spec closure during the Run Phase and can trust that it has been correctly instantiated by the setup node closure.
  1399  
  1400  Be sure to check out the [Table Patterns](#table-specs-patterns) section of the [Ginkgo and Gomega Patterns](#ginkgo-and-gomega-patterns) chapter to learn about a few more table-based patterns.
  1401  
  1402  #### Generating Entry Descriptions
  1403  In the examples we've shown so far, we are explicitly passing in a description for each table entry.  Recall that this description is used to generate the description of the resulting spec's Subject node.  That means it's important as it conveys the intent of the spec and is printed out in case the spec fails.
  1404  
  1405  There are times, though, when adding a description manually can be tedious, repetitive, and error prone.  Consider this example:
  1406  
  1407  ```go
  1408  var _ = Describe("Math", func() {
  1409    DescribeTable("addition",
  1410      func(a, b, c int) {
  1411        Expect(a+b).To(Equal(c))
  1412      },
  1413      Entry("1+2=3", 1, 2, 3),
  1414      Entry("-1+2=1", -1, 2, 1),
  1415      Entry("0+0=0", 0, 0, 0),
  1416      Entry("10+100=101", 10, 100, 110), //OOPS TYPO
  1417    )
  1418  })
  1419  ```
  1420  
  1421  Mercifully, Ginkgo's table DSL provides a few mechanisms to programmatically generate entry descriptions.
  1422  
  1423  **`nil` Descriptions**
  1424  
  1425  First - Entries can have their descriptions auto-generated by passing `nil` for the `Entry` description:
  1426  
  1427  ```go
  1428  var _ = Describe("Math", func() {
  1429    DescribeTable("addition",
  1430      func(a, b, c int) {
  1431        Expect(a+b).To(Equal(c))
  1432      },
  1433      Entry(nil, 1, 2, 3),
  1434      Entry(nil, -1, 2, 1),
  1435      Entry(nil, 0, 0, 0),
  1436      Entry(nil, 10, 100, 110),
  1437    )
  1438  })
  1439  ```
  1440  
  1441  This will generate entries named after the spec parameters.  In this case we'd have `Entry: 1, 2, 3`, `Entry: -1, 2, 1`, `Entry: 0, 0, 0`, `Entry: 10, 100, 110`.
  1442  
  1443  **Custom Description Generator**
  1444  
  1445  Second - you can pass a table-level Entry **description closure** to render entries with `nil` description:
  1446  
  1447  ```go
  1448  var _ = Describe("Math", func() {
  1449    DescribeTable("addition",
  1450      func(a, b, c int) {
  1451        Expect(a+b).To(Equal(c))
  1452      },
  1453      func(a, b, c int) string {
  1454        return fmt.Sprintf("%d + %d = %d", a, b, c)
  1455      }    
  1456      Entry(nil, 1, 2, 3),
  1457      Entry(nil, -1, 2, 1),
  1458      Entry(nil, 0, 0, 0),
  1459      Entry(nil, 10, 100, 110),
  1460    )
  1461  })
  1462  ```
  1463  
  1464  This will generate entries named `1 + 2 = 3`, `-1 + 2 = 1`, `0 + 0 = 0`, and `10 + 100 = 110`.
  1465  
  1466  The description closure must return a `string` and must accept the same parameters passed to the spec closure.
  1467  
  1468  **`EntryDescription()` format string**
  1469  
  1470  There's also a convenience decorator called `EntryDescription` to specify Entry descriptions as format strings:
  1471  
  1472  ```go
  1473  var _ = Describe("Math", func() {
  1474    DescribeTable("addition",
  1475      func(a, b, c int) {
  1476        Expect(a+b).To(Equal(c))
  1477      },
  1478      EntryDescription("%d + %d = %d")
  1479      Entry(nil, 1, 2, 3),
  1480      Entry(nil, -1, 2, 1),
  1481      Entry(nil, 0, 0, 0),
  1482      Entry(nil, 10, 100, 110),
  1483    )
  1484  })
  1485  ```
  1486  
  1487  This will have the same effect as the description above.
  1488  
  1489  **Per-Entry Descriptions**
  1490  
  1491  In addition to `nil` and strings you can also pass a string-returning closure or an `EntryDescription` as the first argument to `Entry`.  Doing so will cause the entry's description to be generated by the passed-in closure or `EntryDescription` format string.
  1492  
  1493  For example:
  1494  
  1495  ```go
  1496  var _ = Describe("Math", func() {
  1497    DescribeTable("addition",
  1498      func(a, b, c int) {
  1499        Expect(a+b).To(Equal(c))
  1500      },
  1501      EntryDescription("%d + %d = %d")
  1502      Entry(nil, 1, 2, 3),
  1503      Entry(nil, -1, 2, 1),
  1504      Entry("zeros", 0, 0, 0),
  1505      Entry(EntryDescription("%[3]d = %[1]d + %[2]d"), 10, 100, 110)
  1506      Entry(func(a, b, c int) string {fmt.Sprintf("%d = %d", a + b, c)}, 4, 3, 7)
  1507    )
  1508  })
  1509  ```
  1510  
  1511  Will generate entries named: `1 + 2 = 3`, `-1 + 2 = 1`, `zeros`, `110 = 10 + 100`, and `7 = 7`.
  1512  
  1513  ## Running Specs
  1514  
  1515  The previous chapter covered the basics of [Writing Specs](#writing-specs) in Ginkgo.  We explored how Ginkgo lets you use container nodes, subject nodes, and setup nodes to construct hierarchical spec trees; and how Ginkgo transforms those trees into a list of specs to run.
  1516  
  1517  In this chapter we'll shift our focus from the Tree Construction Phase to the Run Phase and dive into the various capabilities Ginkgo provides for manipulating the spec list and controlling how specs run.
  1518  
  1519  To start, let's continue to flesh out our mental model for Ginkgo.
  1520  
  1521  ### Mental Model: Ginkgo Assumes Specs are Independent
  1522  
  1523  We've already seen how Ginkgo generates a spec tree and converts it to a flat list of specs.  If you need a refresher, skim through the [Mental Model: How Ginkgo Traverses the Spec Hierarchy](#mental-model-how-ginkgo-traverses-the-spec-hierarchy) section up above.
  1524  
  1525  Lists are powerful things.  They can be sorted.  They can be randomized.  They can be filtered.  They can be distributed to multiple workers.  Ginkgo supports all of these manipulations of the spec list enabling you to randomize, filter, and parallelize your test suite with minimal effort.
  1526  
  1527  To unlock these powerful capabilities Ginkgo makes an important, foundational, assumption about the specs in your suite:
  1528  
  1529  **Ginkgo assumes specs are independent**.
  1530  
  1531  Because individual Ginkgo specs do not depend on each other, it is possible to run them in any order; it is possible to run subsets of them; it is even possible to run them simultaneously in parallel.  Ensuring your specs are independent is foundational to writing effective Ginkgo suites that make the most of Ginkgo's capabilities.
  1532  
  1533  In the next few sections we'll unpack how Ginkgo randomizes specs and supports running specs in parallel.  As we do, we'll cover principles that - if followed - will help you write specs that are independent from each other.
  1534  
  1535  ### Spec Randomization
  1536  
  1537  By default, Ginkgo will randomize the order in which the specs in a suite run.  This is done intentionally.  By randomizing specs, Ginkgo can help suss out spec pollution - accidental dependencies between specs - throughout a suite's development.
  1538  
  1539  Ginkgo's default behavior is to only randomize the order of top-level containers -- the specs *within* those containers continue to run in the order in which they are specified in the test files.  This is helpful when developing specs as it mitigates the cognitive overload of having specs within a container continuously change the order in which they run during a debugging session.
  1540  
  1541  When running on CI, or before committing code, it's good practice to instruct Ginkgo to randomize **all** specs in a suite.  You do this with the `--randomize-all` flag:
  1542  
  1543  ```bash
  1544  ginkgo --randomize-all
  1545  ```
  1546  
  1547  Ginkgo uses the current time to seed the randomization and prints out the seed near the beginning of the suite output.  If you notice intermittent spec failures that you think may be due to spec pollution, you can use the seed from a failing suite to exactly reproduce the spec order for that suite.  To do this pass the `--seed=SEED` flag:
  1548  
  1549  ```bash
  1550  ginkgo --seed=17
  1551  ```
  1552  
  1553  Because Ginkgo randomizes specs you should make sure that each spec runs from a clean independent slate.  Principles like ["Declare in container nodes, initialize in setup nodes"](#avoid-spec-pollution-dont-initialize-variables-in-container-nodes) help you accomplish this: when variables are initialized in setup nodes each spec is guaranteed to get a fresh, correctly initialized, state to operate on.  For example:
  1554  
  1555  ```go
  1556  /* === INVALID === */
  1557  Describe("Bookmark", func() {
  1558    book := &books.Book{
  1559      Title:  "Les Miserables",
  1560      Author: "Victor Hugo",
  1561      Pages:  2783,
  1562    }
  1563  
  1564    It("has no bookmarks by default", func() {
  1565      Expect(book.Bookmarks()).To(BeEmpty())
  1566    })
  1567  
  1568    It("can add bookmarks", func() {
  1569      book.AddBookmark(173)
  1570      Expect(book.Bookmarks()).To(ContainElement(173))
  1571    })
  1572  })
  1573  ```
  1574  
  1575  This suite only passes if the "has no bookmarks" spec runs before the "can add bookmarks" spec.  Instead, you should initialize the book variable in a setup node:
  1576  
  1577  ```go
  1578  Describe("Bookmark", func() {
  1579    var book *books.Book
  1580  
  1581    BeforeEach(func() {
  1582      book = &books.Book{
  1583        Title:  "Les Miserables",
  1584        Author: "Victor Hugo",
  1585        Pages:  2783,
  1586      }    
  1587    })
  1588  
  1589    It("has no bookmarks by default", func() {
  1590      Expect(book.Bookmarks()).To(BeEmpty())
  1591    })
  1592  
  1593    It("can add bookmarks", func() {
  1594      book.AddBookmark(173)
  1595      Expect(book.Bookmarks()).To(ContainElement(173))
  1596    })
  1597  })
  1598  ```
  1599  
  1600  In addition to avoiding accidental spec pollution you should make sure to avoid _intentional_ spec pollution!  Specifically, you should ensure that the correctness of your suite does not rely on the order in which specs run.
  1601  
  1602  For example:
  1603  
  1604  ```go
  1605  /* === INVALID === */
  1606  Describe("checking out a book", func() {
  1607    var book *book.Bookmarks
  1608    var err error
  1609  
  1610    It("can fetch a book from a library", func() {
  1611      book, err = libraryClient.FindByTitle("Les Miserables")
  1612      Expect(err).NotTo(HaveOccurred())
  1613      Expect(book.Title).To(Equal("Les Miserables"))
  1614    })
  1615  
  1616    It("can check out the book", func() {
  1617      Expect(library.CheckOut(book)).To(Succeed())
  1618    })
  1619  
  1620    It("no longer has the book in stock", func() {
  1621      book, err = libraryClient.FindByTitle("Les Miserables")
  1622      Expect(err).To(MatchError(books.NOT_IN_STOCK))
  1623      Expect(book).To(BeNil())
  1624    })
  1625  })
  1626  ```
  1627  
  1628  These specs are not independent - the assume that they run in order.  This means they can't be randomized or parallelized with respect to each other.
  1629  
  1630  You can fix these specs by creating a single `It` to test the behavior of checking out a book:
  1631  
  1632  ```go
  1633  Describe("checking out a book", func() {
  1634    It("can perform a checkout flow", func() {
  1635      By("fetching a book")
  1636      book, err := libraryClient.FindByTitle("Les Miserables")
  1637      Expect(err).NotTo(HaveOccurred())
  1638      Expect(book.Title).To(Equal("Les Miserables"))
  1639  
  1640      By("checking out the book")
  1641      Expect(library.CheckOut(book)).To(Succeed())
  1642  
  1643  
  1644      By("validating the book is no longer in stock")
  1645      book, err = libraryClient.FetchByTitle("Les Miserables")
  1646      Expect(err).To(MatchError(books.NOT_IN_STOCK))
  1647      Expect(book).To(BeNil())
  1648    })
  1649  })
  1650  ```
  1651  
  1652  Ginkgo also provides an alternative that we'll discuss later - you can use [Ordered Containers](#ordered-containers) to tell Ginkgo when the specs in a container must _always_ be run in order.
  1653  
  1654  Finally, if your specs need to _generate_ random numbers you can seed your pseudo-random number generator with the same seed used to seed Ginkgo's randomization.  This will help ensure that specifying the random seed fully determines the pseudo-random aspects of your suite.  You can get access to the random seed in the spec using `GinkgoRandomSeed()`
  1655  
  1656  ### Spec Parallelization
  1657  
  1658  As spec suites grow in size and complexity they have a tendency to get slower.  Thankfully the vast majority of modern computers ship with multiple CPU cores.  Ginkgo helps you use those cores to speed up your suites by running specs in parallel.  This is _especially_ useful when running large, complex, and slow integration suites where the only means to speed things up is to embrace parallelism.
  1659  
  1660  To run a Ginkgo suite in parallel you simply pass the `-p` flag to `ginkgo`:
  1661  
  1662  ```bash
  1663  ginkgo -p
  1664  ```
  1665  
  1666  this will automatically detect the optimal number of test processes to spawn based on the number of cores on your machine.  You can, instead, specify this number manually via `-procs=N`:
  1667  
  1668  ```bash
  1669  ginkgo -procs=N
  1670  ```
  1671  
  1672  And that's it!  Ginkgo will automatically run your specs in parallel and take care of collating the results into a single coherent output stream.
  1673  
  1674  At this point, though, you may be scratching your head.  _How_ does Ginkgo support parallelism given the use of shared closure variables we've seen throughout?  Consider the example from above:
  1675  
  1676  ```go
  1677  Describe("Bookmark", func() {
  1678    var book *books.Book
  1679  
  1680    BeforeEach(func() {
  1681      book = &books.Book{
  1682        Title:  "Les Miserables",
  1683        Author: "Victor Hugo",
  1684        Pages:  2783,
  1685      }    
  1686    })
  1687  
  1688    It("has no bookmarks by default", func() {
  1689      Expect(book.Bookmarks()).To(BeEmpty())
  1690    })
  1691  
  1692    It("can add bookmarks", func() {
  1693      book.AddBookmark(173)
  1694      Expect(book.Bookmarks()).To(ContainElement(173))
  1695    })
  1696  })
  1697  ```
  1698  
  1699  Both "Bookmark" specs are interrogating and mutating the same shared `book` variable.  Running the two specs in parallel would lead to an obvious data race over `book` and undefined, seemingly random, behavior.
  1700  
  1701  #### Mental Model: How Ginkgo Runs Parallel Specs
  1702  
  1703  Ginkgo ensures specs running in parallel are fully isolated from one another.  It does this by running the specs in _different processes_.  Because Ginkgo specs are assumed to be fully independent they can be harvested out to run on different worker processes - each process has its own memory space and there is, therefore, no risk for shared variable data races.
  1704  
  1705  Here's what happens under the hood when you run `ginkgo -p`:
  1706  
  1707  First, the Ginkgo CLI compiles a single test binary (via `go test -c`).  It then invokes `N` copies of the test binary.
  1708  
  1709  Each of these processes then enters the Tree Construction Phase and all processes generate an identical spec tree and, therefore, an identical list of specs to run.  The processes then enter the Run Phase and start running their specs.  They coordinate via the Ginkgo CLI (which acts a server) to figure out the next spec to run, and report to the CLI as specs finish running.  The CLI then takes care of generating a single coherent output stream of the running specs.  In essence, this is a simple map-reduce system with the CLI playing the role of a centralized server.
  1710  
  1711  With few exceptions, the different test processes do not communicate with one another and for most spec suites you, the developer, do not need to worry about which spec is running on which process.  This makes it easy to parallelize your suites and get some major performance gains.
  1712  
  1713  There are, however, contexts where you _do_ need to be aware of which process a given spec is running on.  In particular, there are several patterns for building effective parallelizable integration suites that need this information. We will explore such patterns in much more detail in the [Patterns chapter](#patterns-for-parallel-integration specs) - feel free to jump straight there if you're interested!  For now we'll simply introduce some of the building blocks that Ginkgo provides for implementing these patterns.
  1714  
  1715  #### Discovering Which Parallel Process a Spec is Running On
  1716  
  1717  Ginkgo numbers the running parallel processes from `1` to `N`.  A spec can get the index of the Ginkgo process it is running on via `GinkgoParallelProcess()`.  This can be useful in contexts where specs need to share a globally available external resource but need to access a specific shard, namespace, or instance of the resource so as to avoid spec pollution.  For example:
  1718  
  1719  ```go
  1720  Describe("Storing books in an external database", func() {
  1721    BeforeEach(func() {
  1722      namespace := fmt.Sprintf("namespace-%d", GinkgoParallelProcess())
  1723      Expect(dbClient.SetNamespace(namespace)).To(Succeed())
  1724      DeferCleanup(dbClient.ClearNamespace, namespace)
  1725    })
  1726  
  1727    It("returns empty when there are no books", func() {
  1728      Expect(dbClient.Books()).To(BeEmpty())
  1729    })
  1730  
  1731    Context("when a book is in the database", func() {
  1732      var book *books.Book
  1733      BeforeEach(func() {
  1734        lesMiserables = &books.Book{
  1735          Title:  "Les Miserables",
  1736          Author: "Victor Hugo",
  1737          Pages:  2783,
  1738        }
  1739        Expect(dbClient.Store(book)).To(Succeed())
  1740      })
  1741  
  1742      It("can fetch the book", func() {
  1743        Expect(dbClient.Books()).To(ConsistOf(book))
  1744      })
  1745  
  1746      It("can update the book", func() {
  1747        book.Author = "Victor Marie Hugo"
  1748        Expect(dbClient.Store(book)).To(Succeed())
  1749        Expect(dbClient.Books()).To(ConsistOf(book))
  1750      })
  1751  
  1752      It("can delete the book", func() {
  1753        Expect(dbClient.Delete(book)).To(Succeed())
  1754        Expect(dbClient.Books()).To(BeEmpty())      
  1755      })
  1756    })
  1757  })
  1758  ```
  1759  
  1760  Without sharding access to the database these specs would step on each other's toes and result in non-deterministic flaky behavior. By implementing sharded access to the database (e.g. `dbClient.SetNamespace` could instruct the client to prepend the `namespace` string to any keys stored in a key-value database) this suite can be trivially parallelized.  And by extending the "declare in container nodes, initialize in setup nodes" principle to apply to state stored _external_ to the suite we are able to ensure that each spec runs from a known clean shard of the database.
  1761  
  1762  Such a suite will continue to be parallelizable as it grows - enabling faster runtimes with less flakiness than would otherwise be possible in a serial-only suite.
  1763  
  1764  In addition to `GinkgoParallelProcess()`, Ginkgo provides access to the total number of running processes.  You can get this from `GinkgoConfiguration()`, which returns the state of Ginkgo's configuration, like so:
  1765  
  1766  ```go
  1767  suiteConfig, _ := GinkgoConfiguration()
  1768  totalProcesses := suiteConfig.ParallelTotal
  1769  ```
  1770  
  1771  #### Parallel Suite Setup and Cleanup: SynchronizedBeforeSuite and SynchronizedAfterSuite
  1772  
  1773  Our example above assumed the existence of a single, globally shared, running database.  How might we have set up such a database?
  1774  
  1775  You typically spin up external resources like this in the `BeforeSuite` in your suite bootstrap file.  We saw this example earlier:
  1776  
  1777  ```go
  1778  var dbClient *db.Client
  1779  var dbRunner *db.Runner
  1780  
  1781  var _ = BeforeSuite(func() {
  1782    dbRunner := db.NewRunner()
  1783    Expect(dbRunner.Start()).To(Succeed())
  1784  
  1785    dbClient = db.NewClient()
  1786    Expect(dbClient.Connect(dbRunner.Address())).To(Succeed())
  1787  })
  1788  
  1789  var _ = AfterSuite(func() {
  1790    Expect(dbClient.Cleanup()).To(Succeed())
  1791    Expect(dbRunner.Stop()).To(Succeed())
  1792  })
  1793  ```
  1794  
  1795  However, since `BeforeSuite` runs on _every_ parallel process this would result in `N` independent databases spinning up.  Sometimes that's exactly what you want - as it provides maximal isolation for the running specs and is a natural way to shard data access.  Sometimes, however, spinning up multiple external processes is too resource intensive or slow and it is more efficient to share access to a single resource.
  1796  
  1797  Ginkgo supports this usecase with `SynchronizedBeforeSuite` and `SynchronizedAfterSuite`.  Here are the full signatures for the two:
  1798  
  1799  ```go
  1800  
  1801  func SynchronizedBeforeSuite(
  1802    process1 func() []byte,
  1803    allProcesses func([]byte),
  1804  )
  1805  
  1806  func SynchronizedAfterSuite(
  1807    allProcesses func(),
  1808    process1 func(),
  1809  )
  1810  ```
  1811  
  1812  Let's dig into `SynchronizedBeforeSuite` (henceforth `SBS`) first.  `SBS` runs at the beginning of the Run Phase - before any specs have run but after the spec tree has been parsed and constructed.
  1813  
  1814  `SBS` allows us to set up state in one process, and pass information to all the other processes.  Concretely, the `process1` function runs **only** on parallel process #1.  All other parallel processes pause and wait for `process1` to complete.  Upon completion `process1` returns arbitrary data as a `[]byte` slice and this data is then passed to all parallel processes which then invoke the `allProcesses` function in parallel, passing in the `[]byte` slice.
  1815  
  1816  Similarly, `SynchronizedAfterSuite` is split into two functions.  The first, `allProcesses`, runs on all processes after they finish running specs.  The second, `process1`, only runs on process #1 - and only _after_ all other processes have finished and exited.
  1817  
  1818  We can use this behavior to set up shared external resources like so:
  1819  
  1820  ```go
  1821  var dbClient *db.Client
  1822  var dbRunner *db.Runner
  1823  
  1824  var _ = SynchronizedBeforeSuite(func() []byte {
  1825    //runs *only* on process #1
  1826    dbRunner := db.NewRunner()
  1827    Expect(dbRunner.Start()).To(Succeed())
  1828    return []byte(dbRunner.Address())
  1829  }), func(address []byte) {
  1830    //runs on *all* processes
  1831    dbClient = db.NewClient()
  1832    Expect(dbClient.Connect(string(address))).To(Succeed())
  1833    dbClient.SetNamespace(fmt.Sprintf("namespace-%d", GinkgoParallelProcess()))
  1834  })
  1835  
  1836  var _ = SynchronizedAfterSuite(func() {
  1837    //runs on *all* processes
  1838    Expect(dbClient.Cleanup()).To(Succeed())  
  1839  }, func() {
  1840    //runs *only* on process #1
  1841    Expect(dbRunner.Stop()).To(Succeed())
  1842  })
  1843  ```
  1844  
  1845  This code will spin up a single database and ensure that every parallel Ginkgo process connects to the database and sets up an appropriately sharded namespace.  Ginkgo does all the work of coordinating across these various closures and passing information back and forth - and all the complexity of the parallel setup in the test suite is now contained in the `Synchronized*` setup nodes.
  1846  
  1847  Bu the way, we can clean all this up further using `DeferCleanup`.  `DeferCleanup` is context aware and so knows that any cleanup code registered in a `BeforeSuite`/`SynchronizedBeforeSuite` should run at the end of the suite:
  1848  
  1849  ```go
  1850  var dbClient *db.Client
  1851  
  1852  var _ = SynchronizedBeforeSuite(func() []byte {
  1853    //runs *only* on process #1
  1854    dbRunner := db.NewRunner()
  1855    Expect(dbRunner.Start()).To(Succeed())
  1856    DeferCleanup(dbRunner.Stop)
  1857    return []byte(dbRunner.Address())
  1858  }), func(address []byte) {
  1859    //runs on *all* processes
  1860    dbClient = db.NewClient()
  1861    Expect(dbClient.Connect(string(address))).To(Succeed())
  1862    dbClient.SetNamespace(fmt.Sprintf("namespace-%d", GinkgoParallelProcess()))
  1863    DeferCleanup(dbClient.Cleanup)
  1864  })
  1865  ```
  1866  
  1867  #### The ginkgo CLI vs go test
  1868  One last word before we close out the topic of Spec Parallelization.  Ginkgo's process-based server-client parallelization model should make clear why you need to use the `ginkgo` CLI to run parallel specs instead of `go test`.  While Ginkgo suites are fully compatible with `go test` there _are_ some features, most notably parallelization, that require the use of the` ginkgo` CLI.
  1869  
  1870  We recommend embracing the `ginkgo` CLI as part of your toolchain and workflow.  It's designed to make the process of writing and iterating on complex spec suites as painless as possible.  Consider, for example, the `watch` subcommand:
  1871  
  1872  ```bash
  1873  ginkgo watch -p
  1874  ```
  1875  
  1876  is all you need to have Ginkgo rerun your suite - in parallel -  whenever it detects a change in the suite or any of its dependencies.  Run that in a terminal while you build out your code and get immediate feedback as you evolve your suite!
  1877  
  1878  ### Mental Model: Spec Decorators
  1879  We've emphasized throughout this chapter that Ginkgo _assumes_ specs are fully independent.  This assumption enables spec randomization and spec parallelization.
  1880  
  1881  There are some contexts, however, when spec independence is simply too difficult to achieve.  The cost of ensuring specs are independent may be too high.  Or there may be external constraints beyond your control.  When this is the case, Ginkgo allows you to explicitly control how specific specs in your suite must be run.
  1882  
  1883  We'll get into that in the next two sections.  But first we'll need to introduce **Spec Decorators**.
  1884  
  1885  So far we've seen that container nodes and subject nodes have the following signature:
  1886  
  1887  ```go
  1888  Describe("description", <closure>)
  1889  It("description", <closure>)
  1890  ```
  1891  
  1892  In actuality, the signatures for these functions is actually:
  1893  
  1894  ```go
  1895  Describe("description", args ...interface{})
  1896  It("description", args ...interface{})
  1897  ```
  1898  
  1899  and Ginkgo provides a number of additional types that can be passed in to container and subject nodes.  We call these types Spec Decorators as they decorate the spec with additional metadata.  This metadata can modify the behavior of the spec at run time.  A comprehensive [reference of all decorators](#decorator-reference) is maintained in these docs.
  1900  
  1901  Some Spec Decorators only apply to a specific node.  For example the `Offset` or `CodeLocation` decorators allow you to adjust the location of a node reported by Ginkgo (this is useful when building shared libraries that generate they're own Ginkgo nodes).
  1902  
  1903  Most Spec Decorators, however, get applied to the specs that include the decorated node.  For example, the `Serial` decorator (which we'll see in the next section) instructs Ginkgo to ensure that any specs that include the `Serial` node should only run in series and never in parallel.
  1904  
  1905  So, if `Serial` is applied to a container like so:
  1906  
  1907  ```go
  1908  Describe("Never in parallel please", Serial, func() {
  1909    It("tests one behavior", func() {
  1910      
  1911    })
  1912  
  1913    It("tests another behavior", func() {
  1914      
  1915    })
  1916  })
  1917  ```
  1918  
  1919  Then both specs generated by the subject nodes in this container will be marked as `Serial`.  If we transfer the `Serial` decorator to one of the subject nodes, however:
  1920  
  1921  ```go
  1922  Describe("Never in parallel please",  func() {
  1923    It("tests one behavior", func() {
  1924      
  1925    })
  1926  
  1927    It("tests another behavior", Serial, func() {
  1928      
  1929    })
  1930  })
  1931  ```
  1932  
  1933  now, only the spec with the "tests another behavior" subject node will be marked Serial.
  1934  
  1935  Another way of capturing this behavior is to say that most Spec Decorators apply hierarchically.  If a container node is decorated with a decorator then the decorator applies to all its child nodes.
  1936  
  1937  One last thing - spec decorators can also decorate [Table Specs](#table-specs):
  1938  
  1939  ```go
  1940  DescribeTable("Table", Serial, ...)
  1941  Entry("Entry", FlakeAttempts(3), ...)
  1942  ```
  1943  
  1944  will all work just fine.  You can put the decorators anywhere after the description strings.
  1945  
  1946  The [reference](#decorator-reference) clarifies how decorator inheritance works for each decorator and which nodes can accept which decorators.
  1947  
  1948  ### Serial Specs
  1949  
  1950  When you run `ginkgo -p` Ginkgo spins up multiple processes and distributes **all** your specs across those processes.  As such, any spec must be able to run in parallel with any other spec.
  1951  
  1952  Sometimes, however, you simply _must_ enforce that a spec runs in series.  Perhaps it is a performance benchmark spec that cannot run in parallel with any other work.  Perhaps it is a spec that is known to exercise an edge case that places some external resource into a known-bad state and, therefore, must be run independently of all other specs.  Perhaps it is simply a spec that is just so resource intensive that it must run alone to avoid exhibiting flaky behavior.
  1953  
  1954  Whatever the reason, Ginkgo allows you to decorate container and subject nodes with `Serial`:
  1955  
  1956  ```go
  1957  
  1958  Describe("Something expensive", Serial, func() {
  1959    It("is a resource hog that can't run in parallel", func() {
  1960      ...
  1961    })
  1962  
  1963    It("is another resource hog that can't run in parallel", func() {
  1964      ...
  1965    })
  1966  })
  1967  ```
  1968  
  1969  Ginkgo will guarantee that these specs will never run in parallel with other specs.
  1970  
  1971  Under the hood Ginkgo does this by running `Serial` at the **end** of the suite on parallel process #1.  When it detects the presence of `Serial` specs, process #1 will wait for all other processes to exit before running the `Serial` specs.
  1972  
  1973  ### Ordered Containers
  1974  
  1975  By default Ginkgo does not guarantee the order in which specs run.  As we've seen, `ginkgo --randomize-all` will shuffle the order of all specs and `ginkgo -p` will distribute all specs across multiple workers.  Both operations mean that the order in which specs run cannot be guaranteed.
  1976  
  1977  There are contexts, however, when you must guarantee the order in which a set of specs run.  For example, you may be testing a complex flow of behavior and would like to break your spec up into multiple units instead of having one enormous `It`.  Or you may have to perform some expensive setup for a set of specs and only want to perform that setup **once** _before_ the specs run.
  1978  
  1979  Ginkgo provides `Ordered` containers to solve for these usecases.  Specs in `Ordered` containers are guaranteed to run in the order in which they appear.  Let's pull out an example from before; recall that the following is invalid:
  1980  
  1981  ```go
  1982  /* === INVALID === */
  1983  Describe("checking out a book", func() {
  1984    var book *book.Bookmarks
  1985    var err error
  1986  
  1987    It("can fetch a book from a library", func() {
  1988      book, err = libraryClient.FetchByTitle("Les Miserables")
  1989      Expect(err).NotTo(HaveOccurred())
  1990      Expect(book.Title).To(Equal("Les Miserables"))
  1991    })
  1992  
  1993    It("can check out the book", func() {
  1994      Expect(library.CheckOut(book)).To(Succeed())
  1995    })
  1996  
  1997    It("no longer has the book in stock", func() {
  1998      book, err = libraryClient.FetchByTitle("Les Miserables")
  1999      Expect(err).To(MatchError(books.NOT_IN_STOCK))
  2000      Expect(book).To(BeNil())
  2001    })
  2002  })
  2003  ```
  2004  
  2005  These specs break the "declare in container nodes, initialize in setup nodes" principle.  When randomizing specs or running in parallel Ginkgo will not guarantee that these specs run in order.  Because the specs are mutating the same shared set of variables they will behave in non-deterministic ways when shuffled.  In fact, when running in parallel, specs on different parallel processes will be accessing completely different local copies of the closure variables!
  2006  
  2007  When we introduced this example we recommended condensing the tests into a single `It` and using `By` to document the test.  `Ordered` containers provide an alternative that some users might prefer, stylistically:
  2008  
  2009  ```go
  2010  Describe("checking out a book", Ordered, func() {
  2011    var book *book.Bookmarks
  2012    var err error
  2013  
  2014    It("can fetch a book from a library", func() {
  2015      book, err = libraryClient.FetchByTitle("Les Miserables")
  2016      Expect(err).NotTo(HaveOccurred())
  2017      Expect(book.Title).To(Equal("Les Miserables"))
  2018    })
  2019  
  2020    It("can check out the book", func() {
  2021      Expect(library.CheckOut(book)).To(Succeed())
  2022    })
  2023  
  2024    It("no longer has the book in stock", func() {
  2025      book, err = libraryClient.FetchByTitle("Les Miserables")
  2026      Expect(err).To(MatchError(books.NOT_IN_STOCK))
  2027      Expect(book).To(BeNil())
  2028    })
  2029  })
  2030  ```
  2031  
  2032  here we've decorated the `Describe` container as `Ordered`.  Ginkgo will guarantee that specs in an `Ordered` container will run sequentially, in the order they are written.  Specs in an `Ordered` container may run in parallel with respect to _other_ specs, but they will always run sequentially on the same parallel process.  This allows specs in `Ordered` containers to rely on mutating local closure state.
  2033  
  2034  The `Ordered` decorator can only appear on a container node.  Any container nodes nested within a container node will automatically be considered `Ordered` and there is no way to mark a node within an `Ordered` container as "not `Ordered`".
  2035  
  2036  > Ginkgo did not include support for `Ordered` containers for quite some time.  As you can see `Ordered` containers make it possible to circumvent the "Declare in container nodes, initialize in setup nodes" principle; and they make it possible to write dependent specs  This comes at a cost, of course - specs in `Ordered` containers cannot be fully parallelized which can result in slower suite runtimes.  Despite these cons, pragmatism prevailed and `Ordered` containers were introduced in response to real-world needs in the community.  Nonetheless, we recommend using `Ordered` containers only when needed.
  2037  
  2038  #### Setup in Ordered Containers: BeforeAll and AfterAll
  2039  
  2040  You can include all the usual setup nodes in an `Ordered` container however and they continue to operate in the same way.  `BeforeEach` will run before every spec and `AfterEach` will run after every spec.  This applies to all setup nodes in a spec's hierarchy.  So `BeforeEach`/`AfterEach` nodes that are present outside the `Ordered` container will still run before and after each spec in the container.
  2041  
  2042  There are, however, two new setup node variants that can be used within `Ordered` containers: `BeforeAll` and `AfterAll`.
  2043  
  2044  `BeforeAll` closures will run exactly once before any of the specs within the `Ordered` container.  `AfterAll` closures will run exactly once after the last spec has finished running.  Here's an extension of our earlier example that illustrates how these nodes might be used:
  2045  
  2046  ```go
  2047  Describe("checking out a book", Ordered, func() {
  2048    var libraryClient *library.Client
  2049    var book *book.Bookmarks
  2050    var err error
  2051  
  2052    BeforeAll(func() {
  2053      libraryClient = library.NewClient()
  2054      Expect(libraryClient.Connect()).To(Succeed())
  2055    })
  2056  
  2057    It("can fetch a book from a library", func() {
  2058      book, err = libraryClient.FetchByTitle("Les Miserables")
  2059      Expect(err).NotTo(HaveOccurred())
  2060      Expect(book.Title).To(Equal("Les Miserables"))
  2061    })
  2062  
  2063    It("can check out the book", func() {
  2064      Expect(library.CheckOut(book)).To(Succeed())
  2065    })
  2066  
  2067    It("no longer has the book in stock", func() {
  2068      book, err = libraryClient.FetchByTitle("Les Miserables")
  2069      Expect(err).To(MatchError(books.NOT_IN_STOCK))
  2070      Expect(book).To(BeNil())
  2071    })
  2072  
  2073    AfterAll(func() {
  2074      Expect(libraryClient.Disconnect()).To(Succeed())
  2075    })
  2076  })
  2077  ```
  2078  
  2079  here we only set up the `libraryCLient` once before all the specs run, and then tear it down once all the specs complete.
  2080  
  2081  `BeforeAll` and `AfterAll` nodes can only be introduced within an `Ordered` container.  `BeforeAll` and `AfterAll` can also be nested within containers that appear in `Ordered` containers - in such cases they will run before/after the specs in that nested container.
  2082  
  2083  As always, you can also use `DeferCleanup`.  Since `DeferCleanupe` is context aware, it will detect when it is called in a `BeforeAll` and behave like an `AfterAll` at the same nesting level.  The following is equivalent to the example above:
  2084  
  2085  ```go
  2086  BeforeAll(func() {
  2087    libraryClient = library.NewClient()
  2088    Expect(libraryClient.Connect()).To(Succeed())  
  2089    DeferCleanup(libraryClient.Disconnect)
  2090  })
  2091  
  2092  ```
  2093  
  2094  #### Failure Handling in Ordered Containers
  2095  
  2096  Normally, when a spec fails Ginkgo moves on to the next spec.  This is possible because Ginkgo assumes, by default, that all specs are independent.  However `Ordered` containers explicitly opt in to a different behavior.  Spec independence cannot be guaranteed in `Ordered` containers, so Ginkgo treats failures differently.
  2097  
  2098  When a spec in an `Ordered` container fails all subsequent specs are skipped. Ginkgo will then run any `AfterAll` node closures to clean up after the specs.  This failure behavior cannot be overridden.
  2099  
  2100  #### Combining Serial and Ordered
  2101  
  2102  To sum up: specs decorated with `Serial` are guaranteed to run in series and never in parallel with other specs.  Specs in `Ordered` containers are guaranteed to run in order sequentially on the same parallel process but may be parallelized with specs in other containers.
  2103  
  2104  You can combine both decorators to have specs in `Ordered` containers run serially with respect to all other specs.  To do this, you must apply the `Serial` decorator to the same container that has the `Ordered` decorator.  You cannot declare a spec within an `Ordered` container as `Serial` independently.
  2105  
  2106  ### Filtering Specs
  2107  
  2108  There are several contexts where you may only want to run a _subset_ of specs in a suite.  Perhaps some specs are slow and only need to be run on CI or before a commit.  Perhaps you're only working on a subset of the code and want to run the relevant subset of the specs, or even just one spec.  Perhaps a spec is under development and isn't ready to run yet.  Perhaps a spec should always be skipped if a certain condition is met.
  2109  
  2110  Ginkgo supports all these usecases (and more) through a wide variety of mechanisms to organize and filter specs.  Let's dig into them.
  2111  
  2112  #### Pending Specs
  2113  You can mark individual specs, or containers of specs, as `Pending`.  This is used to denote that a spec or its code is under development and should not be run.  None of the other filtering mechanisms described in this chapter can override a `Pending` spec and cause it to run.
  2114  
  2115  Here are all the ways you can mark a spec as `Pending`:
  2116  
  2117  ```go
  2118  // With the Pending decorator:
  2119  Describe("these specs aren't ready for primetime", Pending, func() { ... })
  2120  It("needs work", Pending, func() { ... })
  2121  It("placeholder", Pending) //note: pending specs don't require a closure
  2122  DescribeTable("under development", Pending, func() { ... }, ...)
  2123  Entry("this one isn't working yet", Pending)
  2124  
  2125  // By prepending `P` or `X`:
  2126  PDescribe("these specs aren't ready for primetime", func() { ... })
  2127  XDescribe("these specs aren't ready for primetime", func() { ... })
  2128  PIt("needs work", func() { ... })
  2129  XIt("placeholder")
  2130  PDescribeTable("under development", func() {...}, ...)
  2131  XEntry("this one isn't working yet")
  2132  ```
  2133  
  2134  Ginkgo will never run a pending spec.  If all other specs in the suite pass the suite will be considered successful.  You can, however, run `ginkgo --fail-on-pending` to have Ginkgo fail the suite if it detects any pending specs.  This can be useful on CI if you want to enforce a policy that pending specs should not be committed to source control.
  2135  
  2136  Note that pending specs are declared at compile time.  You cannot mark a spec as pending dynamically at runtime.  For that, keep reading...
  2137  
  2138  #### Skipping Specs
  2139  If you need to skip a spec at runtime you can use Ginkgo's `Skip(...)` function.  For example, say we want to skip a spec if some condition is not met.  We could:
  2140  
  2141  ```go
  2142  It("should do something, if it can", func() {
  2143    if !someCondition {
  2144      Skip("Special condition wasn't met.")
  2145    }
  2146    ...
  2147  })
  2148  ```
  2149  
  2150  This will cause the current spec to skip.  Ginkgo will immediately end execution (`Skip`, just like `Fail`, throws a panic to halt execution of the current spec) and mark the spec as skipped.  The message passed to `Skip` will be included in the spec report.  Note that `Skip` **does not** fail the suite.  Even skipping all the specs in the suite will not cause the suite to fail.  Only an explicitly failure will do so.
  2151  
  2152  You can call `Skip` in any subject or setup nodes.  If called in a `BeforeEach`, `Skip` will skip the current spec.  If called in a `BeforeAll`, `Skip` will skip all specs in the `Ordered` container (however, skipping an individual spec in an `Ordered` container does not skip subsequent specs).  If called in a `BeforeSuite`, `Skip` will skip the entire suite.
  2153  
  2154  You cannot call `Skip` in a container node - `Skip` only applies during the Run Phase, not the Tree Construction Phase.
  2155  
  2156  #### Focused Specs
  2157  Ginkgo allows you to `Focus` individual specs, or containers of specs.  When Ginkgo detects focused specs in a suite it skips all other specs and _only_ runs the focused specs.
  2158  
  2159  Here are all the ways you can mark a spec as focused:
  2160  
  2161  ```go
  2162  // With the Focus decorator:
  2163  Describe("just these specs please", Focus, func() { ... })
  2164  It("just me please", Focus, func() { ... })
  2165  DescribeTable("run this table", Focus, func() { ... }, ...)
  2166  Entry("run just this entry", Focus)
  2167  
  2168  // By prepending `F`:
  2169  FDescribe("just these specs please", func() { ... })
  2170  FIt("just me please", func() { ... })
  2171  FDescribeTable("run this table", func() { ... }, ...)
  2172  FEntry("run just this entry", ...)
  2173  ```
  2174  
  2175  doing so instructs Ginkgo to only run the focused specs.  To run all specs, you'll need to go back and remove all the `F`s and `Focus` decorators.
  2176  
  2177  You can nest focus declarations.  Doing so follows a simple rule: if a child node is marked as focused, any of its ancestor nodes that are marked as focused will be unfocused.  This behavior was chosen as it most naturally maps onto the developers intent when iterating on a spec suite.  For example:
  2178  
  2179  ```go
  2180  FDescribe("some specs you're debugging", func() {
  2181    It("might be failing", func() { ... })
  2182    It("might also be failing", func() { ... })
  2183  })
  2184  ```
  2185  
  2186  will run both specs.  Let's say you discover that the second spec is the one failing and you want to rerun it rapidly as you iterate on the code.  Just `F` it:
  2187  
  2188  ```go
  2189  FDescribe("some specs you're debugging", func() {
  2190    It("might be failing", func() { ... })
  2191    FIt("might also be failing", func() { ... })
  2192  })
  2193  ```
  2194  
  2195  now only the second spec will run because of Ginkgo's focus rules.
  2196  
  2197  We refer to the focus filtering mechanism as "Programmatic Focus" as the focus declarations are "programmed in" at compile time.  Programmatic focus can be super helpful when developing or debugging a test suite, however it can be a real pain to accidentally commit a focused spec. So...
  2198  
  2199  When Ginkgo detects that a passing test suite has programmatically focused tests it causes the suite to exit with a non-zero status code.  The logs will show that the suite succeeded, but will also include a message that says that programmatic specs were detected.  The non-zero exit code will be caught by most CI systems and flagged, allowing developers to go back and unfocus the specs they committed. 
  2200  
  2201  You can unfocus _all_ specs in a suite by running `ginkgo unfocus`.  This simply strips off any `F`s off of `FDescribe`, `FContext`, `FIt`, etc... and removes an `Focus` decorators.
  2202  
  2203  #### Spec Labels
  2204  `Pending`, `Skip`, and `Focus` provide ad-hoc mechanisms for filtering suites.  For particularly large and complex suites, however, you may need a more structured mechanism for organizing and filtering specs.  For such usecases, Ginkgo provides labels.
  2205  
  2206  Labels are simply textual tags that can be attached to Ginkgo container and setup nodes via the `Label` decorator.  Here are the ways you can attach labels to a node:
  2207  
  2208  ```go
  2209  It("is labelled", Label("first label", "second label"), func() { ... })
  2210  It("is labelled", Label("first label"), Label("second label"), func() { ... })
  2211  ```
  2212  
  2213  Labels can container arbitrary strings but cannot contain any of the characters in the set: `"&|!,()/"`.  The labels associated with a spec is the union of all the labels attached to the spec's container nodes and subject nodes. For example:
  2214  
  2215  ```go
  2216  Describe("Storing books", Label("integration", "storage"), func() {
  2217    It("can save entire shelves of books to the central library", Label("network", "slow", "library storage"), func() {
  2218      // has labels [integration, storage, network, slow, library storage]
  2219    })
  2220  
  2221    It("cannot delete books from the central library", Label("network", "library storage"), func() {
  2222      // has labels [integration, storage, network, library storage]    
  2223    })
  2224  
  2225    It("can check if a book is stored in the central library", Label("network", "slow", "library query"), func() {
  2226      // has labels [integration, storage, network, slow, library query]    
  2227    })
  2228  
  2229    It("can save books locally", Label("local"), func() {
  2230      // has labels [integration, storage, local]    
  2231    })
  2232  
  2233    It("can delete books locally", Label("local"), func() {
  2234      // has labels [integration, storage, local]        
  2235    })
  2236  })
  2237  ```
  2238  
  2239  The labels associated with a spec are included in any generated reports and are emitted alongside the spec whenever it fails.
  2240  
  2241  The real power, of labels, however, is around filtering.  You can filter by label using via the `ginkgo --label-filter=QUERY` flag.  Ginkgo will accept and parse a simple filter query language with the following operators and rules:
  2242  
  2243  - The `&&` and `||` logical binary operators representing AND and OR operations.
  2244  - The `!` unary operator representing the NOT operation.
  2245  - The `,` binary operator equivalent to `||`.
  2246  - The `()` for grouping expressions.
  2247  - All other characters will match as label literals.  Label matches are **case intensive** and trailing and leading whitespace is trimmed.
  2248  - Regular expressions can be provided using `/REGEXP/` notation.
  2249  
  2250  To build on our example above, here are some label filter queries and their behavior:
  2251  
  2252  | Query | Behavior |
  2253  | --- | --- |
  2254  | `ginkgo --label-filter="integration"` | Match any specs with the `integration` label |
  2255  | `ginkgo --label-filter="!slow"` | Avoid any specs labelled `slow` |
  2256  | `ginkgo --label-filter="network && !slow"` | Run specs labelled `network` that aren't `slow` |
  2257  | `ginkgo --label-filter=/library/` | Run specs with labels matching the regular expression `library` - this will match the three library-related specs in our example.
  2258  
  2259  You can list the labels used in a given package using the `ginkgo labels` subcommand.  This does a simple/naive scan of your test files for calls to `Label` and returns any labels it finds.
  2260  
  2261  You can iterate on different filters quickly with `ginkgo --dry-run -v --label-filter=FILTER`.  This will cause Ginkgo to tell you which specs it will run for a given filter without actually running anything.
  2262  
  2263  Finally, in addition to specifying Labels on subject and container nodes you can also specify suite-wide labels by decorating the `RunSpecs` command with `Label`:
  2264  
  2265  ```go
  2266  func TestBooks(t *testing.T) {
  2267    RegisterFailHandler(Fail)
  2268    RunSpecs(t, "Books Suite", Label("books", "this-is-a-suite-level-label"))
  2269  }
  2270  ```
  2271  
  2272  Suite-level labels apply to the entire suite making it easy to filter out entire suites using label filters.
  2273  
  2274  
  2275  #### Location-Based Filtering
  2276  
  2277  Ginkgo allows you to filter specs based on their source code location from the command line.  You do this using the `ginkgo --focus-file` and `ginkgo --skip-file` flags.  Ginkgo will only run specs that are in files that _do_ match the `--focus-file` filter *and* _don't_ match the `--skip-file` filter.  You can provide multiple `--focus-file` and `--skip-file` flags.  The `--focus-file`s will be ORed together and the `--skip-file`s will be ORed together.
  2278  
  2279  The argument passed to `--focus-file`/`--skip-file` is a file filter and takes one of the following forms:
  2280  
  2281  - `FILE_REGEX` - will match specs in files who's absolute path matches the FILE_REGEX.  So `ginkgo --focus-file=foo` will match specs in files like `foo_test.go` or `/foo/bar_test.go`.
  2282  - `FILE_REGEX:LINE` - will match specs in files that match FILE_REGEX where at least one node in the spec is constructed at line number `LINE`.
  2283  - `FILE_REGEX:LINE1-LINE2` - will match specs in files that match FILE_REGEX where at least one node in the spec is constructed at a line within the range of `[LINE1:LINE2)`.
  2284  
  2285  You can specify multiple comma-separated `LINE` and `LINE1-LINE2` arguments in a single `--focus-file/--skip-file` (e.g. `--focus-file=foo:1,2,10-12` will apply filters for line 1, line 2, and the range [10-12)).  To specify multiple files, pass in multiple `--focus-file` or `--skip-file` flags.
  2286  
  2287  To filter a spec based on its line number you must use the exact line number where one of the spec's nodes (e.g. `It()`) is called.  You can't use a line number that is "close" to the node, or within the node's closure.
  2288  
  2289  #### Description-Based Filtering
  2290  
  2291  Finally, Ginkgo allows you to filter specs based on the description strings that appear in their subject nodes and/or container hierarchy nodes.  You do this using the `ginkgo --focus=REGEXP` and `ginkgo --skip=REGEXP` flags.
  2292  
  2293  When these flags are provided Ginkgo matches the passed-in regular expression against the fully concatenated description of each spec.  For example the spec tree:
  2294  
  2295  ```go
  2296  Describe("Studying books", func() {
  2297    Context("when the book is long", func() {
  2298      It("can be read over multiple sessions", func() {
  2299        
  2300      })
  2301    })
  2302  })
  2303  ```
  2304  
  2305  will generate a spec with description `"Studying books when the book is long can be read over multiple sessions"`.
  2306  
  2307  When `--focus` and/or `--skip` are provided Ginkgo will _only_ run specs with descriptions that match the focus regexp **and** _don't_ match the skip regexp.  You can provide `--focus` and `--skip` multiple times.  The `--focus` filters will be ORed together and the `--skip` filters will be ORed together.  For example, say you have the following specs:
  2308  
  2309  ```go
  2310  It("likes dogs", func() {...})
  2311  It("likes purple dogs", func() {...})
  2312  It("likes cats", func() {...})
  2313  It("likes dog fish", func() {...})
  2314  It("likes cat fish", func() {...})
  2315  It("likes fish", func() {...})
  2316  ```
  2317  
  2318  then `ginkgo --focus=dog --focus=fish --skip=cat --skip=purple` will only run `"likes dogs"`, `"likes dog fish"`, and `"likes fish"`.
  2319  
  2320  The description-based `--focus` and `--skip` flags were Ginkgo's original command-line based filtering mechanism and will continue to be supported - however we recommend using labels when possible as the label filter language is more flexible and easier to reason about.
  2321  
  2322  #### Combining Filters
  2323  
  2324  To sum up, we've seen that Ginkgo supports the following mechanisms for organizing and filtering specs:
  2325  
  2326  - Specs that are marked as `Pending` at compile-time never run.
  2327  - At run-time, specs can be individually skipped by calling `Skip()`
  2328  - Specs that are programmatically focused with the `Focus` decorator at compile-time run to the exclusion of other specs.
  2329  - Specs can be labelled with the `Label()` decorator.  `ginkgo --label-filter=QUERY` will apply a label filter query and only run specs that pass the filter.
  2330  - `ginkgo --focus-file=FILE_FILTER/--skip-file=FILE_FILTER` will filter specs based on their source code location.
  2331  - `ginkgo --focus=REGEXP/--skip=REGEXP` will filter specs based on their descriptions.
  2332  
  2333  These mechanisms can all be used in concert.  They combine with the following rules:
  2334  
  2335  - `Pending` specs are always pending and can never be coerced to run by another filtering mechanism.
  2336  - Specs that invoke `Skip()` will always be skipped regardless of other filtering mechanisms.
  2337  - The CLI based filters (`--label-filter`, `--focus-file/--skip-file`, `--focus/--skip`) **always** override any programmatic focus.
  2338  - When multiple CLI filters are provided they are all ANDed together.  The spec must satisfy the label filter query **and** any location-based filters **and** any description based filters.
  2339  
  2340  ### Repeating Spec Runs and Managing Flaky Specs
  2341  
  2342  Ginkgo wants to help you write reliable, deterministic, tests.  Flaky specs - i.e. specs that fail _sometimes_ in non-deterministic or difficult to reason about ways - can be incredibly frustrating to debug and can erode faith in the value of a spec suite.
  2343  
  2344  Ginkgo provides a few mechanisms to help you suss out and debug flaky specs.  If you suspect a flaky spec you can rerun a suite repeatedly until it fails via:
  2345  
  2346  ```bash
  2347  ginkgo --until-it-fails
  2348  ```
  2349  
  2350  This will compile the suite once and then run it repeatedly, forever, until a failure is detected.  This flag pairs well with `--randomize-all` and `-p` to try and suss out failures due to accidental spec dependencies.
  2351  
  2352  Since `--until-it-fails` runs indefinitely, until a failure is detected, it is not appropriate for CI environments.  If you'd like to help ensure that flaky specs don't creep into your codebase you can use:
  2353  
  2354  ```bash
  2355  ginkgo --repeat=N
  2356  ```
  2357  
  2358  to have Ginkgo repeat your test suite up to `N` times or until a failure occurs, whichever comes first.  This is especially valuable in CI environments.
  2359  
  2360  One quick note on `--repeat`: when you invoke `ginkgo --repeat=N` Ginkgo will run your suite a total of `1+N` times.  In this way, `ginkgo --repeat=N` is similar to `go test --count=N+1` **however** `--count` is one of the few `go test` flags that is **not** compatible with Ginkgo suites.  Please use `ginkgo --repeat=N` instead.
  2361  
  2362  Both `--until-it-fails` and `--repeat` help you identify flaky specs early.  Doing so will help you debug flaky specs while the context that introduced them is fresh.
  2363  
  2364  However.  There are times when the cost of preventing and/or debugging flaky specs simply is simply too high and specs simply need to be retried.  While this should never be the primary way of dealing with flaky specs, Ginkgo is pragmatic about this reality and provides a mechanism for retrying specs.
  2365  
  2366  You can retry all specs in a suite via:
  2367  
  2368  ```bash
  2369  ginkgo --flake-attempts=N
  2370  ```
  2371  
  2372  Now, when a spec fails Ginkgo will not automatically mark the suite as failed.  Instead it will attempt to rerun the spec up to `N` times.  If the spec succeeds during a retry, Ginkgo moves on and marks the suite as successful but reports that the spec needed to be retried.
  2373  
  2374  You can take a more granular approach by decorating individual subject nodes or container nodes as potentially flaky with the `FlakeAttempts(N)` decorator:
  2375  
  2376  ```go
  2377  Describe("Storing books", func() {
  2378    It("can save books to the central library", FlakeAttempts(3), func() {
  2379      // this spec has been marked as flaky and will be retried up to 3 times
  2380    })
  2381  
  2382    It("can save books locally", func() {
  2383      // this spec must always pass on the first try
  2384    })
  2385  })
  2386  ```
  2387  
  2388  Ginkgo's retry behavior generally works as you'd expect with most specs, however there is some complexity when `FlakeAttempts` is applied to `Ordered` containers.  In brief, Ginkgo generally guarantees that `BeforeAll` and `AfterAll` node closures only run once - but `FlakeAttempts` can modify this behavior.  If a failure occurs within a subject node in an `Ordered` container (i.e. in an `It`) then Ginkgo will rerun that `It` but not the `BeforeAll` or `AfterAll`.  However, if a failure occurs in a `BeforeAll` Ginkgo will immediately run the `AfterAll` (to clean up) then rerun the `BeforeAll`.
  2389  
  2390  Stepping back - it bears repeating: you should use `FlakeAttempts` judiciously.  The best approach to managing flaky spec suites is to debug flakes early and resolve them.  More often than not they are telling you something important about your architecture.  In a world of competing priorities and finite resources, however, `FlakeAttempts` provides a means to explicitly accept the technical debt of flaky specs and move on.
  2391  
  2392  ### Interrupting, Aborting, and Timing Out Suites
  2393  
  2394  We've talked a lot about running specs.  Let's take moment to talk about stopping them.
  2395  
  2396  Ginkgo provides a few mechanisms for stopping a suite before all specs have naturally completed.  These mechanisms are especially useful when a spec gets stuck and hangs.
  2397  
  2398  First, you can signal to a suite that it must stop running by sending a `SIGINT` or `SIGTERM` signal to the running spec process (or just hit `^C`).
  2399  
  2400  Second, you can also specify a timeout on a suite (or set of suites) via:
  2401  
  2402  ```bash
  2403  ginkgo --timeout=duration
  2404  ```
  2405  
  2406  where `duration` is a parseable go duration string (the default is `1h` -- one hour).  When running multiple suites Ginkgo will ensure that the total runtime of _all_ the suites does not exceed the specified timeout.
  2407  
  2408  Finally, you can abort a suite from within the suite by calling `Abort(<reason>)`.  This will immediately end the suite and is the programmatic equivalent of sending an interrupt signal to the test process.
  2409  
  2410  All three mechanisms have same effects.  They:
  2411  
  2412  - Immediately interrupt the current spec.
  2413  - Run any cleanup nodes (`AfterEach`, `JustAfterEach`, `AfterAll`, `DeferCleanup` code, etc.)
  2414  - Emit as much information about the interrupted spec as possible.  This includes:
  2415    - anything written to the `GinkgoWriter`
  2416    - the location of the node that was running at the time of interrupt.
  2417    - (for timeout and signal interrupts) a full dump of all running goroutines.
  2418  - Skip any subsequent specs.
  2419  - Run any `AfterSuite` closures.
  2420  - Exit, marking the suite as failed.
  2421  
  2422  In short, Ginkgo does its best to cleanup and emit as much information as possible about the suite before shutting down.  If, during cleanup, any cleanup node closures get stuck Ginkgo allows you to interrupt them via subsequent interrupt signals.  In the case of a timeout, Ginkgo sends these repeat interrupt signals itself to make sure the suite shuts down eventually.
  2423  
  2424  ### Running Multiple Suites
  2425  
  2426  So far we've covered writing and running specs in individual suites.  Of course, the `ginkgo` CLI also supports running multiple suites with a single invocation on the command line.  We'll close out this chapter on running specs by covering how Ginkgo runs multiple suites.
  2427  
  2428  When you run `ginkgo` the Ginkgo CLI first looks for a spec suite in the current directory.  If it finds one it runs `go test -c` to compile the suite and generate a `.test` binary.  It then invokes the binary directly, passing along any necessary flags to correctly configure it.  In the case of parallel specs, the CLI will configure and spin up multiple copies of the binary and act as a server to coordinate running specs in parallel.
  2429  
  2430  You can have `ginkgo` run multiple spec suites by pointing it at multiple package locations (i.e. directories) like so:
  2431  
  2432  ```bash
  2433  ginkgo <flags> path/to/package-1 path/to/package-2 ...
  2434  ```
  2435  
  2436  Ginkgo will enter each of these directory and look for a spec suite.  If it finds one it will compile the suite and run it.  Note that you need to include any `ginkgo` flags **before** the list of packages.
  2437  
  2438  You can also have `ginkgo` recursively find and run all spec suites within the current directory:
  2439  
  2440  ```bash
  2441  ginkgo -r
  2442  
  2443  - or, equivalently,
  2444  
  2445  ginkgo <flags> ./...
  2446  ```
  2447  
  2448  Now Ginkgo will walk the file tree and search for spec suites.  It will compile any it finds and run them.
  2449  
  2450  When there are multiple suites to run Ginkgo attempts to compile the suites in parallel but **always** runs them sequentially.  You can control the number of parallel compilation workers using the `ginkgo --compilers=N` flag, by default Ginkgo runs as many compilers as you have cores.
  2451  
  2452  Ginkgo provides a few additional configuration flags when running multiple suites.
  2453  
  2454  You can ask Ginkgo to skip certain packages via:
  2455  
  2456  ```bash
  2457  ginkgo -r --skip-package=list,of,packages
  2458  ```
  2459  
  2460  `--skip-package` takes a comma-separated list of package names.  If any part of the package's **path** matches one of the entries in this list that package is skipped: it is not compiled and it is not run.
  2461  
  2462  By default, Ginkgo runs suites in the order it finds them.  You can have Ginkgo randomize the order in which suites run withL
  2463  
  2464  ```bash
  2465  ginkgo -r --randomize-suites
  2466  ```
  2467  
  2468  Finally, Ginkgo's default behavior when running multiple suites is to stop execution after the first suite that fails.  (Note that Ginkgo will run _all_ the specs in that suite unless `--fail-fast` is specified.)  You can alter this behavior and have Ginkgo run _all_ suites regardless of failure with:
  2469  
  2470  ```bash
  2471  ginkgo -r --keep-going
  2472  ```
  2473  
  2474  As you can see, Ginkgo provides several CLI flags for controlling how specs are run.  Be sure to check out the [Recommended Continuous Integration Configuration](#recommended-continuous-integration-configuration) section of the patterns chapter for pointers on which flags are best used in CI environments.
  2475  
  2476  ## Reporting and Profiling Suites
  2477  The previous two chapters covered how Ginkgo specs are written and how Ginkgo specs run.  This chapter is all about output.  We'll cover how Ginkgo reports on spec suites and how Ginkgo can help you profile your spec suites.
  2478  
  2479  ### Controlling Ginkgo's Output
  2480  Ginkgo emits a real-time report of the progress of your spec suite to the console while running your specs.  A green dot is emitted for each successful spec and a red `F`, along with failure information, is emitted for each unsuccessful spec.
  2481  
  2482  There are several CLI flags that allow you to tweak this output:
  2483  
  2484  #### Controlling Verbosity
  2485  Ginkgo has four verbosity settings: succinct (the default when running multiple suites), normal (the default when running a single suite), verbose, and very-verbose.
  2486  
  2487  You can opt into succinct mode with `ginkgo --succinct`, verbose mode with `ginkgo -v` and very-verbose mode with `ginkgo -vv`.
  2488  
  2489  These settings control the amount of information emitted with each spec.  By default (i.e. succinct and normal) Ginkgo only emits detailed information about specs that fail.  That includes the location of the spec/failure and any captured `GinkgoWriter` content.
  2490  
  2491  The two verbose settings are most helpful when debugging spec suites.  They make Ginkgo emit detailed information for _every_ spec regardless of failure or success.  This includes anything written to the `GinkgoWriter` and the source code location of each spec.  When running in series in verbose or very-verbose mode Ginkgo will always immediately stream out this information in real-time while specs are running. A real-time stream isn't possible when running in parallel (the [streams would be interleaved](https://www.youtube.com/watch?v=jyaLZHiJJnE)); instead Ginkgo emits all this information about each spec right after it completes.
  2492  
  2493  When you [filter specs](#filtering-specs) using Ginkgo's various filtering mechanism Ginkgo usually emits a single cyan `S` for each skipped spec (the only exception is specs skipped with `Skip(<message>)` - Ginkgo emits the message for those specs.  You can circumvent this with `Skip("")`).  If you run with the very-verbose setting, however, Ginkgo will emit the description and location information of every skipped spec.  This can be useful if you need to debug your filter queries and can be paired with `--dry-run`.
  2494  
  2495  There are a couple more flags that are verbosity-related but can be controlled independently from the verbosity mode:
  2496  
  2497  First, you can tell Ginkgo to always emit the `GinkgoWriter` output of every spec with `--always-emit-ginkgo-writer`.  This will emit `GinkgoWriter` output for both failed _and_ passing specs, regardless of verbosity setting.
  2498  
  2499  Second, you can tell Ginkgo to emit progress of a spec as Ginkgo runs each of its node closures.  You do this with `ginkgo --progress -v` (or `-vv`).  `--progress` will emit a message to the `GinkgoWriter` just before a node starts running.  By running with `-v` or `-vv` you can then stream the output to the `GinkgoWriter` immediately.  `--progress` was initially introduced to help debug specs that are stuck/hanging.  It is not longer necessary as Ginkgo's behavior during an interrupt has matured and now generally has enough information to help you identify where a spec is stuck.
  2500  
  2501  #### Other Settings
  2502  Here are a grab bag of other settings:
  2503  
  2504  You can disable Ginkgo's color output by running `ginkgo --no-color`.
  2505  
  2506  By default, Ginkgo calls out specs that are running slowly if they exceed a certain threshold (default: 5 seconds).  This doesn't affect the status of the spec - it is still considered to have passed - but can give you an early warning that a slow spec has been introduced.  You can adjust this threshold with `ginkgo --slow-spec-threshold=<duration>`.
  2507  
  2508  By default, Ginkgo only emits full stack traces when a spec panics.  When a normal assertion failure occurs, Ginkgo simply emits the line at which the failure occurred.  You can, instead, have Ginkgo always emit the full stack trace by running `ginkgo --trace`.
  2509  
  2510  ### Reporting Infrastructure
  2511  Ginkgo's console output is great when running specs on the console or quickly grokking a CI run.  Of course, there are several contexts where generating a machine-readable report is crucial.  Ginkgo provides first-class CLI support for generating and aggregating reports in a number of machine-readable formats _and_ an extensible reporting infrastructure to enable additional formats and custom reporting.  We'll dig into these topics in the next few sections.
  2512  
  2513  ### Generating machine-readable reports
  2514  Ginkgo natively supports generating and aggregating reports in a number of machine-readable formats - and these reports can be generated and managed by simply passing `ginkgo` command line flags.
  2515  
  2516  A JSON-formatted report that faithfully captures all available information about a Ginkgo spec run can be generated via:
  2517  
  2518  ```bash
  2519  ginkgo --json-report=report.json
  2520  ```
  2521  
  2522  The resulting JSON file encodes an array of `types.Report`.  Each entry in that array lists detailed information about an individual spec suite and includes a list of `types.SpecReport` that captures detailed information about each spec.  These types are documented in [godoc](https://pkg.go.dev/github.com/onsi/ginkgo/types).
  2523  
  2524  When possible, we recommend building tooling on top of Ginkgo's JSON format and using Ginkgo's `types` package directly to access the suite and spec reports.  The structs in the package include several helper functions to interpret the report.
  2525  
  2526  Ginkgo also supports generating JUnit reports with 
  2527  
  2528  ```bash
  2529  ginkgo --junit-report=report.xml
  2530  ```
  2531  
  2532  The JUnit report is compatible with the JUnit specification, however Ginkgo specs carry much more metadata than can be easily mapped onto the JUnit spec so some information is lost and/or a bit harder to decode than using Ginkgo's native JSON format.
  2533  
  2534  Ginkgo also supports Teamcity reports with `ginkgo --teamcity-report=report.teamcity` though, again, the Teamcity spec makes it difficult to capture all the spec metadata.
  2535  
  2536  Of course, you can generate multiple formats simultaneously by passing in multiple flags:
  2537  
  2538  ```bash
  2539  ginkgo --json-report=report.json --junit-report=report.xml
  2540  ```
  2541  
  2542  By default, when any of these command-line report flags are provided Ginkgo will generate a single report file, per format, at the passed-in file name.  If Ginkgo is running multiple suites (e.g. `ginkgo -r --json-report=report.json`) then _all_ the suite reports will be encoded in the single report file.
  2543  
  2544  If you'd rather generate separate reports for each suite, you can pass in the `--keep-separate-reports` flag like so: `ginkgo -r --json-report=report.json --keep-separate-reports`.  This will generate an individual report named `report.json` in each suite/package directory,
  2545  
  2546  If you'd like to have all reports end up in a single directory.  Set `--output-dir=<dir>`:
  2547  
  2548  When generating combined reports with: `ginkgo -r --json-report=report.json --output-dir=<dir>` Ginkgo will create the `<dir>` directory (if necessary), and place `report.json` there.
  2549  
  2550  When generating separate reports with: `ginkgo -r --json-report=report.json --output-dir=<dir> --keep-separate-reports` Ginkgo will create the `<dir>` directory (if necessary), and place a report file per package in the directory.  These reports will be namespaced with the name of the package: `PACKAGE_NAME_report.json`.
  2551  
  2552  ### Generating reports programmatically
  2553  The JSON and JUnit reports described above can be easily generated from the command line - there's no need to make any changes to your suite.
  2554  
  2555  Ginkgo's reporting infrastructure does, however, provide several mechanisms for writing custom reporting code in your spec suites (or, in a supporting package).  We'll explore these mechanisms next.
  2556  
  2557  #### Getting a report for the current spec
  2558  
  2559  At any point during the Run Phase you can get an information-rich up-to-date copy of the current spec's report by running `CurrentSpecReport()`.
  2560  
  2561  There are several uses for this data.  For example, you can write code that performs additional, potentially expensive, diagnostics after a spec runs - but only if the spec has failed:
  2562  
  2563  ```go
  2564  Describe("Manipulating books at the central library", func() {
  2565    It("can fetch all books", func() {
  2566      Expect(libraryClient.FetchBooks()).NotTo(BeEmpty())
  2567    })
  2568  
  2569    It("can fetch a specific book", func() {
  2570      book, err := libraryClient.FetchBook("Les Miserables")
  2571      Expect(err).NotTo(HaveOccurred())
  2572      Expect(book.AuthorLastName()).To(Equal("Hugo"))    
  2573    })
  2574  
  2575    It("can update a book", func() {
  2576      book, err := libraryClient.FetchBook("Les Miserables")
  2577      Expect(err).NotTo(HaveOccurred())
  2578      book.Author = "Victor Marie Hugo"
  2579      Expect(libraryClient.SaveBook(book)).To(Succeed())
  2580    })
  2581  
  2582    AfterEach(func() {
  2583      if CurrentSpecReport().Failed() {
  2584        GinkgoWriter.Println(libraryClient.DebugLogs())
  2585      }
  2586    })
  2587  })
  2588  ```
  2589  
  2590  In this example, the `AfterEach` closure is using `CurrentSpecReport()` to discover whether or not the current spec has failed.  If it has debug information is fetched from the library server and emitted to the `GinkgoWriter`.
  2591  
  2592  Given `CurrentSpecReport()` you can imagine generating custom report information with something like a top-level `AfterEach`.  For example, let's say we want to write report information to a local file using a custom format _and_ send updates to a remote server.  You might try something like:
  2593  
  2594  ```go
  2595  /* === INVALID === */
  2596  var report *os.File
  2597  BeforeSuite(func() {
  2598    report = os.Create("report.custom")
  2599    DeferCleanup(report.Close)
  2600  })
  2601  
  2602  AfterEach(func() {
  2603    report := CurrentSpecReport()
  2604    customFormat := fmt.Sprintf("%s | %s", report.State, report.FullText())
  2605    fmt.Fprintln(report, customFormat)
  2606    client.SendReport(customFormat)
  2607  })
  2608  ```
  2609  
  2610  At first glance it looks like this could work.  However, there are a number of problems with this approach:
  2611  
  2612  First of all, the `AfterEach` will _only_ be called if the spec in question runs.  It will never be called for skipped or pending specs and we'll miss reporting on those specs!
  2613  
  2614  Second, the approach we're taking to generate a custom report file will work when running in serial, but not in parallel.  In parallel, multiple test processes will race over writing to `report.custom` and you'll end up with a mess.
  2615  
  2616  Ginkgo's reporting infrastructure provides an alternative solution for this use case.  A special category of setup nodes called **Reporting Nodes**.
  2617  
  2618  #### Reporting Nodes - ReportAfterEach and ReportBeforeEach
  2619  
  2620  Ginkgo provides three reporting-focused nodes `ReportAfterEach`, `ReportAfterSuite`, and `ReportBeforeEach`.
  2621  
  2622  `ReportAfterEach` behaves similarly to a standard `AfterEach` node and can be declared anywhere an `AfterEach` node can be declared.  `ReportAfterEach` takes a closure that accepts a single [`SpecReport`](https://pkg.go.dev/github.com/onsi/ginkgo/types#SpecReport) argument.  For example, we could implement a top-level ReportAfterEach that emits information about every spec to a remote server:
  2623  
  2624  ```go
  2625  ReportAfterEach(func(report SpecReport) {
  2626    customFormat := fmt.Sprintf("%s | %s", report.State, report.FullText())
  2627    client.SendReport(customFormat)
  2628  })
  2629  ```
  2630  
  2631  `ReportAfterEach` has several unique properties that distinguish it from `AfterEach`.  Most importantly, `ReportAfterEach` closures are **always** called - even if the spec has failed, is marked pending, or is skipped.  This ensures reports that rely on `ReportAfterEach` are complete.
  2632  
  2633  
  2634  In addition, `ReportAfterEach` closures are called after a spec completes.  i.e. _after_ all `AfterEach` closures have run.  This gives them access to the complete final state of the spec.  Note that if a failure occurs in a `ReportAfterEach` your the spec will be marked as failed.  Subsequent `ReportAfterEach` closures will see the failed state, but not the closure in which the failure occurred.
  2635  
  2636  Also, `ReportAfterEach` closures **cannot** be interrupted.  This is to ensure the integrity of generated reports - so be careful what kind of code you put in there.  If you're making network requests make sure to wrap them in a timeout!
  2637  
  2638  `ReportAfterEach` is useful if you need to stream or emit up-to-date information about the suite as it runs. Ginkgo also provides `ReportBeforeEach` which is called before the test runs and receives a preliminary `types.SpecReport` - the state of this report will indicate whether the test will be skipped or is marked pending.
  2639  
  2640  You should be aware that when running in parallel, each parallel process will be running specs and their `ReportAfterEach`es.  This means that multiple `ReportAfterEach` blocks can be running concurrently on independent processes.  Given that, code like this won't work:
  2641  
  2642  ```go
  2643  /* === INVALID === */
  2644  var reportFile *os.File
  2645  BeforeSuite(func() {
  2646    reportFile = os.Open("report.custom")
  2647  })
  2648  
  2649  ReportAfterEach(func(report SpecReport) {
  2650    fmt.Fprintf(reportFile, "%s | %s\n", report.FullText(), report.State)
  2651  })
  2652  ```
  2653  
  2654  you'll end up with multiple processes writing to the same file and the output will be a mess.  There is a better approach for this usecase...
  2655  
  2656  #### Reporting Nodes - ReportAfterSuite
  2657  `ReportAfterSuite` nodes behave similarly to `AfterSuite` and can be placed at the top-level of your suite (typically in the suite bootstrap file).  `ReportAfterSuite` nodes take a closure that accepts a single [`Report`]((https://pkg.go.dev/github.com/onsi/ginkgo/types#Report)) argument:
  2658  
  2659  ```go
  2660  var _ = ReportAfterSuite(func(report Report) {
  2661    // process report
  2662  })
  2663  ```
  2664  
  2665  `Report` contains all available information about the suite, including individual `SpecReport` entries for each spec that ran in the suite, and the overall status of the suite (whether it passed or failed).
  2666  
  2667  The closure passed to `ReportAfterSuite` is called exactly once at the end of the suite after any `AfterSuite` nodes have run.  Just like `ReportAfterEach`, `ReportAfterSuite` nodes can't be interrupted by the user to ensure the integrity of the generated report - so you'll want to make sure the code you put in there doesn't have a chance of hanging/getting stuck.
  2668  
  2669  Finally, and most importantly, when running in parallel `ReportAfterSuite` **only runs on process #1** and receives a `Report` that aggregates the `SpecReports` from all processes.  This allows you to perform any custom suite reporting in one place after all specs have run and not have to worry about aggregating information across multiple parallel processes.
  2670  
  2671  So, we can rewrite our invalid `ReportAfterEach` example from above into a valid `ReportAfterSuite` example:
  2672  
  2673  ```go
  2674  ReportAfterSuite(func(report Report) {
  2675    f := os.Open("report.custom")
  2676    for _, specReport := range report.SpecReports {
  2677      fmt.Fprintf(f, "%s | %s\n", report.FullText(), report.State)
  2678    }
  2679    f.Close()
  2680  })
  2681  ```
  2682  
  2683  Now each suite will generate exactly one report with all the specs appropriately formatted whether running in series or in parallel.
  2684  
  2685  ### Attaching Data to Reports
  2686  Ginkgo supports attaching arbitrary data to individual spec reports.  These are called `ReportEntries` and appear in the various report-related data structures (e.g. `Report` in `ReportAfterSuite` and `SpecReport` in `ReportAfterEach`) as well as the machine-readable reports generated by `--json-report`, `--junit-report`, etc.  `ReportEntries` are also emitted to the console by Ginkgo's reporter and you can specify a visibility policy to control when this output is displayed.
  2687  
  2688  You attach data to a spec report via
  2689  
  2690  ```go
  2691  AddReportEntry(name string, args ...interface{})
  2692  ```
  2693  
  2694  `AddReportEntry` can be called from any setup or subject node closure.  When called, `AddReportEntry` generates `ReportEntry` and attaches it to the current running spec.  `ReportEntry` includes the passed in `name` as well as the time and source location at which `AddReportEntry` was called.  Users can also attach a single object of arbitrary type to the `ReportEntry` by passing it into `AddReportEntry` - this object is wrapped and stored under `ReportEntry.Value` and is always included in the suite's JSON report.
  2695  
  2696  You can access the report entries attached to a spec by getting the `CurrentSpecReport()` or registering a `ReportAfterEach()` - the returned report will include the attached `ReportEntries`.  You can fetch the value associated with the `ReportEntry` by calling `entry.GetRawValue()`.  When called in-process this returns the object that was passed to `AddReportEntry`.  When called after hydrating a report from JSON `entry.GetRawValue()` will include a parsed JSON `interface{}` - if you want to hydrate the JSON yourself into an object of known type you can `json.Unmarshal([]byte(entry.Value.AsJSON), &object)`.
  2697  
  2698  #### Supported Args
  2699  `AddReportEntry` supports the `Offset` and `CodeLocation` decorators.  These will control the source code location associated with the generated `ReportEntry`.  You can also pass in a `time.Time` argument to override the timestamp associated with the `ReportEntry` - this can be helpful if you want to ensure a consistent timestamp between your code and the `ReportEntry`.
  2700  
  2701  You can also pass in a `ReportEntryVisibility` enum to control the report's visibility.  This is discussed in more detail below.
  2702  
  2703  If you pass multiple arguments of the same type (e.g. two `Offset`s), the last argument in wins.  This does mean you cannot attach an object with one of the types discussed in this section as the `ReportEntry.Value`.  To get by this you'll need to define a custom type.  For example, if you want the `Value` to be a `time.Time` timestamp you can use a custom type such as
  2704  
  2705  `type Timestamp time.Time`
  2706  
  2707  #### Controlling Output
  2708  By default, Ginkgo's console reporter will emit any `ReportEntry` attached to a spec.  It will emit the `ReportEntry` name, location, and time.  If the `ReportEntry` value is non-nil it will also emit a representation of the value.  If the value implements `fmt.Stringer` or `types.ColorableStringer` then `value.String()` or `value.ColorableString()` (which takes precedence) is used to generate the representation, otherwise Ginkgo uses `fmt.Sprintf("%#v", value)`. 
  2709  
  2710  You can modify this default behavior by passing in one of the `ReportEntryVisibility` enum to `AddReportEntry`:
  2711  
  2712  - `ReportEntryVisibilityAlways`: the default behavior - the `ReportEntry` is always emitted.
  2713  - `ReportEntryVisibilityFailureOrVerbose`: the `ReportEntry` is only emitted if the spec fails or the tests are run with `-v` (similar to `GinkgoWriter`s behavior).
  2714  - `ReportEntryVisibilityNever`: the `ReportEntry` is never emitted though it appears in any generated machine-readable reports (e.g. by setting `--json-report`).
  2715  
  2716  The console reporter passes the string representation of the `ReportEntry.Value` through Ginkgo's `formatter`.  This allows you to generate colorful console output using the color codes documented in `github.com/onsi/ginkgo/formatter/formatter.go`.  For example:
  2717  
  2718  ```go
  2719  type StringerStruct struct {
  2720    Label string
  2721    Count int
  2722  }
  2723  
  2724  // ColorableString for ReportEntry to use
  2725  func (s StringerStruct) ColorableString() string {
  2726    return fmt.Sprintf("{{red}}%s {{yellow}}{{bold}}%d{{/}}", s.Label, s.Count)
  2727  }
  2728  
  2729  // non-colorable String() is used by go's string formatting support but ignored by ReportEntry
  2730  func (s StringerStruct) String() string {
  2731    return fmt.Sprintf("%s %d", s.Label, s.Count)
  2732  }
  2733  
  2734  
  2735  It("is reported", func() {
  2736    AddReportEntry("Report", StringerStruct{Label: "Mahomes", Count: 15})
  2737  })
  2738  ```
  2739  
  2740  Will emit a report that has the word "Mahomes" in red and the number 15 in bold and yellow.
  2741  
  2742  Lastly, it is possible to pass a pointer into `AddReportEntry`.  Ginkgo will compute the string representation of the passed in pointer at the last possible moment - so any changes to the object _after_ it is reported will be captured in the final report.  This is useful for building libraries on top of `AddReportEntry` - users can simply register objects when they're created and any subsequent mutations will appear in the generated report.  You can see an example of this in the [Benchmarking Code](#benchmarking-code) pattern section of the patterns chapter.
  2743  
  2744  ### Profiling your Suites
  2745  Go supports a rich set of profiling features to gather information about your running test suite.  Ginkgo exposes all of these and manages them for you when you are running multiple suites and/or parallel suites.
  2746  
  2747  Ginkgo supports `--race` to analyze race conditions, `--cover` to compute code coverage, `--vet` to evaluate and vet your code, `--cpuprofile` to profile CPU performance, `--memprofile` to profile memory usage, `--blockprofile` to profile blocking goroutines, and `--mutexprofile` to profile locking around mutexes.
  2748  
  2749  `ginkgo -race` runs the race detector and emits any detected race conditions as the suite runs.  If any are detected the suite is marked as failed.
  2750  
  2751  `ginkgo -vet` allows you to configure the set of checks that are applied when your code is compiled.  `ginkgo` defaults to the set of default checks that `go test` uses and you can specify additional checks by passing a comma-separated list to `--vet`.  The set of available checks can be found by running `go doc cmd/vet`.
  2752  
  2753  #### Computing Coverage
  2754  `ginkgo -cover` will compute and emit code coverage.  When running multiple suites Ginkgo will emit coverage for each suite and then emit a composite coverage across all running suites.  As with `go test` the default behavior for a given suite is to measure the coverage it provides for the code in the suite's package - however you can extend coverage to additional packages using `--coverpkg`.  You can also specify the `--covermode` to be one of `set` ("was this code called at all?"), `count` (how many times was it called?) and `atomic` (same as count, but threadsafe and expensive).  If you run `ginkgo --race --cover` the `--covermode` is automatically set to `atomic`.
  2755  
  2756  When run with `--cover`, Ginkgo will generate a single `coverprofile.out` file that captures the coverage statistics of all the suites that ran.  You can change the name of this file by specifying `-coverprofile=filename`.  If you would like to keep separate coverprofiles for each suite use the `--keep-separate-coverprofiles` option.
  2757  
  2758  Ginkgo also honors the `--output-dir` flag when generating coverprofiles.  If you specify `--output-dir` the generated coverprofile will be placed in the requested directory.  If you also specify `--keep-separate-coverprofiles` individual package coverprofiles will be placed in the requested directory and namespaced with a prefix that contains the name of the package in question.
  2759  
  2760  #### Other Profiles
  2761  Running `ginkgo` with any of `--cpuprofile=X`, `--memprofile=X`, `--blockprofile=X`, and `--mutexprofile=X` will generate corresponding profile files for suite that runs.  Doing so will also preserve the test binary generated by Ginkgo to enable users to use `go tool pprof <BINARY> <PROFILE>` to analyze the profile.
  2762  
  2763  By default, the test binary and various profile files are stored in the individual directories of any suites that Ginkgo runs.  If you specify `--output-dir`, however, then these assets are moved to the requested directory and namespaced with a prefix that contains the name of the package in question.
  2764  
  2765  ## Ginkgo and Gomega Patterns
  2766  So far we've introduced and described the majority of Ginkgo's capabilities and building blocks.  Hopefully the previous chapters have helped give you a mental model for how Ginkgo specs are written and run.
  2767  
  2768  In this chapter we'll switch gears and illustrate common patterns for how Ginkgo's building blocks can be put together to solve for real-world problems.  Since Ginkgo and Gomega are so often paired this chapter will assume that you are using both together - as you'll see, the combination can unlock some powerful, and expressive, testing patterns.
  2769  
  2770  ### Recommended Continuous Integration Configuration
  2771  
  2772  The `ginkgo` CLI supports a number of flags to control how your suites are run.  We recommend the following set of flags when running in a continuous integration environment:
  2773  
  2774  ```bash
  2775  ginkgo -r --procs=N --compilers=N --randomize-all --randomize-suites --fail-on-pending --keep-going --cover --coverprofile=cover.profile --race --trace --json-report=report.json --timeout=TIMEOUT
  2776  ```
  2777  
  2778  Here's why:
  2779  
  2780  - `-r` will recursively find and run all suites in the current directory.
  2781  - `-procs=N` will run each suite in parallel.  This can substantially speed up suites and you should experiment with different values of `N`.  Note that it is not recommended that you run specs in parallel with `-p` on CI.  Some CI services run on shared machines that will report (e.g.) `32` cores but will not actually give an individual account access to all those compute resources!
  2782  - `--compilers=N` will control how many cores to use to compile suites in parallel.  You may need to set this explicitly to avoid accidentally trying to use all `32` cores on that CI machine!
  2783  - `--randomize-all` and `--randomize-suites` will randomize all specs and randomize the order in which suites run.  This will help you suss out spec pollution early!
  2784  - `--keep-going` will instruct Ginkgo to keep running suites, even after a suite fails.  This can help you get a set of all failures instead of stopping after the first failed suite.
  2785  - `--cover` and `--coverprofile=cover.profile` will compute coverage scores and generate a single coverage file for all your specs.
  2786  - `--race` will run the race detector.
  2787  - `--trace` will instruct Ginkgo to generate a stack trace for all failures (instead of simply including the location where the failure occurred).  This isn't usually necessary but can be helpful in CI environments where you may not have access to a fast feedback loop to iterate on and debug code.
  2788  - `--json-report=report.json` will generate a JSON formatted report file.  You can store these off and use them later to get structured access to the suite and spec results.
  2789  - `--timeout` allows you to specify a timeout for the `ginkgo` run.  The default duration is one hour, which may or may not be enough!
  2790  
  2791  ### Supporting Custom Suite Configuration
  2792  
  2793  There are contexts where you may want to change some aspects of a suite's behavior based on user-provided configuration.  There are two widely adopted means of doing this: environment variables and command-line flags.
  2794  
  2795  We'll explore both these options in this section by building out a concrete usecase.  Let's imagine a suite that is intended to ensure that a service is up and running correctly (these are sometimes referred to as smoketest suites).  We want to be able to point our suite at an arbitrary server address/port.  We also want to configure how our suite runs depending on the environment we're smoketesting - we'll want to be minimally invasive for `PRODUCTION` environments, but can perform a more thorough check for `STAGING` environments.
  2796  
  2797  Here's a sketch of what this might look like.
  2798  
  2799  #### Supporting Custom Suite Configuration: Environment Variables
  2800  Setting and parsing environment variables is fairly straightforward.  We'll configure the server address with a `SMOKETEST_SERVER_ADDR` environment variable and we'll configure the environment with a `SMOKETEST_ENV` variable.
  2801  
  2802  Our suite might look like:
  2803  
  2804  ```go
  2805  // This is the testing hook in our bootstrap file
  2806  func TestSmokeTest(t *testing.T) {
  2807    RegisterFailHandler(Fail)
  2808    RunSpecs(t, "Smoketest Suite")
  2809  }
  2810  
  2811  var client *client.Client
  2812  var _ = BeforeSuite(func() {
  2813    // Some basic validations
  2814    Expect(os.Getenv("SMOKETEST_SERVER_ADDR")).NotTo(BeZero(), "Please make sure SMOKETEST_SERVER_ADDR is set correctly.")
  2815    Expect(os.Getenv("SMOKETEST_ENV")).To(Or(Equal("PRODUCTION"), Equal("STAGING")), "SMOKETEST_ENV must be set to PRODUCTION or STAGING.")
  2816  
  2817    //set up a client 
  2818    client = client.NewClient(os.Getenv("SMOKETEST_SERVER_ADDR"))
  2819  })
  2820  
  2821  var _ = Describe("Smoketests", func() {
  2822    Describe("Minimally-invasive", func() {
  2823      It("can connect to the server", func() {
  2824        Eventually(client.Connect).Should(Succeed())
  2825      })
  2826  
  2827      It("can get a list of books", func() {
  2828        Expect(client.ListBooks()).NotTo(BeEmpty())
  2829      })
  2830    })
  2831  
  2832    if os.Getenv("SMOKETEST_ENV") == "STAGING" {
  2833      Describe("Ensure basic CRUD operations", func() {
  2834        It("can create, updated, and delete a book", func() {
  2835          book := &books.Book{
  2836            Title: "This Book is a Test",
  2837            Author: "Ginkgo",
  2838            Pages: 17,
  2839          }
  2840          Expect(client.Store(book)).To(Succeed())
  2841          Expect(client.FetchByTitle("This Book is a Test")).To(Equal(book))
  2842          Expect(client.Delete(book)).To(Succeed())
  2843          Expect(client.FetchByTitle("This Book is a Test")).To(BeNil())
  2844        })
  2845      })
  2846    }
  2847  })
  2848  ```
  2849  
  2850  users could then run:
  2851  
  2852  ```bash
  2853  SMOKETEST_SERVER_ADDR="127.0.0.1:3000" SMOKETEST_ENV="STAGING" ginkgo
  2854  ```
  2855  
  2856  to run all three specs against a local server listening on port `3000`.  If the user fails to correctly provide the configuration environment variables, the `BeforeSuite` checks will fail and `Gomega` will emit the description strings (e.g. "Please make sure SMOKETEST_SERVER_ADDR is set correctly.") to help the user know what they missed.
  2857  
  2858  As you can see, environment variables are convenient and easily accessible from anywhere in the suite.  We use them during the Run Phase to configure the client.  But we also use them at the Tree Construction Phase to control which specs are included in the suite.  There are some clearer ways to accomplish the latter so keep reading!
  2859  
  2860  #### Supporting Custom Configuration: Custom Command-Line Flags
  2861  An alternative to environment variables is to provide custom command-line flags to the suite.  These take a bit more setting up but have the benefit of being a bit more self-documenting and structured.
  2862  
  2863  The tricky bits here are:
  2864  
  2865  1. Injecting your command line flags into Go's `flags` list before the test process parses flags.
  2866  2. Understanding when in the spec lifecycle the parsed flags are available.
  2867  3. Remembering to pass the flags in correctly.
  2868  
  2869  Here's a fleshed out example:
  2870  
  2871  ```go
  2872  var serverAddr, smokeEnv string
  2873  
  2874  // Register your flags in an init function.  This ensures they are registered _before_ `go test` calls flag.Parse().
  2875  func init() {
  2876    flag.StringVar(&serverAddr, "server-addr", "", "Address of the server to smoke-check")
  2877    flag.StringVar(&smokeEnv, "environment", "", "Environment to smoke-check")
  2878  }
  2879  
  2880  // This is the testing hook in our bootstrap file
  2881  func TestSmokeTest(t *testing.T) {
  2882    RegisterFailHandler(Fail)
  2883    RunSpecs(t, "Smoketest Suite")
  2884  }
  2885  
  2886  var client *client.Client
  2887  var _ = BeforeSuite(func() {
  2888    // Some basic validations - at this point the flags have been parsed so we can access them
  2889    Expect(serverAddr).NotTo(BeZero(), "Please make sure --server-addr is set correctly.")
  2890    Expect(smokeEnv).To(Or(Equal("PRODUCTION"), Equal("STAGING")), "--environment must be set to PRODUCTION or STAGING.")
  2891  
  2892    //set up a client 
  2893    client = client.NewClient(serverAddr)
  2894  })
  2895  
  2896  var _ = Describe("Smoketests", func() {
  2897    Describe("Minimally-invasive", func() {
  2898      It("can connect to the server", func() {
  2899        Eventually(client.Connect).Should(Succeed())
  2900      })
  2901  
  2902      It("can get a list of books", func() {
  2903        Expect(client.ListBooks()).NotTo(BeEmpty())
  2904      })
  2905    })
  2906  
  2907    if smokeEnv == "STAGING" {
  2908      Describe("Ensure basic CRUD operations", func() {
  2909        It("can create, updated, and delete a book", func() {
  2910          book := &books.Book{
  2911            Title: "This Book is a Test",
  2912            Author: "Ginkgo",
  2913            Pages: 17,
  2914          }
  2915          Expect(client.Store(book)).To(Succeed())
  2916          Expect(client.FetchByTitle("This Book is a Test")).To(Equal(book))
  2917          Expect(client.Delete(book)).To(Succeed())
  2918          Expect(client.FetchByTitle("This Book is a Test")).To(BeNil())
  2919        })
  2920      })
  2921    }
  2922  })
  2923  ```
  2924  
  2925  We would invoke this suite with
  2926  
  2927  ```bash
  2928  ginkgo -- --server-addr="127.0.0.1:3000" --environment="STAGING"
  2929  ```
  2930  
  2931  note the `--` separating the arguments `ginkgo` from the arguments passed down to the suite.  You would put Ginkgo's arguments to the left of `--`.  For example, to run in parallel:
  2932  
  2933  ```bash
  2934  ginkgo -p -- --server-addr="127.0.0.1:3000" --environment="STAGING"
  2935  ```
  2936  
  2937  One more note before we move on.  As shown in this example, parsed flag variables are available both during the Run Phase (e.g. when we call `client.NewClient(serverAddr)`) _and_ during the Tree Construction Phase (e.g. when we guard the `CRUD` specs with `if smokeEnv == "STAGING"`).  However flag variables are _not_ available at the **top-level** of the suite.
  2938  
  2939  Here's a trivial, but instructive, example.  Say we wanted to add the value of `environment` to the name the top-level `Describe`:
  2940  
  2941  ```go
  2942  ...
  2943  
  2944  var describeName = fmt.Sprintf("Smoketests - %s", smokeEnv)
  2945  var _ = Describe(describeName, func() {
  2946    ...
  2947  })
  2948  
  2949  ...
  2950  ```
  2951  
  2952  Counterintuitively, this will always yield `"Smoketests - "`.  The reason is that `fmt.Sprintf` is being called as go is traversing the top-level identifiers in the suite.  At this point, `init` functions are being _defined_ but have not yet been invoked.  So (a) we haven't actually registered our flags yet and, more importantly, (b) `go test` hasn't _parsed_ the flags yet.  Our `smokeEnv` variable is therefore empty.  There's no way around this - in general you should avoid trying to access configuration information at the top-level.  However, if you must then you will need to use use environment variables instead of flags.
  2953  
  2954  #### Overriding Ginkgo's command-line configuration in the suite
  2955  
  2956  The previous two examples used an `if` guard to control whether specs were included in the spec tree based on user-provided configuration.  This approach _works_ but can be a bit confusing - specs that are "skipped" in this way never appear in any generated reports, and the total number of specs in the suite depends on configuration.  It would be cleaner and clearer to leverage Ginkgo's filtering mechanisms.  You could, for example, use `Skip`:
  2957  
  2958  ```go
  2959  var _ = Describe("Smoketests", func() {
  2960    Describe("Minimally-invasive", func() {
  2961      It("can connect to the server", func() {
  2962        ...
  2963      })
  2964  
  2965      It("can get a list of books", func() {
  2966        ...
  2967      })
  2968    })
  2969  
  2970    Describe("Ensure basic CRUD operations", func() {
  2971      BeforeEach(func(){
  2972        if environment != "STAGING" {
  2973          Skip("CRUD spec only runs on staging")
  2974        }
  2975      })
  2976  
  2977      It("can create, updated, and delete a book", func() {
  2978        ...
  2979      })
  2980    })
  2981  })
  2982  ```
  2983  
  2984  this works just fine - however as the suite grows you may see that `environment` check start to spread throughout the suite.  You could, instead, use Ginkgo's label mechanisms.  Here we're explicitly labeling specs with their allowed environments:
  2985  
  2986  ```go
  2987  var _ = Describe("Smoketests", func() {
  2988    Describe("Minimally-invasive", Label("PRODUCTION", "STAGING")func() {
  2989      It("can connect to the server", func() {
  2990        ...
  2991      })
  2992  
  2993      It("can get a list of books", func() {
  2994        ...
  2995      })
  2996    })
  2997  
  2998    Describe("Ensure basic CRUD operations", Label("STAGING"), func() {
  2999      It("can create, updated, and delete a book", func() {
  3000        ...
  3001      })
  3002    })
  3003  })
  3004  ```
  3005  
  3006  We could then use Ginkgo's expressive filter queries to control which specs do/don't run.  However that would require us to change our contract with the user.  They'll now need to run:
  3007  
  3008  ```bash
  3009  ginkgo --label-filter="STAGING" -- --server-addr="127.0.0.1"
  3010  ```
  3011  
  3012  this isn't great.  Ideally we'd maintain the same contract and allow the user to express their intent through the existing semantics of "environment" and take care of managing the label-filter in the suite.
  3013  
  3014  You can accomplish this in Ginkgo by overriding Ginkgo's configuration _before_ running the specs.  Here's our fully-worked example showing how:
  3015  
  3016  ```go
  3017  var serverAddr, smokeEnv string
  3018  
  3019  // Register your flags in an init function.  This ensures they are registered _before_ `go test` calls flag.Parse().
  3020  func init() {
  3021    flag.StringVar(&serverAddr, "server-addr", "", "Address of the server to smoke-check")
  3022    flag.StringVar(&smokeEnv, "environment", "", "Environment to smoke-check")
  3023  }
  3024  
  3025  // This is the testing hook in our bootstrap file
  3026  func TestSmokeTest(t *testing.T) {
  3027    RegisterFailHandler(Fail)
  3028  
  3029    //we're moving the validation up here since we're about to use the flag variables before entering the RunPhase
  3030    //thankfully Gomega can run within normal `testing` tests, we simply create a new Gomega by wrapping `testing.T`
  3031    g := NewGomegaWithT(t)
  3032    g.Expect(serverAddr).NotTo(BeZero(), "Please make sure --server-addr is set correctly.")
  3033    g.Expect(smokeEnv).To(Or(Equal("PRODUCTION"), Equal("STAGING")), "--environment must be set to PRODUCTION or STAGING.")
  3034  
  3035    //we're now guaranteed to have validated configuration variables
  3036    //let's update Ginkgo's configuration using them
  3037    //first we grab Ginkgo's current configuration
  3038    suiteConfig, _ := GinkgoConfiguration() //the second argument is the reporter configuration which we won't be adjusting
  3039  
  3040    //now we modify the label-filter
  3041    if suiteConfig.LabelFilter == "" {
  3042      suiteConfig.LabelFilter = smokeEnv
  3043    }  else {
  3044      // if the user has specified a label-filter we extend it:
  3045      suiteConfig.LabelFilter = "(" + suiteConfig.LabelFilter + ") && " + smokeEnv 
  3046    }
  3047  
  3048    // finally, we pass the modified configuration in to RunSpecs
  3049    RunSpecs(t, "Smoketest Suite", suiteConfig)
  3050  }
  3051  
  3052  var client *client.Client
  3053  var _ = BeforeSuite(func() {
  3054    client = client.NewClient(serverAddr)
  3055  })
  3056  
  3057  var _ = Describe("Smoketests", func() {
  3058    Describe("Minimally-invasive", Label("PRODUCTION", "STAGING"), func() {
  3059      It("can connect to the server", func() {
  3060        Eventually(client.Connect).Should(Succeed())
  3061      })
  3062  
  3063      It("can get a list of books", func() {
  3064        Expect(client.ListBooks()).NotTo(BeEmpty())
  3065      })
  3066    })
  3067  
  3068    Describe("Ensure basic CRUD operations", Label("STAGING"), func() {
  3069      It("can create, updated, and delete a book", func() {
  3070        book := &books.Book{
  3071          Title: "This Book is a Test",
  3072          Author: "Ginkgo",
  3073          Pages: 17,
  3074        }
  3075        Expect(client.Store(book)).To(Succeed())
  3076        Expect(client.FindByTitle("This Book is a Test")).To(Equal(book))
  3077        Expect(client.Delete(book)).To(Succeed())
  3078        Expect(client.FindByTitle("This Book is a Test")).To(BeNil())
  3079      })
  3080    })
  3081  })
  3082  ```
  3083  
  3084  In this way we can provide alternative, more semantically appropriate, interfaces to consumers of our suite and build on top of Ginkgo's existing building blocks.
  3085  
  3086  ### Dynamically Generating Specs
  3087  
  3088  There are several patterns for dynamically generating specs with Ginkgo.  You can use a simple loop to generate specs.  For example:
  3089  
  3090  ```go
  3091  Describe("Storing and retrieving books by category", func() {
  3092    for _, category := range []books.Category{books.CategoryNovel, books.CategoryShortStory, books.CategoryBiography} {
  3093      category := category
  3094      It(fmt.Sprintf("can store and retrieve %s books", category), func() {
  3095        book := &books.Book{
  3096          Title: "This Book is a Test",
  3097          Author: "Ginkgo",
  3098          Category: category,
  3099        }
  3100        Expect(library.Store(book)).To(Succeed())
  3101        DeferCleanup(library.Delete, book)
  3102        Expect(library.FindByCategory(category)).To(ContainElement(book))      
  3103      })
  3104    }
  3105  })
  3106  ```
  3107  
  3108  This will generate several `It`s - one for each category.  Note that you must assign a copy of the loop variable to a local variable (that's what `category := category` is doing) - otherwise the `It` closure will capture the mutating loop variable and all the specs will run against the last element in the loop.  It is idiomatic to give the local copy the same name as the loop variable.
  3109  
  3110  Of course, this particular example might be better written as a [table](#table-specs)!
  3111  
  3112  There are contexts where external information needs to be loaded in order to figure out which specs to dynamically generate.  For example, let's say we maintain a `json` file that lists a set of fixture books that we want to test storing/retrieving from the library.  There are many ways to approach writing such a test - but let's say we want to maximize parallelizability of our suite and so want to generate a separate `It` for each book fixture.
  3113  
  3114  Many Ginkgo users attempt the following approach.  It's a common gotcha:
  3115  
  3116  ```go
  3117  /* === INVALID === */
  3118  var fixtureBooks []*books.Book
  3119  
  3120  var _ = BeforeSuite(func() {
  3121    fixtureBooks = LoadFixturesFrom("./fixtures/books.json")
  3122    Expect(fixtureBooks).NotTo(BeEmpty())
  3123  })
  3124  
  3125  Describe("Storing and retrieving the book fixtures", func() {
  3126    for _, book := range fixtureBooks {
  3127      book := book
  3128      It(fmt.Sprintf("can store and retreive %s", book.Title), func() {
  3129        Expect(library.Store(book)).To(Succeed())
  3130        DeferCleanup(library.Delete, book)
  3131        Expect(library.FindByTitle(book.Title)).To(Equal(book))            
  3132      })
  3133    }
  3134  })
  3135  ```
  3136  
  3137  This will not work.  The fixtures are loaded in the `BeforeSuite` closure which runs during the **Run Phase**... _after_ the **Tree Construction Phase** where we loop over `fixtureBooks`.  If you need to perform work that influences the structure of the spec tree you must do it  _before_ or _during_ the Tree Construction Phase.  In this case, it is idiomatic to place the relevant code in the `Test` function in the bootstrap file:
  3138  
  3139  ```go
  3140  var fixtureBooks []*books.Book
  3141  
  3142  func TestBooks(t *testing.T) {
  3143    RegisterFailHandler(Fail)
  3144  
  3145    // perform work that needs to be done before the Tree Construction Phase here
  3146    // note that we wrap `t` with a new Gomega instance to make assertions about the fixtures here.
  3147    g := NewGomegaWithT(t)
  3148    fixtureBooks = LoadFixturesFrom("./fixtures/books.json")
  3149    g.Expect(fixtureBooks).NotTo(BeEmpty())
  3150  
  3151    // finally, we pass the modified configuration in to RunSpecs
  3152    RunSpecs(t, "Books Suite")
  3153  }
  3154  
  3155  Describe("Storing and retrieving the book fixtures", func() {
  3156    for _, book := range fixtureBooks {
  3157      book := book
  3158      It(fmt.Sprintf("can store and retrieve %s", book.Title), func() {
  3159        Expect(library.Store(book)).To(Succeed())
  3160        DeferCleanup(library.Delete, book)
  3161        Expect(library.FindByTitle(book.Title)).To(Equal(book))            
  3162      })
  3163    }
  3164  })
  3165  ```
  3166  
  3167  ### Shared Behaviors
  3168  It's common to want to extract subsets of spec behavior for reuse - these are typically called "Shared Behaviors".  
  3169  
  3170  It is often the case that within a particular suite there will be a number of different `Context`s that assert the exact same behavior, in that they have identical `It`s within them.  The only difference between these `Context`s is the set up done in their respective `BeforeEach`s.  Rather than repeat the `It`s for these `Context`s, you can extract the code into a shared-scope closure and avoid repeating yourself.  For example:
  3171  
  3172  ```go
  3173  Describe("Storing books in the library", func() {
  3174    var book *books.Book{}
  3175  
  3176    Describe("the happy path", func() {
  3177      BeforeEach(func() {
  3178        book = &books.Book{
  3179          Title:  "Les Miserables",
  3180          Author: "Victor Hugo",
  3181          Pages:  2783,
  3182        }
  3183      })
  3184  
  3185      It("validates that the book can be stored", func() {
  3186        Expect(library.IsStorable(book)).To(BeTrue())
  3187      })
  3188  
  3189      It("can store the book", func() {
  3190        Expect(library.Store(book)).To(Succeed())
  3191      })
  3192    })
  3193  
  3194    Describe("failure modes", func() {
  3195      AssertFailedBehavior := func() {
  3196        It("validates that the book can't be stored", func() {
  3197          Expect(library.IsStorable(book)).To(BeFalse())
  3198        })
  3199  
  3200        It("fails to store the book", func() {
  3201          Expect(library.Store(book)).To(MatchError(books.ErrStoringBook))
  3202        })
  3203      }
  3204  
  3205      Context("when the book has no title", func() {
  3206        BeforeEach(func() {
  3207          book = &books.Book{
  3208            Author: "Victor Hugo",
  3209            Pages:  2783,
  3210          }
  3211        })
  3212  
  3213        AssertFailedBehavior()
  3214      })
  3215  
  3216      Context("when the book has no author", func() {
  3217        BeforeEach(func() {
  3218          book = &books.Book{
  3219            Title: "Les Miserables",
  3220            Pages:  2783,
  3221          }
  3222        })
  3223  
  3224        AssertFailedBehavior()
  3225      })
  3226  
  3227      Context("when the book is nil", func() {
  3228        BeforeEach(func() {
  3229          book = nil
  3230        })
  3231  
  3232        AssertFailedBehavior()
  3233      })    
  3234    })
  3235  })
  3236  ```
  3237  
  3238  Since `AssertFailedBehavior` is defined in the same stack of closures as the other nodes, it has access to the shared `book` variable.  Note that the `AssertFailedBehavior` function is called within the body of the `Context` container block.  This will happen during The Tree Construction phase and result in a spec tree that includes the `It`s defined in the `AssertFailedBehavior` function for each context.  
  3239  
  3240  ### Table Specs Patterns
  3241  
  3242  We introduced Ginkgo's support for Table Specs in an [earlier section](#table-specs).  Here we'll just outline a couple of useful patterns.
  3243  
  3244  Tables specs allow you to specify a spec function that takes arbitrary parameters and entries to feed parameters to the function.  This works well when you've got a small handful of parameters but can become unwieldy with more parameters.  For example:
  3245  
  3246  ```go
  3247  var book *books.Book
  3248  BeforeEach(func() {
  3249    book = LoadFixture("les-miserables.json")
  3250  })
  3251  DescribeTable("Repaginating Books",
  3252    func(fontSize int, lineHeight float64, pageWidth float64, pageHeight float64, expectedPages int) {
  3253      book.SetFontSize(fontSize)
  3254      book.SetLineHeight(lineHeight)
  3255      book.SetPageDimensions(pageWidth, pageHeight)
  3256      Expect(book.RecomputePages()).To(BeNumerically("~", expectedPages, 30))
  3257    },
  3258    func(fontSize int, lineHeight float64, pageWidth float64, pageHeight float64, expectedPages int) string {
  3259      return fmt.Sprintf("FontSize: %d, LineHeight: %.2f, Page:%.2fx%.2f => %d", fontSize, lineHeight, pageWidth, pageHeight, expectedPages)
  3260    }
  3261    Entry(nil, 12, 1.2, 8.5, 11, 2783),
  3262    Entry(nil, 14, 1.3, 8.5, 11, 3120),
  3263    Entry(nil, 10, 1.2, 8.5, 11, 2100),
  3264    Entry(nil, 12, 2.0, 8.5, 11, 6135),
  3265    Entry(nil, 12, 1, 5, 6, 12321),
  3266  )
  3267  ```
  3268  
  3269  These entries are inscrutable!  A common pattern in this case is to define a type to capture the entry information:
  3270  
  3271  ```go
  3272  var book *books.Book
  3273  type BookFormatting struct {
  3274    FontSize int
  3275    LineHeight float64
  3276    PageWidth float64
  3277    PageHeight float64
  3278  }
  3279  
  3280  BeforeEach(func() {
  3281    book = LoadFixture("les-miserables.json")
  3282  })
  3283  DescribeTable("Repaginating Books",
  3284    func(formatting BookFormatting, expectedPages int) {
  3285      book.SetFontSize(formatting.FontSize)
  3286      book.SetLineHeight(formatting.LineHeight)
  3287      book.SetPageDimensions(formatting.PageWidth, formatting.PageHeight)
  3288      Expect(book.RecomputePages()).To(BeNumerically("~", expectedPages, 30))
  3289    },
  3290    func(formatting BookFormatting, expectedPages int) string {
  3291      return fmt.Sprintf("FontSize: %d, LineHeight: %.2f, Page:%.2fx%.2f => %d", 
  3292        formatting.fontSize, formatting.lineHeight, 
  3293        formatting.pageWidth, formatting.pageHeight,
  3294        expectedPages)
  3295    }
  3296    Entry(nil, BookFormatting{FontSize: 12, LineHeight: 1.2, PageWidth:8.5, PageHeight:11}, 2783),
  3297    Entry(nil, BookFormatting{FontSize: 14, LineHeight: 1.3, PageWidth:8.5, 11}, 3120),
  3298    Entry(nil, BookFormatting{FontSize: 10, LineHeight: 1.2, PageWidth:8.5, 11}, 2100),
  3299    Entry(nil, BookFormatting{FontSize: 12, LineHeight: 2.0, PageWidth:8.5, 11}, 6135),
  3300    Entry(nil, BookFormatting{FontSize: 12, LineHeight: 1, PageWidth:5, PageHeight:6}, 12321),
  3301  )
  3302  ```
  3303  
  3304  This is longer but certainly easier to read!
  3305  
  3306  Another Table Spec pattern involves the reuse of table of Entries.  If you have multiple cases to run against the same set of entries you can save of the entries in a `[]TableEntry` slice and then pass the slice to multiple `DescribeTable` functions.  For example:
  3307  
  3308  ```go
  3309  
  3310  var InvalidBookEntries = []TableEntry{
  3311    Entry("Empty book", &books.Book{}),
  3312    Entry("Only title", &books.Book{Title: "Les Miserables"}),
  3313    Entry("Only author", &books.Book{Author: "Victor Hugo"}),
  3314    Entry("Missing pages", &books.Book{Title: "Les Miserables", Author: "Victor Hugo"}),
  3315  }
  3316  
  3317  DescribeTable("Storing invalid books always errors", func(book *books.Book) {
  3318    Expect(library.Store(book)).To(MatchError(books.ErrInvalidBook))
  3319  }, InvalidBookEntries)
  3320  
  3321  DescribeTable("Reading invalid books always errors", func(book *books.Book) {
  3322    Expect(user.Read(book)).To(MatchError(books.ErrInvalidBook))
  3323  }, InvalidBookEntries)
  3324  
  3325  ```
  3326  
  3327  ### Patterns for Asynchronous Testing
  3328  
  3329  It is common, especially in integration suites, to be testing behaviors that occur asynchronously (either within the same process or, in the case of distributed systems, outside the current test process in some combination of external systems).  Ginkgo and Gomega provide the building blocks you need to write effective asynchronous specs efficiently.
  3330  
  3331  Rather than an exhaustive/detailed review we'll simply walk through some common patterns.  Throughout you'll see that you should generally try to use Gomega's `Eventually` and `Consistently` to make [asynchronous assertions](https://onsi.github.io/gomega/#making-asynchronous-assertions).
  3332  
  3333  Both `Eventually` and `Consistently` perform asynchronous assertions by polling the provided input.  In the case of `Eventually`, Gomega polls the input repeatedly until the matcher is satisfied - once that happens the assertion exits successfully and execution continues.  If the matcher is never satisfied `Eventually` will time out with a useful error message.  Both the timeout and polling interval are [configurable](https://onsi.github.io/gomega/#eventually).
  3334  
  3335  In the case of `Consistently`, Gomega polls the the input repeatedly and asserts the matcher is satisfied every time.  `Consistently` only exits early if a failure occurs - otherwise it continues polling until the specified interval elapses.  This is often the only way to assert that something "does not happen" in an asynchronous system.
  3336  
  3337  `Eventually` and `Consistently` can accept three types of input.  You can pass in bare values and assert that some aspect of the value changes eventually.  This is most commonly done with Go channels or Gomega's 
  3338  [`gbytes`](https://onsi.github.io/gomega/#gbytes-testing-streaming-buffers) and [`gexec`](https://onsi.github.io/gomega/#gexec-testing-external-processes) packages.  You can also pass in functions and assert that their return values `Eventually` or `Consistently` satisfy a matcher - we'll cover those later.  Lastly, you can pass in functions that take a `Gomega` argument - these allow you to make assertions within the function and are a way to assert that a series of assertions _eventually_ succeeds.  We'll cover _that_ later as well.  Let's look at these various input types through the lens of some concrete use-cases.
  3339  
  3340  #### Testing an in-process Asynchronous Service.
  3341  Let's imagine an in-process asynchronous service that can prepare books for publishing and emit updates to a buffer.  Since publishing is expensive the publish service returns a channel that will include the published book bits and runs the actual publishing process in a separate Goroutine.  We could test such a service like so:
  3342  
  3343  ```go
  3344  Describe("Publishing books", func() {
  3345    var book *books.Book
  3346    BeforeEach(func() {
  3347      book = loadBookWithContent("les_miserables.fixture")
  3348      Expect(book).NotTo(BeNil())
  3349    })
  3350  
  3351    It("can publish a book, emitting information as it goes", func() {
  3352      buffer := gbytes.NewBuffer() //gbytes provides a thread-safe buffer that works with the `gbytes.Say` matcher
  3353      
  3354      // we begin publishing the book.  This kicks off a goroutine and returns a channel
  3355      c := publisher.Publish(book, buffer)
  3356  
  3357      //gbytes.Say allows us to assert on output to a stream
  3358      Eventually(buffer).Should(gbytes.Say(`Publishing "Les Miserables...`))
  3359      Eventually(buffer).Should(gbytes.Say(`Published page 1/2783`))
  3360      Eventually(buffer).Should(gbytes.Say(`Published page 2782/2783`))
  3361      Eventually(buffer).Should(gbytes.Say(`Publish complete!`))
  3362  
  3363      //rather than call <-c which could block the spec forever we use Eventually to poll the channel and
  3364      //store any received values in a pointer
  3365      var result publisher.PublishResult
  3366      Eventually(c).Should(Receive(&result))
  3367  
  3368      //we make some synchronous assertions on the result
  3369      Expect(result.Title).To(Equal("Les Miserables"))
  3370      Expect(result.EpubSize).To(BeNumerically(">", 10))
  3371      Expect(result.EpubContent).To(ContainSubstring("I've ransomed you from fear and hatred, and now I give you back to God."))
  3372  
  3373      //we expect the publisher to close the channel when it's done
  3374      Eventually(c).Should(BeClosed())
  3375    })
  3376  })
  3377  ```
  3378  
  3379  As you can see Gomega allows us to make some pretty complex asynchronous assertions pretty easily!
  3380  
  3381  #### Testing Local Processes
  3382  Launching and testing an external process is actually quite similar to testing an in-process asynchronous service (the example above).  You typically leverage Goemga's [`gexec`](https://onsi.github.io/gomega/#gexec-testing-external-processes) and [`gbytes`](https://onsi.github.io/gomega/#gbytes-testing-streaming-buffers) packages.  Let's imagine our book-publishing service was a actually a command-line tool we wanted to test:
  3383  
  3384  ```go
  3385  //We compile the publisher in a BeforeSuite so its available to our specs
  3386  //Not that this step can be skipped if the publisher binary is already precompiled
  3387  var publisherPath string
  3388  BeforeSuite(func() {
  3389    var err error
  3390    publisherPath, err = gexec.Build("path/to/publisher")
  3391    Expect(err).NotTo(HaveOccurred())
  3392    DeferCleanup(gexec.CleanupBuildArtifacts)  
  3393  })
  3394  
  3395  Describe("Publishing books", func() {
  3396    It("can publish a book, emitting information as it goes", func() {
  3397      //First, we create a command to invoke the publisher and pass appropriate args
  3398      cmd := exec.Command(publisherPath, "-o=les-miserables.epub", "les-miserables.fixture")
  3399  
  3400      //Now we launch the command with `gexec`.  This returns a session that wraps the running command.  
  3401      //We also tell `gexec` to tee any stdout/stderr output from the process to `GinkgoWriter` - this will
  3402      //ensure we get all the process output if the spec fails.
  3403      session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
  3404      Expect(err).NotTo(HaveOccurred())
  3405  
  3406      //At this point the process is running in the background
  3407      //In addition to teeing to GinkgoWriter gexec will capture any stdout/stderr output to
  3408      //gbytes buffers.  This allows us to make assertions against its stdout output using `gbytes.Say`
  3409      Eventually(session).Should(gbytes.Say(`Publishing "Les Miserables...`))
  3410      Eventually(session).Should(gbytes.Say(`Published page 1/2783`))
  3411      Eventually(session).Should(gbytes.Say(`Published page 2782/2783`))
  3412      Eventually(session).Should(gbytes.Say(`Publish complete!`))
  3413  
  3414      //We can also assert the session has exited 
  3415      Eventually(session).Should(gexec.Exit(0)) //with exit code 0
  3416  
  3417      //At this point we should have the `les-miserables.epub` artifact
  3418      Expect("les-miserables.epub").To(BeAnExistingFile())
  3419  
  3420      result, err := epub.Load("les-miserables.epub")
  3421      Expect(err).NotTo(HaveOccurred())
  3422  
  3423      //we make some synchronous assertions on the result
  3424      Expect(result.Title).To(Equal("Les Miserables"))
  3425      Expect(result.EpubSize).To(BeNumerically(">", 10))
  3426      Expect(result.EpubContent).To(ContainSubstring("I've ransomed you from fear and hatred, and now I give you back to God."))
  3427    })
  3428  })
  3429  ```
  3430  
  3431  #### Testing Blocking Functions
  3432  It's common in Go for functions to block and perform complex operations synchronously - and leave the work of spawning goroutines and managing thread-safety to the user.  You can test such patterns easily with Gomega.  For example, let's test a flow that performs a few expensive operations and assert that everything finishes eventually.
  3433  
  3434  ```go
  3435  Describe("Change book font-size", func() {
  3436    var book *books.Book
  3437    BeforeEach(func() {
  3438      book = loadBookWithContent("les_miserables.fixture")
  3439      Expect(book).NotTo(BeNil())
  3440    })
  3441    
  3442    It("can repaginate books without losing any content", func() {
  3443      done := make(chan interface{})
  3444      go func() {
  3445        defer GinkgoRecover()
  3446  
  3447        content := book.RawContent()
  3448        Expect(book.Pages).To(Equal(2783))
  3449  
  3450        //this might be quite expensive and will block...
  3451        err := book.SetFontSize(28)
  3452        Expect(err).NotTo(HaveOccurred())
  3453  
  3454        Expect(book.Pages).To(BeNumerically(">", 2783))
  3455        Expect(book.RawContent()).To(Equal(content))
  3456  
  3457        close(done)
  3458      }()
  3459  
  3460      Eventually(done).Should(BeClosed())
  3461    })  
  3462  })
  3463  ```
  3464  
  3465  This use of a `done` channel is idiomatic and guards the spec against potentially hanging forever.
  3466  
  3467  #### Testing External Systems
  3468  When integration testing an external system, particularly a distributed system, you'll often find yourself needing to wait for the external state to converge and become eventually consistent.  Gomega makes it easy to poll and validate that the system under test eventually exhibits the desired behavior.  This is typically done by passing functions in to `Eventually` and `Consistently`.
  3469  
  3470  For example, let's imagine testing how an external library service handles notifying users about holds on their books.  Here's what a fully worked example might look like:
  3471  
  3472  ```go
  3473  var library *library.Client
  3474  var _ = BeforeSuite(func() {
  3475    var err error
  3476    library, err = library.NewClient(os.Getenv("LIBRARY_SERVICE"))
  3477    Expect(err).NotTo(HaveOccurred())
  3478  
  3479    Eventually(library.Ping).Should(Succeed())
  3480  })
  3481  
  3482  var _ = Describe("Getting notifications about holds", func() {
  3483    var book *books.Book
  3484    var sarah, jane *user.User
  3485    BeforeEach(func() {
  3486      book = &books.Book{
  3487        Title: "My test book",
  3488        Author: "Ginkgo",
  3489        Pages: 17,
  3490      }
  3491  
  3492      Expect(library.Store(book)).To(Succeed())
  3493      DeferCleanup(library.Delete, book)
  3494  
  3495      sarah = user.NewUser("Sarah", "integration-test-account+sarah@gmail.com")
  3496      jane = user.NewUser("Jane", "integration-test-account+jane@gmail.com")
  3497      
  3498      By("Sarah checks the book out")
  3499      Expect(sarah.CheckOut(library, book)).To(Succeed())
  3500    })
  3501  
  3502    It("notifies the user when their hold is ready", func() {
  3503      By("Jane can't check the book out so she places a hold")
  3504      Expect(jane.CheckOut(library, book)).To(MatchError(books.ErrNoAvailableCopies))
  3505      Expect(jane.PlaceHold(library, book)).To(Succeed())
  3506  
  3507      By("when Sarah returns the book")
  3508      Expect(sarah.Return(library, book)).To(Succeed())
  3509  
  3510      By("Jane eventually gets notified that her book is available in the library app...")
  3511      Eventually(func() ([]user.Notification, error) {
  3512        return jane.FetchNotifications()
  3513      }).Should(ContainElement(user.Notification{Title: book.Title, State: book.ReadyForPickup}))
  3514  
  3515      By("...and in her email...")
  3516      Eventually(func() ([]string, error) {
  3517        messages, err := gmail.Fetch(jane.EmailAddress)
  3518        if err != nil {
  3519          return nil, err
  3520        }
  3521        subjects := []string{}
  3522        for _, message := range messages {
  3523          subjects = append(subjects, message.Subject)
  3524        }
  3525        return subjects, nil
  3526      }).Should(ContainElement(fmt.Sprintf(`"%s" is available for pickup`, book.Title)))
  3527  
  3528      Expect(jane.CheckOut(library, book)).To(Succeed())
  3529    })
  3530  })
  3531  ```
  3532  
  3533  As you can see we are able to clearly test both synchronous concerns (blocking calls to the library service that return immediately) with asynchronous concerns (out-of-band things that happen after a library call has been made).  The DSL allows us to clearly express our intent and capture the flow of this spec with relatively little noise.
  3534  
  3535  One important thing warrants calling out, however.  Notice that we aren't using `Eventually` to assert that individual calls to the `library` or `user` client don't time out.  `Eventually` assumes that the function it is polling will return in a timely manner.  It does not monitor the duration of the function call to apply a timeout.  Rather, it calls the function synchronously and then asserts against the result immediately - it then waits for the polling interval before trying again.  It is expected that the client under test can handle connection timeout issues and return in a timely manner.  One common pattern, shown here, is to place an assertion in a `BeforeSuite` that validates that the external service we need to communicate with is up and ready to receive network traffic.  That's what `Eventually(library.Ping).Should(Succeed())` is doing.  Once we've established the server is up we can proceed to test with confidence.
  3536  
  3537  `Eventually` has a few more tricks that we can leverage to clean this code up a bit.  Since `Eventually` accepts functions we can simply replace this:
  3538  
  3539  ```go
  3540  Eventually(func() ([]user.Notification, error) {
  3541    return jane.FetchNotifications()
  3542  }).Should(ContainElement(user.Notification{Title: book.Title, State: book.ReadyForPickup}))
  3543  ```
  3544  
  3545  with this:
  3546  
  3547  ```go
  3548  Eventually(jane.FetchNotifications).Should(ContainElement(user.Notification{Title: book.Title, State: book.ReadyForPickup}))
  3549  ```
  3550  
  3551  Note that `Eventually` automatically asserts a niladic error as it polls the `FetchNotifications` function.  Also note that we are passing in a reference to the method on the `jane` instance - not invoking it.  `Eventually(jane.FetchNotifications())` would not work - you must pass in `Eventually(jane.FetchNotifications)`!
  3552  
  3553  `Eventually` can _also_ accept functions that take a single `Gomega` parameter.  These functions are then passed a local `Gomega` that can be used to make assertions _inside_ the function as it is polled.  `Eventually` will retry the function if an assertion fails.  This would allow us to replace:
  3554  
  3555  ```go
  3556  Eventually(func() ([]string, error) {
  3557    messages, err := gmail.Fetch(jane.EmailAddress)
  3558    if err != nil {
  3559      return nil, err
  3560    }
  3561    subjects := []string{}
  3562    for _, message := range messages {
  3563      subjects = append(subjects, message.Subject)
  3564    }
  3565    return subjects, nil
  3566  }).Should(ContainElement(fmt.Sprintf(`"%s" is available for pickup`, book.Title)))
  3567  ```
  3568  
  3569  with
  3570  
  3571  ```go
  3572  Eventually(func(g Gomega) ([]string) {
  3573    messages, err := gmail.Fetch(jane.EmailAddress)
  3574    g.Expect(err).NotTo(HaveOccurred())
  3575    subjects := []string{}
  3576    for _, message := range messages {
  3577      subjects = append(subjects, message.Subject)
  3578    }
  3579    return subjects, nil
  3580  }).Should(ContainElement(fmt.Sprintf(`"%s" is available for pickup`, book.Title)))
  3581  ```
  3582  
  3583  we can even push the entire assertion into the polled function:
  3584  
  3585  ```go
  3586  Eventually(func(g Gomega) {
  3587    messages, err := gmail.Fetch(jane.EmailAddress)
  3588    g.Expect(err).NotTo(HaveOccurred())
  3589    subjects := []string{}
  3590    for _, message := range messages {
  3591      subjects = append(subjects, message.Subject)
  3592    }
  3593    expectedSubject := fmt.Sprintf(`"%s" is available for pickup`, book.Title)
  3594    g.Expect(subjects).To(ContainElement(expectedSubject))
  3595    return subjects, nil
  3596  }).Should(Succeed())
  3597  ```
  3598  
  3599  this approach highlights a special-case use of the `Succeed()` matcher with `Eventually(func(g Gomega) {})` - `Eventually` will keep retrying the function until no failures are detected.
  3600  
  3601  > You may be wondering why we need to pass in a dedicated `Gomega` instance to the polled function.  That's because the default global-level assertions are implicitly tied to Ginkgo's `Fail` handler.  The first failed assertion in an `Eventually` would cause the spec to fail with no possibility to retry.  By passing in a fresh `Gomega` instance, `Eventually` can monitor for failures itself and control the final failure/success state of the assertion it is governing.
  3602  
  3603  Finally, since we're on the topic of simplifying things, we can make use of the fact that `ContainElement` can take a matcher to compose it with the `WithTransform` matcher and get rid of the `subjects` loop:
  3604  
  3605  ```go
  3606  Eventually(func(g Gomega) {
  3607    messages, err := gmail.Fetch(jane.EmailAddress)
  3608    g.Expect(err).NotTo(HaveOccurred())
  3609    expectedSubject := fmt.Sprintf(`"%s" is available for pickup`, book.Title)
  3610    subjectGetter := func(m gmail.Message) string { return m.Subject }
  3611    g.Expect(subjects).To(ContainElement(WithTransform(subjectGetter, Equal(expectedSubject))))
  3612    return subjects, nil
  3613  }).Should(Succeed())
  3614  ```
  3615  
  3616  ### Patterns for Parallel Integration Specs
  3617  One of Ginkgo's strengths centers around building and running large complex integration suites.  Integration suites are spec suites that exercise multiple related components to validate the behavior of the integrated system as a whole.  They are notorious for being difficult to write, susceptible to random failure, and painfully slow.  They also happen to be incredibly valuable, particularly when building large complex distributed systems.
  3618  
  3619  The [Patterns for Asynchronous Testing](#patterns-for-asynchronous-testing) section above goes into depth about patterns for testing asynchronous systems like these.  This section will cover patterns for ensuring such specs can run in parallel.  Make sure to read the [Spec Parallelization](#spec-parallelization) section to build a mental model for how Ginkgo supports parallelization first - it's important to understand that parallel specs are running in **separate** processes and are coordinated via the Ginkgo CLI.
  3620  
  3621  #### Managing External Processes in Parallel Suites
  3622  
  3623  We covered how to use `gexec` and `gbytes` to compile, launch, and test external processes in the [Testing Local Processes](#testing-local-processes) portion of the asynchronous testing section.  We'll extend the example there to cover how to design such a test to work well in parallel.
  3624  
  3625  First recall that we used a `BeforeSuite` to compile our `publisher` binary:
  3626  
  3627  ```go
  3628  var publisherPath string
  3629  BeforeSuite(func() {
  3630    var err error
  3631    publisherPath, err = gexec.Build("path/to/publisher")
  3632    Expect(err).NotTo(HaveOccurred())
  3633    DeferCleanup(gexec.CleanupBuildArtifacts)  
  3634  })
  3635  ```
  3636  
  3637  This code will work fine in parallel as well (under the hood `gexec.Build` places build artifacts in a randomly-generated temporary directory - this is why you need to call `gexec.CleanupBuildArtifacts` to clean 
  3638  up); but it's inefficient and all your parallel processes will spend time up front compiling multiple copies of the same binary.  Instead, we can use `SynchronizedBeforeSuite` to perform the compilation step just once:
  3639  
  3640  ```go
  3641  var publisherPath string
  3642  SynchronizedBeforeSuite(func() []byte {
  3643    path, err := gexec.Build("path/to/publisher")
  3644    Expect(err).NotTo(HaveOccurred())
  3645    DeferCleanup(gexec.CleanupBuildArtifacts)
  3646    return []byte(path)
  3647  }, func(path []byte) {
  3648    publisherPath = string(path)
  3649  })
  3650  ```
  3651  
  3652  Now only process #1 will compile the publisher.  All other processes will wait until it's done.  Once complete it will pass the path to the compiled artifact to all other processes.  Note that the `DeferCleanup` in the `SynchronizedBeforeSuite` will have the same runtime semantics as a `SynchronizedAfterSuite` so `gexec` will not cleanup after itself until _all_ processes have finished running.
  3653  
  3654  Now any spec running on any process can simply launch it's own instance of the `publisher` process via `gexec` and make assertions on its output with `gbytes`.  The only thing to be aware of is potential interactions between the multiple publisher processes if they happen to access some sort of shared singleton resources...  Keep reading!
  3655  
  3656  #### Managing External Resources in Parallel Suites: Files
  3657  
  3658  The filesystem is a shared singleton resource.  Each parallel process in a parallel spec run will have access to the same shared filesystem.  As such it is important to avoid spec pollution caused by accidental collisions.  For example, consider the following publisher specs:
  3659  
  3660  ```go
  3661  Describe("Publishing books", func() {
  3662    It("can publish a complete epub", func() {
  3663      cmd := exec.Command(publisherPath, "-o=out.epub", "les-miserables.fixture")
  3664      session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
  3665      Expect(err).NotTo(HaveOccurred())
  3666      Eventually(session).Should(gexec.Exit(0)) //with exit code 0
  3667  
  3668      result, err := epub.Load("out.epub")
  3669      Expect(err).NotTo(HaveOccurred())
  3670      Expect(result.EpubPages).To(Equal(2783))
  3671    })
  3672  
  3673    It("can publish a preview that contains just the first chapter", func() {    
  3674      cmd := exec.Command(publisherPath, "-o=out.epub", "--preview", "les-miserables.fixture")
  3675      session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
  3676      Expect(err).NotTo(HaveOccurred())
  3677      Eventually(session).Should(gexec.Exit(0)) //with exit code 0
  3678  
  3679      result, err := epub.Load("out.epub")
  3680      Expect(err).NotTo(HaveOccurred())
  3681      Expect(result.EpubPages).To(BeNumerically("<", 2783))
  3682      Expect(result.EpubContent).To(ContainSubstring("Chapter 1"))
  3683      Expect(result.EpubContent).NotTo(ContainSubstring("Chapter 2"))
  3684    })
  3685  })
  3686  ```
  3687  
  3688  these specs will always run fine in series - but can fail in subtle and confusing ways when run in parallel!  Since both publish to the same `out.epub` file simultaneously collisions are possible.
  3689  
  3690  There are multiple ways to approach this.  Perhaps the obvious way would be to manually ensure a different output name for each spec:
  3691  
  3692  ```go
  3693  Describe("Publishing books", func() {
  3694    It("can publish a complete epub", func() {
  3695      cmd := exec.Command(publisherPath, "-o=complete.epub", "les-miserables.fixture")
  3696      ...
  3697    })
  3698  
  3699    It("can publish a preview that contains just the first chapter", func() {    
  3700      cmd := exec.Command(publisherPath, "-o=preview.epub", "--preview", "les-miserables.fixture")
  3701      ...
  3702    })
  3703  })
  3704  ```
  3705  
  3706  that's... _ok_.  But it's asking for trouble by putting the namespacing burden on the user.
  3707  
  3708  A better alternative would be to carve out a separate namespace for each spec.  For example, we could create a temporary directory:
  3709  
  3710  ```go
  3711  var tmpDir string
  3712  BeforeEach(func() {
  3713    tmpDir = GinkgoT().TempDir()
  3714  })
  3715  
  3716  Describe("Publishing books", func() {
  3717    It("can publish a complete epub", func() {
  3718      path := filepath.Join(tmpDir, "out.epub")
  3719      cmd := exec.Command(publisherPath, "-o="+path, "les-miserables.fixture")
  3720      ...
  3721    })
  3722  
  3723    It("can publish a preview that contains just the first chapter", func() {    
  3724      path := filepath.Join(tmpDir, "out.epub")
  3725      cmd := exec.Command(publisherPath, "-o="+path, "--preview", "les-miserables.fixture")
  3726      ...
  3727    })
  3728  })
  3729  
  3730  ```
  3731  (here we're using `GinkgoT().TempDir()` to access Ginkgo's implementation of `t.TempDir()` which cleans up after itself - there's no magic here.  You could have simply called `os.MkdirTemp` and cleaned up afterwards yourself.)
  3732  
  3733  This approach works fine but has the sometimes unfortunate side-effect of placing your files in a random location which can make debugging a bit more tedious.
  3734  
  3735  Another approach - and the one used by Ginkgo's own integration suite - is to use the current parallel process index to shard the filesystem:
  3736  
  3737  ```go
  3738  var pathTo func(path string) string
  3739  
  3740  BeforeEach(func() {
  3741    //shard based on our current process index.
  3742    //this starts at 1 and goes up to N, the number of parallel processes.
  3743    dir := fmt.Sprintf("./tmp-%d", GinkgoParallelProcess())
  3744    os.MkdirAll(dir)
  3745    DeferCleanup(os.RemoveAll, dir)
  3746    pathTo = func(path string) string { return filepath.Join(dir, path)}
  3747  })
  3748  
  3749  Describe("Publishing books", func() {
  3750    It("can publish a complete epub", func() {
  3751      path := pathTo("out.epub")
  3752      cmd := exec.Command(publisherPath, "-o="+path, "les-miserables.fixture")
  3753      ...
  3754    })
  3755  
  3756    It("can publish a preview that contains just the first chapter", func() {    
  3757      path := pathTo("out.epub")
  3758      cmd := exec.Command(publisherPath, "-o="+path, "--preview", "les-miserables.fixture")
  3759      ...
  3760    })
  3761  })
  3762  ```
  3763  
  3764  this will create a namespaced local temp directory and provides a convenience function for specs to access paths to the directory.  The directory is cleaned up after each spec.
  3765  
  3766  One nice thing about this approach is our ability to preserve the artifacts in the temporary directory in case of failure.  A common pattern when debugging is to use `--fail-fast` to indicate that the suite should stop running as soon as the first failure occurs.  We can key off of that config to change the behavior of our cleanup code:
  3767  
  3768  ```go
  3769  var pathTo func(path string) string
  3770  
  3771  BeforeEach(func() {
  3772    //shard based on our current process index.
  3773    //this starts at 1 and goes up to N, the number of parallel processes.
  3774    dir := fmt.Sprintf("./tmp-%d", GinkgoParallelProcess())
  3775    os.MkdirAll(dir)
  3776  
  3777    DeferCleanup(func() {
  3778      suiteConfig, _ := GinkgoConfiguration()
  3779      if CurrentSpecReport().Failed() && suiteConfig.FailFast {
  3780        GinkgoWriter.Printf("Preserving artifacts in %s\n", dir)
  3781        return
  3782      }
  3783      Expect(os.RemoveAll(dir)).To(Succeed())
  3784    })
  3785  
  3786    pathTo = func(path string) string { return filepath.Join(dir, path)}
  3787  })
  3788  ```
  3789  
  3790  now, the temporary directory will be preserved in the event of spec failure, but only if `--fail-fast` is configured.
  3791  
  3792  #### Managing External Resources in Parallel Suites: Ports
  3793  Another shared singleton resources is the set of available ports on the local machine.  If you need to be able to explicitly specify a port to use during a spec (e.g. you're spinning up an external process that needs to be told what port to listen on) you'll need to be careful how you carve up the available set of ports.  For example, the following would not work:
  3794  
  3795  ```go
  3796  var libraryAddr string
  3797  
  3798  BeforeSuite(func() {
  3799    libraryAddr := "127.0.0.1:50000"
  3800    library.Serve(listenAddr)
  3801    client = library.NewClient(listenAddr)
  3802  })
  3803  ```
  3804  
  3805  when running in parallel each process will attempt to listen on port 50000 and a race with only one winner will ensue.  You could, instead, have the server you're spinning up figure out a free port to use and report it back - but that is not always possible in the case where a service must be explicitly configured.
  3806  
  3807  Instead, you can key off of the current parallel process index to give each process a unique port.  In this case we could:
  3808  
  3809  ```go
  3810  var libraryAddr string
  3811  
  3812  BeforeSuite(func() {
  3813    libraryAddr := fmt.Sprintf("127.0.0.1:%d", 50000 + GinkgoParallelProcess())
  3814    library.Serve(listenAddr)
  3815    client = library.NewClient(listenAddr)
  3816  })
  3817  ```
  3818  
  3819  now each process will have its own unique port.
  3820  
  3821  #### Patterns for Testing against Databases
  3822  Stateful services that store data in external databases benefit greatly from a robust comprehensive test suite.  Unfortunately, many testers shy away from full-stack testing that includes the database for fear of slowing their suites down.  Fake/mock databases only get you so far, however.  In this section we outline patterns for spinning up real databases and testing against them in ways that are parallelizable and, therefore, able to leverage the many cores in modern machines to keep our full-stack tests fast.
  3823  
  3824  The core challenge with stateful testing is to ensure that specs do not pollute one-another.  This applies in the serial context where a one spec can change the state of the database in a way that causes a subsequent spec to fail.  This also applies in the parallel context where multiple specs can write to the same database at the same time in contradictory ways.  Thankfully there are patterns that make mitigating these sorts of pollution straightforward and transparent to the user writing specs.
  3825  
  3826  Throughout these examples we have a `DBRunner` library that can spin up instances of a database and a `DBClient` library that can connect to that instance and perform actions.  We aren't going to pick any particular database technology as these patterns apply across most of them.
  3827  
  3828  ##### A Database for Every Spec
  3829  
  3830  Here's an incredibly expensive but sure-fire way to make sure each spec has a clean slate of data:
  3831  
  3832  ```go
  3833  var client *DBClient.Client
  3834  var _ = BeforeEach(func() {
  3835    db, err := DBRunner.Start()
  3836    Expect(err).NotTo(HaveOccurred())
  3837    DeferCleanup(db.Stop)
  3838  
  3839    client = DBClient.New(db)
  3840    Expect(client.Connect()).To(Succeed())
  3841    DeferCleanup(client.Disconnect)
  3842  
  3843    client.InitializeSchema()
  3844  })
  3845  ```
  3846  
  3847  Now, each spec will get a fresh running database, with a clean initialized schema, to use.  This will work - but will probably be quite slow, even when running in parallel.
  3848  
  3849  ##### A Database for Every Parallel Process
  3850  
  3851  Instead, a more common pattern is to spin up a database for each parallel process and reset its state between specs.
  3852  
  3853  ```go
  3854  var client *DBClient.Client
  3855  var snapshot *DBClient.Snapshot
  3856  var _ = BeforeSuite(func() {
  3857    db, err := DBRunner.Start()
  3858    Expect(err).NotTo(HaveOccurred())
  3859    DeferCleanup(db.Stop)
  3860  
  3861    client = DBClient.New(db)
  3862    Expect(client.Connect()).To(Succeed())
  3863    DeferCleanup(client.Disconnect)
  3864  
  3865    client.InitializeSchema()
  3866    snapshot, err = client.TakeSnapshot()
  3867    Expect(err).NotTo(HaveOccurred())
  3868  })
  3869  
  3870  var _ = BeforeEach(func() {
  3871    Expect(client.RestoreSnapshot(snapshot)).To(Succeed())
  3872  })
  3873  ```
  3874  
  3875  here we've assumed the `client` can take and restore a snapshot of the database.  This could be as simple as truncating tables in a SQL database or clearing out a root key in a hierarchical key-value store.  Such methods are usually quite _fast_ - certainly fast enough to warrant full-stack testing over mock/fake-heavy testing.
  3876  
  3877  With this approach each parallel process has its own dedicated database so there is no chance for cross-spec pollution when running in parallel.  Within each parallel process the dedicated database is cleared out between specs so there's no chance for spec pollution from one spec to the next.
  3878  
  3879  This all works if you have the ability to spin up a local copy of the database.  But there are times when you must rely on an external stateful singleton resource and need to test against it.  We'll explore patterns for testing those next.
  3880  
  3881  #### Patterns for Testing against Singletons
  3882  There are times when your spec suite must run against a stateful shared singleton system.  Perhaps it is simply too expensive to spin up multiple systems (e.g. each "system" is actually a memory-hungry cluster of distributed systems; or, perhaps, you are testing against a real-life instance of a service and can't spin up another instance).
  3883  
  3884  In such cases the recommended pattern for ensuring your specs are parallelizable is to embrace sharding the external service by the parallel process index.  Exactly how this is done will depend on the nature of the system.
  3885  
  3886  Here are some examples to give you a sense for how to approach this:
  3887  
  3888  - If you're testing against a shared hierarchical key-value store (in which the keys are represented as `/paths/to/values` - e.g. S3, etcd) you can write your specs and code to accept a configurable root key such that all values are stored under `/{ROOT}/path/to/value`.  The suite can then configure `ROOT = fmt.Sprintf("test-%d", GinkgoParallelProcess())`
  3889  - If you're testing an external multi-tenant service you can have your suite create a unique tenant per parallel process.  Perhaps something like `service.CreateUser(fmt.Sprintf("test-user-%d", GinkgoParallelProcess()))`
  3890  - If you're testing an external service that supports namespace you can request a dedicated namespace per parallel process (e.g. a dedicated Cloud Foundry org and space, or a dedicated Kubernetes namespace).
  3891  
  3892  The details will be context dependent - but generally speaking you should be able to find a way to shard access to the singleton system by `GinkgoParallelProcess()`.  You'll also need to figure out how to reset the shard between specs to ensure that each spec has a clean slate to operate from.
  3893  
  3894  #### Some Subtle Parallel Testing Gotchas
  3895  
  3896  We'll round out the parallel testing patterns with a couple of esoteric gotchas.
  3897  
  3898  There's a somewhat obscure issue where an external process that outlives the current spec suite can cause the spec suite to hang mysteriously.  If you've hit that issue read through this [GitHub issue](https://github.com/onsi/gomega/issues/473) - there's likely a stdout/stderr pipe that's sticking around preventing Go's `cmd.Wait()` from returning.
  3899  
  3900  When you spin up a process yourself you should generally have it pipe its output to `GinkgoWriter`.  If you pipe to `os.Stdout` and/or `os.Stderr` and the process outlives the current spec you'll cause Ginkgo's output interceptor to hang.  Ginkgo will actually catch this and print out a long error message telling you what to do.  You can learn more on the associated [GitHub issue](https://github.com/onsi/ginkgo/issues/851)
  3901  
  3902  ### Benchmarking Code
  3903  
  3904  Go's built-in `testing` package provides support for running `Benchmark`s.  Earlier versions of Ginkgo subject-node variants that were able to mimic Go's `Benchmark` tests.  As of Ginkgo 2.0 these nodes are no longer available.  Instead, Ginkgo users can benchmark their code using Gomega's substantially more flexible `gmeasure` package.  If you're interested, check out the `gmeasure` [docs](https://onsi.github.io/gomega/#gmeasure-benchmarking-code).  Here we'll just provide a quick example to show how `gmeasure` integrates into Ginkgo's reporting infrastructure.
  3905  
  3906  `gmeasure` is structured around the metaphor of Experiments.  With `gmeasure` you create ``Experiments` that can record multiple named `Measurements`.  Each named `Measurement` can record multiple values (either `float64` or `duration`).  `Experiments` can then produce reports to show the statistical distribution of their `Measurements` and different `Measurements`, potentially from different `Experiments` can be ranked and compared.  `Experiments` can also be cached using an `ExperimentCache` - this can be helpful to avoid rerunning expensive experiments _and_ to save off "gold-master" experiments to compare against to identify potential regressions in performance - orchestrating all that is left to the user.
  3907  
  3908  Here's an example where we profile how long it takes to repaginate books:
  3909  
  3910  ```go
  3911  
  3912  Describe("Repaginating Books", func() {
  3913    var book *books.Book
  3914    BeforeEach(func() {
  3915      book = LoadFixture("les-miserables.json")
  3916    })
  3917  
  3918    // this is a spec that validates the behavior is correct
  3919    // note that we can mix validation specs alongside performance specs
  3920    It("can repaginate books", func() {
  3921      Expect(book.CurrentFontSize()).To(Equal(12))
  3922      originalPages := book.Pages
  3923  
  3924      book.SetFontSize(10)
  3925      Expect(book.RecomputePages()).To(BeNumerically(">", originalPages))
  3926    })
  3927  
  3928    // this is our performance spec.  we mark it as Serial to ensure it does not run in
  3929    // parallel with other specs (which could affect performance measurements)
  3930    // we also label it with "measurement" - this is optional but would allow us to filter out
  3931    // measurement-related specs more easily
  3932    It("repaginates books efficiently", Serial, Label("measurement"), func() {
  3933      //we create a new experiment
  3934      experiment := gmeasure.NewExperiment("Repaginating Books")
  3935  
  3936      //Register the experiment as a ReportEntry - this will cause Ginkgo's reporter infrastructure
  3937      //to print out the experiment's report and to include the experiment in any generated reports
  3938      AddReportEntry(experiment.Name, experiment)
  3939  
  3940      //we sample a function repeatedly to get a statistically significant set of measurements
  3941      experiment.Sample(func(idx int) {
  3942        book = LoadFixture("les-miserables.json") //always start with a fresh copy
  3943        book.SetFontSize(10)
  3944  
  3945        //measure how long it takes to RecomputePages() and store the duration in a "repagination" measurement
  3946        experiment.MeasureDuration("repagination", func() {
  3947          book.RecomputePages()
  3948        })
  3949      }, gmeasure.SamplingConfig{N:20, Duration: time.Minute}) //we'll sample the function up to 20 times or up to a minute, whichever comes first.
  3950    })
  3951  })
  3952  ```
  3953  
  3954  Now when this spec runs Ginkgo will print out a report detailing the experiment:
  3955  
  3956  ```
  3957  Will run 1 of 1 specs
  3958  ------------------------------
  3959  • [2.029 seconds]
  3960  Repaginating Books repaginates books efficiently [measurement]
  3961  /path/to/books_test.go:19
  3962  
  3963    Begin Report Entries >>
  3964    Repaginating Books - /path/to/books_test.go:21 @ 11/04/21 13:42:57.936
  3965      Repaginating Books
  3966      Name          | N  | Min   | Median | Mean  | StdDev | Max
  3967      ==========================================================================
  3968      repagination [duration] | 20 | 5.1ms | 104ms  | 101.4ms | 52.1ms | 196.4ms
  3969    << End Report Entries
  3970  ```
  3971  
  3972  This is helpful - but the real value in a performance suite like this would be to capture possible performance regressions.  There are multiple ways of doing this - you could use an [Experiment Cache](https://onsi.github.io/gomega/#caching-experiments) and make the suite [configurable](#supporting-custom-suite-configuration) such that a baseline experiment is stored to disk when the suite is so configured.  Then, when the suite runs, it simply loads the baseline from the cache and compares it to the measured duration.  Ginkgo's own performance suite does this.
  3973  
  3974  Alternatively you can just hard-code an expected value after running the experiment and make an appropriate assertion.  For example:
  3975  
  3976  ```go
  3977  It("repaginates books efficiently", Serial, Label("measurement"), func() {
  3978    experiment := gmeasure.NewExperiment("Repaginating Books")
  3979    AddReportEntry(experiment.Name, experiment)
  3980  
  3981    experiment.Sample(func(idx int) {
  3982      book = LoadFixture("les-miserables.json")
  3983      book.SetFontSize(10)
  3984  
  3985      experiment.MeasureDuration("repagination", func() {
  3986        book.RecomputePages()
  3987      })
  3988    }, gmeasure.SamplingConfig{N:20, Duration: time.Minute})
  3989  
  3990    //we get the median repagination duration from the experiment we just ran
  3991    repaginationStats := experiment.GetStats("repagination")
  3992    medianDuration := repaginationStats.DurationFor(gmeasure.StatMedian)
  3993  
  3994    //and assert that it hasn't changed much from ~100ms
  3995    Expect(medianDuration).To(BeNumerically("~", 100*time.Millisecond, 50*time.Millisecond))
  3996  })
  3997  ```
  3998  
  3999  now the spec will fail if the pagination time ever changes drastically from its measured value.  Of course the actual runtime will depend on the machine and test environment you're running on - so some caveats will apply.  Nonetheless an upper bound spec such as:
  4000  
  4001  ```go
  4002  Expect(medianDuration).To(BeNumerically("<", 300*time.Millisecond))
  4003  ```
  4004  
  4005  could still be a useful smoketest to catch any major regressions early in the development cycle.
  4006  
  4007  ### Building Custom Matchers
  4008  As you've seen throughout this documentation, Gomega allows you to write expressive assertions.  You can build on Gomega's building blocks to construct custom matchers tuned to the semantics of your codebase.
  4009  
  4010  One way to do this is by implementing Gomega's `GomegaMatcher` interface.
  4011  
  4012  A simpler, alternative, however, is to simply compose matchers together in a simple function.  For example, let's write a matcher that asserts that our book is valid, has a given title, author, and page-count.  Rather than repeat this all the time:
  4013  
  4014  ```go
  4015  Expect(book.IsValid()).To(BeTrue())
  4016  Expect(book.Title).To(Equal("Les Miserables"))
  4017  Expect(book.Author).To(Equal("Victor Hugo"))
  4018  Expect(book.Pages).To(Equal(2783))
  4019  ```
  4020  
  4021  we can implement a function that returns a composite Gomega matcher:
  4022  
  4023  ```go
  4024  func BeAValidBook(title string, author string, pages int) types.GomegaMatcher {
  4025    return And(
  4026      WithTransform(func(book *books.Book) bool {
  4027        return book.IsValid()
  4028      }, BeTrue()),
  4029      HaveField("Title", Equal(title)),
  4030      HaveField("Author", Equal(author)),
  4031      HaveField("Pages", Equal(pages)),
  4032    )
  4033  }
  4034  ```
  4035  
  4036  this function uses Gomega's `And` matcher to require that the four passed-in matchers are satisfied.  It then uses `WithTransform` to accept the passed-in book and call it's `IsValid()` method, then asserts the returned value is `true`.  It then uses the `HaveField` matcher to make assertions on the fields within the `Book` struct.
  4037  
  4038  Now we can write:
  4039  
  4040  ```go
  4041  Expect(book).To(BeAValidBook("Les Miserables", "Victor Hugo", 2783))
  4042  ```
  4043  
  4044  We can go one step further and use typed parameters to pick and choose which pieces of `Book` we want to test with our matcher.  This is a bit contrived for our simple example but can be quite useful in more complex domains:
  4045  
  4046  ```go
  4047  
  4048  type Title string
  4049  type Author string
  4050  type Pages int
  4051  
  4052  func BeAValidBook(params ...interface{}) types.GomegaMatcher {
  4053    matchers := []types.GomegaMatcher{
  4054      WithTransform(func(book *books.Book) bool {
  4055        return book.IsValid()
  4056      }, BeTrue())
  4057    }
  4058  
  4059    if len(params) > 0 {
  4060      for _, param := range params {
  4061        switch v := param.(type) {
  4062        case Title:
  4063          matchers = append(matchers, HaveField("Title", Equal(v)))
  4064        case Author:
  4065          matchers = append(matchers, HaveField("Author", Equal(v)))
  4066        case Pages:
  4067          matchers = append(matchers, HaveField("Pages", Equal(v)))
  4068        default:
  4069          Fail("Unknown type %T in BeAValidBook() \n", v)
  4070        }
  4071      }
  4072    }
  4073  
  4074    return And(matchers...)
  4075  }
  4076  ```
  4077  
  4078  Now we can do things like:
  4079  
  4080  ```go
  4081  Expect(book).To(BeAValidBook()) //simply asserts IsValid() is true
  4082  Expect(book).To(BeAValidBook(Title("Les Miserables")))
  4083  Expect(book).To(BeAValidBook(Author("Victor Hugo")))
  4084  Expect(book).To(BeAValidBook(Title("Les Miserables"), Pages(2783)))
  4085  ```
  4086  
  4087  ## Decorator Reference
  4088  We've seen a number of Decorators detailed throughout this documentation.  This reference collects them all in one place.
  4089  
  4090  #### Node Decorators Overview
  4091  Ginkgo's container nodes, subject nodes, and setup nodes all accept decorators.  Decorators are specially typed arguments passed into the node constructors.  They can appear anywhere in the `args ...interface{}` list in the constructor signatures:
  4092  
  4093  ```go
  4094  func Describe(text string, args ...interface{})
  4095  func It(text string, args ...interface{})
  4096  func BeforeEach(args ...interface{})
  4097  ```
  4098  
  4099  Ginkgo will vet the passed in decorators and exit with a clear error message if it detects any invalid configurations. 
  4100  
  4101  Moreover, Ginkgo also supports passing in arbitrarily nested slices of decorators.  Ginkgo will unroll these slices and process the flattened list.  This makes it easier to pass around groups of decorators.  For example, this is valid:
  4102  
  4103  ```go
  4104  markFlaky := []interface{}{Label("flaky"), FlakeAttempts(3)}
  4105  
  4106  var _ = Describe("a bunch of flaky controller tests", markFlaky, Label("controller"), func() {
  4107    ...
  4108  }
  4109  ```
  4110  The resulting tests will be decorated with `FlakeAttempts(3)` and the two labels `flaky` and `controller`.
  4111  
  4112  #### The Serial Decorator
  4113  The `Serial` decorator applies to container nodes and subject nodes only.  It is an error to try to apply the `Serial` decorator to a setup node.
  4114  
  4115  `Serial` allows the user to mark specs and containers of specs as only eligible to run in serial.  Ginkgo will guarantee that these specs never run in parallel with other specs.
  4116  
  4117  If a container is marked as `Serial` then all the specs defined in that container will be marked as `Serial`.
  4118  
  4119  You cannot mark specs and containers as `Serial` if they appear in an `Ordered` container.  Instead, mark the `Ordered` container as `Serial`.
  4120  
  4121  #### The Ordered Decorator
  4122  The `Ordered` decorator applies to container nodes only.  It is an error to try to apply the `Ordered` decorator to a setup or subject node.  It is an error to nest an `Ordered` container within another `Ordered` container - however you may nest an `Ordered` container within a non-ordered container and vice versa.
  4123  
  4124  `Ordered` allows the user to [mark containers of specs as ordered](#ordered-containers).  Ginkgo will guarantee that the container's specs will run in the order they appear in and will never run in parallel with one another (though they may run in parallel with other specs unless the `Serial` decorator is also applied to the `Ordered` container).
  4125  
  4126  When a spec in an `Ordered` container fails, all subsequent specs in the ordered container are skipped.  Only `Ordered` containers can contain `BeforeAll` and `AfterAll` setup nodes.
  4127  
  4128  #### The Label Decorator
  4129  The `Label` decorator applies to container nodes and subject nodes only.  It is an error to try to apply the `Label` decorator to a setup node.  You can also apply the `Label` decorator to your `RunSpecs` invocation to annotate the entire suite with a label.
  4130  
  4131  `Label` allows the user to annotate specs and containers of specs with labels.  The `Label` decorator takes a variadic set of strings allowing you to apply multiple labels simultaneously.  Labels are arbitrary strings that do not include the characters `"&|!,()/"`.  Specs can have as many labels as you'd like and the set of labels for a given spec is the union of all the labels of the container nodes and the subject node.
  4132  
  4133  Labels can be used to control which subset of tests to run.  This is done by providing the `--label-filter` flag to the `ginkgo` CLI.  More details can be found at [Spec Labels](#spec-labels).
  4134  
  4135  #### The Focus and Pending Decorator
  4136  The `Focus` and `Pending` decorators apply to container nodes and subject nodes only.  It is an error to try to `Focus` or `Pending` a setup node.
  4137  
  4138  Using these decorators is identical to using the `FX` or `PX` form of the node constructor.  For example:
  4139  
  4140  ```go
  4141  FDescribe("container", func() {
  4142    It("runs", func() {})
  4143    PIt("is pending", func() {})
  4144  })
  4145  ```
  4146  
  4147  and
  4148  
  4149  ```go
  4150  Describe("container", Focus, func() {
  4151    It("runs", func() {})
  4152    It("is pending", Pending, func() {})
  4153  })
  4154  ```
  4155  
  4156  are equivalent.
  4157  
  4158  It is an error to decorate a node as both `Pending` and `Focus`:
  4159  
  4160  ```go
  4161  It("is invalid", Focus, Pending, func() {}) //this will cause Ginkgo to exit with an error
  4162  ```
  4163  
  4164  The `Focus` and `Pending` decorators are propagated through the test hierarchy as described in [Pending Specs](#pending-specs) and [Focused Specs](#focused-specs)
  4165  
  4166  #### The Offset Decorator
  4167  The `Offset(uint)` decorator applies to all decorable nodes.  The `Offset(uint)` decorator allows the user to change the stack-frame offset used to compute the location of the test node.  This is useful when building shared test behaviors.  For example:
  4168  
  4169  ```go
  4170  SharedBehaviorIt := func() {
  4171    It("does something common and complicated", Offset(1), func() {
  4172      ...
  4173    })
  4174  }
  4175  
  4176  Describe("thing A", func() {
  4177    SharedBehaviorIt()
  4178  })
  4179  
  4180  Describe("thing B", func() {
  4181    SharedBehaviorIt()
  4182  })
  4183  ```
  4184  
  4185  now, if the `It` defined in `SharedBehaviorIt` the location reported by Ginkgo will point to the line where `SharedBehaviorIt` is *invoked*.
  4186  
  4187  `Offset`s only apply to the node that they decorate.  Setting the `Offset` for a container node does not affect the `Offset`s computed in its child nodes.
  4188  
  4189  If multiple `Offset`s are provided on a given node, only the last one is used.
  4190  
  4191  #### The CodeLocation Decorator
  4192  In addition to `Offset`, users can decorate nodes with a `types.CodeLocation`.  `CodeLocation`s are the structs Ginkgo uses to capture location information.  You can, for example, set a custom location using `types.NewCustomCodeLocation(message string)`.  Now when the location of the node is emitted the passed in `message` will be printed out instead of the usual `file:line` location.
  4193  
  4194  Passing a `types.CodeLocation` decorator in has the same semantics as passing `Offset` in: it only applies to the node in question.
  4195  
  4196  #### The FlakeAttempts Decorator
  4197  The `FlakeAttempts(uint)` decorator applies container and subject nodes.  It is an error to apply `FlakeAttempts` to a setup node.
  4198  
  4199  `FlakeAttempts` allows the user to flag specific tests or groups of tests as potentially flaky.  Ginkgo will run tests up to the number of times specified in `FlakeAttempts` until they pass.  For example:
  4200  
  4201  ```go
  4202  Describe("flaky tests", FlakeAttempts(3), func() {
  4203    It("is flaky", func() {
  4204      ...
  4205    })
  4206  
  4207    It("is also flaky", func() {
  4208      ...
  4209    })
  4210  
  4211    It("is _really_ flaky", FlakeAttempts(5) func() {
  4212      ...
  4213    })
  4214  
  4215    It("is _not_ flaky", FlakeAttempts(1), func() {
  4216      ...
  4217    })
  4218  })
  4219  ```
  4220  
  4221  With this setup, `"is flaky"` and `"is also flaky"` will run up to 3 times.  `"is _really_ flaky"` will run up to 5 times.  `"is _not_ flaky"` will run only once.  Note that if multiple `FlakeAttempts` appear in a spec's hierarchy, the most deeply nested `FlakeAttempts` wins.  If multiple `FlakeAttempts` are passed into a given node, the last one wins.
  4222  
  4223  If `ginkgo --flake-attempts=N` is set the value passed in by the CLI will override all the decorated values.  Every test will now run up to `N` times.
  4224  
  4225  ## Ginkgo CLI Overview
  4226  
  4227  This chapter provides a quick overview and tour of the Ginkgo CLI.  For comprehensive details about all of the Ginkgo CLI's flags, run `ginkgo help`.  To get information about Ginkgo's implicit `run` command (i.e. what you get when you just run `ginkgo`) run `ginkgo help run`.
  4228  
  4229  The Ginkgo CLI is the recommended and supported tool for running Ginkgo suites.  While you _can_ run Ginkgo suites with `go test` you must use the CLI to run suites in parallel and to aggregate profiles.  There are also a (small) number of `go test` flags that Ginkgo does not support - an error will be emitted if you attempt to use these (for example, `go test -count=N`, use `ginkgo -repeat=N` instead).
  4230  
  4231  In addition to Ginkgo's own flags, the `ginkgo` CLI also supports passing through (nearly) all `go test` flags and `go build` flags.  These are documented under `ginkgo help run` and `ginkgo help build` (which provides a detailed list of available `go build` flags).  If you think Ginkgo's missing anything, please open an [issue](https://github.com/onsi/ginkgo/issues/new).
  4232  
  4233  ### Running Specs
  4234  
  4235  By default:
  4236  
  4237  ```bash
  4238  ginkgo
  4239  ```
  4240  
  4241  Will run the suite in the current directory.
  4242  
  4243  You can run multiple suites by passing them in as arguments:
  4244  
  4245  ```bash
  4246  ginkgo path/to/suite path/to/other/suite
  4247  ```
  4248  
  4249  or by running:
  4250  
  4251  ```bash
  4252  ginkgo -r
  4253  #or
  4254  ginkgo ./...
  4255  ```
  4256  
  4257  which will recurse through the current file tree and run any suites it finds.
  4258  
  4259  To pass additional arguments or custom flags down to your suite use `--` to separate your arguments from arguments intended for `ginkgo`:
  4260  
  4261  ```bash
  4262  ginkgo -- <PASS-THROUGHS>
  4263  ```
  4264  
  4265  Finally, note that any Ginkgo flags must appear _before_ the list of packages.  Putting it all together:
  4266  
  4267  ```bash
  4268  ginkgo <GINKGO-FLAGS> <PACKAGES> -- <PASS-THROUGHS>
  4269  ```
  4270  
  4271  By default Ginkgo is running the `run` subcommand.  So all these examples can also be written as `ginkgo run <GINKGO-FLAGS> <PACKAGES> -- <PASS-THROUGHS>`.  To get help about Ginkgo's run flags you'll need to run `ginkgo help run`.
  4272  
  4273  ### Precompiling Suites
  4274  
  4275  It is often convenient to precompile suites and distribute them as binaries.  You can do this with `ginkgo build`:
  4276  
  4277  ```bash
  4278  ginkgo build path/to/suite /path/to/other/suite
  4279  ```
  4280  
  4281  This will produce precompiled binaries called `package-name.test`.  You can then run `ginkgo package-name.test` _or_ `./package-name.test` to invoke the binary without going through a compilation step.
  4282  
  4283  Since the `ginkgo` CLI is a [necessary component when running specs in parallel](#spec-parallelization) to run precompiled specs in parallel you must:
  4284  
  4285  ```bash
  4286  ginkgo -p ./path/to/suite.test
  4287  ```
  4288  
  4289  As with the rest of the go tool chain, you can cross-compile and target different platforms using the standard `GOOS` and `GOARCH` environment variables.  For example: 
  4290  
  4291  ```bash
  4292  GOOS=linux GOARCH=amd64 ginkgo build path/to/package
  4293  ```
  4294  
  4295  will build a linux binary.
  4296  
  4297  Finally, the `build` command accepts a subset of the flags of the `run` command.  This is because some flags apply at compile time whereas others apply at run-time only.  This can be a bit confusing with the `go test` toolchain but Ginkgo tries to make things clearer by carefully controlling the availability of flags across the two commands.
  4298  
  4299  ### Watching for Changes
  4300  
  4301  To help enable a fast feedback loop during development, Ginkgo provides a `watch` subcommand that watches suites and their dependencies for changes.  When a change is detected `ginkgo watch` will automatically rerun the suite.
  4302  
  4303  `ginkgo watch` accepts most of `ginkgo run`'s flags.  So, you can do things like:
  4304  
  4305  ```bash
  4306  ginkgo watch -r -p
  4307  ```
  4308  
  4309  to monitor all packages, recursively, for changes and run them in parallel when changes are detected.
  4310  
  4311  For each monitored package, Ginkgo also monitors that package's dependencies.  By default `ginkgo watch` monitors a package's immediate dependencies.  You can adjust this using the `-depth` flag.  Set `-depth` to `0` to disable monitoring dependencies and set `-depth` to something greater than `1` to monitor deeper down the dependency graph.
  4312  
  4313  
  4314  ### Generators
  4315  
  4316  As discussed above, Ginkgo provides a pair of generator functions to help you bootstrap a suite and add a spec file to it:
  4317  
  4318  ```bash
  4319  ginkgo bootstrap
  4320  ```
  4321  
  4322  will generate a file named `PACKAGE_suite_test.go` and
  4323  
  4324  ```bash
  4325  ginkgo generate <SUBJECT>
  4326  ```
  4327  
  4328  will generate a file named `SUBJECT_test.go` (or `PACKAGE_test.go` if `<SUBJECT>` is not provided).  Both generators support custom templates using `--template`.  Take a look at the [Ginkgo's CLI code](https://github.com/onsi/ginkgo/tree/master/ginkgo/ginkgo/generators) to see what's available in the template.
  4329  
  4330  ### Creating an Outline of Specs
  4331  
  4332  If you want to see an outline of the Ginkgo specs in an individual file, you can use the `ginkgo outline` command:
  4333  
  4334  ```bash
  4335  ginkgo outline book_test.go
  4336  ```
  4337  
  4338  This generates an outline in a comma-separated-values (CSV) format. Column headers are on the first line, followed by Ginkgo containers, specs, and other identifiers, in the order they appear in the file:
  4339  
  4340    Name,Text,Start,End,Spec,Focused,Pending
  4341    Describe,Book,124,973,false,false,false
  4342    BeforeEach,,217,507,false,false,false
  4343    Describe,Categorizing book length,513,970,false,false,false
  4344    Context,With more than 300 pages,567,753,false,false,false
  4345    It,should be a novel,624,742,true,false,false
  4346    Context,With fewer than 300 pages,763,963,false,false,false
  4347    It,should be a short story,821,952,true,false,false
  4348  
  4349  The columns are:
  4350  
  4351  - Name (string): The name of a container, spec, or other identifier in the core DSL.
  4352  - Text (string): The description of a container or spec. (If it is not a literal, it is undefined in the outline.)
  4353  - Start (int): Position of the first character in the container or spec.
  4354  - End (int): Position of the character immediately after the container or spec.
  4355  - Spec (bool): True, if the identifier is a spec.
  4356  - Focused (bool): True, if focused. (Conforms to the rules in [Focused Specs](#focused-specs).)
  4357  - Pending (bool): True, if pending. (Conforms to the rules in [Pending Specs](#pending-specs).)
  4358  
  4359  You can set a different output format with the `-format` flag. Accepted formats are `csv`, `indent`, and `json`. The `ident` format is like `csv`, but uses identation to show the nesting of containers and specs. Both the `csv` and `json` formats can be read by another program, e.g., an editor plugin that displays a tree view of Ginkgo tests in a file, or presents a menu for the user to quickly navigate to a container or spec.
  4360  
  4361  `ginkgo outline` is intended for integration with third-party libraries and applications.  If you simply want to know how a suite will run without running it try `ginkgo -v --dry-run` instead.
  4362  
  4363  ### Other Subcommands
  4364  
  4365  To unfocus any programmatically focused specs in the current directory or subdirectories, run:
  4366  
  4367  ```bash
  4368  ginkgo unfocus
  4369  ```
  4370  
  4371  To get a list of `Label`s used in a suite run
  4372  
  4373  ```bash
  4374  ginkgo labels
  4375  ```
  4376  
  4377  `labels` (naively) parses your spec files and looks for calls to the `Label` decorator.
  4378  
  4379  To get the current version of the `ginkgo` CLI run:
  4380  
  4381  ```bash
  4382  ginkgo version
  4383  ```
  4384  
  4385  ## Third-Party Integrations
  4386  
  4387  ### Using Third-party Libraries
  4388  
  4389  Most third-party Go `testing` integrations (e.g. matcher libraries, mocking libraries) take and wrap a `*testing.T` to provide functionality.  Unfortunately there is no formal interface for `*testing.T` however Ginkgo provides a function, `GinkgoT()` that returns a struct that implements all the methods that `*testing.T` implements.  Most libraries accept the `*testing.T` object via an interface and you can usually simply pass in `GinkgoT()` and expect the library to work.
  4390  
  4391  For example, you can choose to use [testify](https://github.com/stretchr/testify) instead of Gomega like so:
  4392  
  4393  ```go
  4394  package foo_test
  4395  
  4396  import (
  4397    . "github.com/onsi/ginkgo"
  4398  
  4399    "github.com/stretchr/testify/assert"
  4400  )
  4401  
  4402  var _ = Describe(func("foo") {
  4403    It("should testify to its correctness", func(){
  4404      assert.Equal(GinkgoT(), foo{}.Name(), "foo")
  4405    })
  4406  })
  4407  ```
  4408  
  4409  Similarly if you're using [Gomock](https://code.google.com/p/gomock/) you can simply pass `GinkgoT()` to your controller:
  4410  
  4411  
  4412  ```go
  4413  import (
  4414    "code.google.com/p/gomock/gomock"
  4415  
  4416    . "github.com/onsi/ginkgo"
  4417    . "github.com/onsi/gomega"
  4418  )
  4419  
  4420  var _ = Describe("Consumer", func() {
  4421    var (
  4422      mockCtrl *gomock.Controller
  4423      mockThing *mockthing.MockThing
  4424      consumer *Consumer
  4425    )
  4426  
  4427    BeforeEach(func() {
  4428      mockCtrl = gomock.NewController(GinkgoT())
  4429      mockThing = mockthing.NewMockThing(mockCtrl)
  4430      consumer = NewConsumer(mockThing)
  4431    })
  4432  
  4433  
  4434    It("should consume things", func() {
  4435      mockThing.EXPECT().OmNom()
  4436      consumer.Consume()
  4437    })
  4438  })
  4439  ```
  4440  
  4441  Since `GinkgoT()` implements `Cleanup()` (using `DeferCleanup()` under the hood) Gomock will automatically register a call to `mockCtrl.Finish()` when the controller is created.
  4442  
  4443  When using Gomock you may want to run `ginkgo` with the `-trace` flag to print out stack traces for failures which will help you trace down where, in your code, invalid calls occured.
  4444  
  4445  ### IDE Support
  4446  Ginkgo works best from the command-line, and [`ginkgo watch`](#watching-for-changes) makes it easy to rerun tests on the command line whenever changes are detected.
  4447  
  4448  There are a set of [completions](https://github.com/onsi/ginkgo-sublime-completions) available for [Sublime Text](https://www.sublimetext.com/) (just use [Package Control](https://sublime.wbond.net/) to install `Ginkgo Completions`) and for [VS Code](https://code.visualstudio.com/) (use the extensions installer and install vscode-ginkgo).  There is also a VS Code extension to run specs from VSCode called [Ginkgo Test Explorer](https://github.com/joselitofilho/ginkgoTestExplorer).
  4449  
  4450  IDE authors can set the `GINKGO_EDITOR_INTEGRATION` environment variable to any non-empty value to enable coverage to be displayed for focused specs. By default, Ginkgo will fail with a non-zero exit code if specs are focused to ensure they do not pass in CI.
  4451  
  4452  {% endraw  %}