1
2
3[](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) | [Ginkgo Docs](https://onsi.github.io/ginkgo/)
4
5---
6
7# Ginkgo
8
9Ginkgo is a mature testing framework for Go designed to help you write expressive specs. Ginkgo builds on top of Go's `testing` foundation and is complemented by the [Gomega](https://github.com/onsi/gomega) matcher library. Together, Ginkgo and Gomega let you express the intent behind your specs clearly:
10
11```go
12import (
13 . "github.com/onsi/ginkgo/v2"
14 . "github.com/onsi/gomega"
15 ...
16)
17
18var _ = Describe("Checking books out of the library", Label("library"), func() {
19 var library *libraries.Library
20 var book *books.Book
21 var valjean *users.User
22 BeforeEach(func() {
23 library = libraries.NewClient()
24 book = &books.Book{
25 Title: "Les Miserables",
26 Author: "Victor Hugo",
27 }
28 valjean = users.NewUser("Jean Valjean")
29 })
30
31 When("the library has the book in question", func() {
32 BeforeEach(func(ctx SpecContext) {
33 Expect(library.Store(ctx, book)).To(Succeed())
34 })
35
36 Context("and the book is available", func() {
37 It("lends it to the reader", func(ctx SpecContext) {
38 Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed())
39 Expect(valjean.Books()).To(ContainElement(book))
40 Expect(library.UserWithBook(ctx, book)).To(Equal(valjean))
41 }, SpecTimeout(time.Second * 5))
42 })
43
44 Context("but the book has already been checked out", func() {
45 var javert *users.User
46 BeforeEach(func(ctx SpecContext) {
47 javert = users.NewUser("Javert")
48 Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed())
49 })
50
51 It("tells the user", func(ctx SpecContext) {
52 err := valjean.Checkout(ctx, library, "Les Miserables")
53 Expect(err).To(MatchError("Les Miserables is currently checked out"))
54 }, SpecTimeout(time.Second * 5))
55
56 It("lets the user place a hold and get notified later", func(ctx SpecContext) {
57 Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed())
58 Expect(valjean.Holds(ctx)).To(ContainElement(book))
59
60 By("when Javert returns the book")
61 Expect(javert.Return(ctx, library, book)).To(Succeed())
62
63 By("it eventually informs Valjean")
64 notification := "Les Miserables is ready for pick up"
65 Eventually(ctx, valjean.Notifications).Should(ContainElement(notification))
66
67 Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed())
68 Expect(valjean.Books(ctx)).To(ContainElement(book))
69 Expect(valjean.Holds(ctx)).To(BeEmpty())
70 }, SpecTimeout(time.Second * 10))
71 })
72 })
73
74 When("the library does not have the book in question", func() {
75 It("tells the reader the book is unavailable", func(ctx SpecContext) {
76 err := valjean.Checkout(ctx, library, "Les Miserables")
77 Expect(err).To(MatchError("Les Miserables is not in the library catalog"))
78 }, SpecTimeout(time.Second * 5))
79 })
80})
81```
82
83Jump to the [docs](https://onsi.github.io/ginkgo/) to learn more. It's easy to [bootstrap](https://onsi.github.io/ginkgo/#bootstrapping-a-suite) and start writing your [first specs](https://onsi.github.io/ginkgo/#adding-specs-to-a-suite).
84
85If you have a question, comment, bug report, feature request, etc. please open a [GitHub issue](https://github.com/onsi/ginkgo/issues/new), or visit the [Ginkgo Slack channel](https://app.slack.com/client/T029RQSE6/CQQ50BBNW).
86
87## Capabilities
88
89Whether writing basic unit specs, complex integration specs, or even performance specs - Ginkgo gives you an expressive Domain-Specific Language (DSL) that will be familiar to users coming from frameworks such as [Quick](https://github.com/Quick/Quick), [RSpec](https://rspec.info), [Jasmine](https://jasmine.github.io), and [Busted](https://lunarmodules.github.io/busted/). This style of testing is sometimes referred to as "Behavior-Driven Development" (BDD) though Ginkgo's utility extends beyond acceptance-level testing.
90
91With Ginkgo's DSL you can use nestable [`Describe`, `Context` and `When` container nodes](https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes) to help you organize your specs. [`BeforeEach` and `AfterEach` setup nodes](https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach) for setup and cleanup. [`It` and `Specify` subject nodes](https://onsi.github.io/ginkgo/#spec-subjects-it) that hold your assertions. [`BeforeSuite` and `AfterSuite` nodes](https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite) to prep for and cleanup after a suite... and [much more!](https://onsi.github.io/ginkgo/#writing-specs).
92
93At runtime, Ginkgo can run your specs in reproducibly [random order](https://onsi.github.io/ginkgo/#spec-randomization) and has sophisticated support for [spec parallelization](https://onsi.github.io/ginkgo/#spec-parallelization). In fact, running specs in parallel is as easy as
94
95```bash
96ginkgo -p
97```
98
99By following [established patterns for writing parallel specs](https://onsi.github.io/ginkgo/#patterns-for-parallel-integration-specs) you can build even large, complex integration suites that parallelize cleanly and run performantly. And you don't have to worry about your spec suite hanging or leaving a mess behind - Ginkgo provides a per-node `context.Context` and the capability to interrupt the spec after a set period of time - and then clean up.
100
101As your suites grow Ginkgo helps you keep your specs organized with [labels](https://onsi.github.io/ginkgo/#spec-labels) and lets you easily run [subsets of specs](https://onsi.github.io/ginkgo/#filtering-specs), either [programmatically](https://onsi.github.io/ginkgo/#focused-specs) or on the [command line](https://onsi.github.io/ginkgo/#combining-filters). And Ginkgo's reporting infrastructure generates machine-readable output in a [variety of formats](https://onsi.github.io/ginkgo/#generating-machine-readable-reports) _and_ allows you to build your own [custom reporting infrastructure](https://onsi.github.io/ginkgo/#generating-reports-programmatically).
102
103Ginkgo ships with `ginkgo`, a [command line tool](https://onsi.github.io/ginkgo/#ginkgo-cli-overview) with support for generating, running, filtering, and profiling Ginkgo suites. You can even have Ginkgo automatically run your specs when it detects a change with `ginkgo watch`, enabling rapid feedback loops during test-driven development.
104
105And that's just Ginkgo! [Gomega](https://onsi.github.io/gomega/) brings a rich, mature, family of [assertions and matchers](https://onsi.github.io/gomega/#provided-matchers) to your suites. With Gomega you can easily mix [synchronous and asynchronous assertions](https://onsi.github.io/ginkgo/#patterns-for-asynchronous-testing) in your specs. You can even build your own set of expressive domain-specific matchers quickly and easily by composing Gomega's [existing building blocks](https://onsi.github.io/ginkgo/#building-custom-matchers).
106
107Happy Testing!
108
109## License
110
111Ginkgo is MIT-Licensed
112
113## Contributing
114
115See [CONTRIBUTING.md](CONTRIBUTING.md)
View as plain text