Convert Figma logo to code with AI

onsi logoginkgo

A Modern Testing Framework for Go

8,225
650
8,225
99

Top Related Projects

9,298

GoMock is a mocking framework for the Go programming language.

22,996

A toolkit with common assertions and mocks that plays nicely with the standard library

Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.

4,921

Automatically generate Go test boilerplate from your source code.

5,959

A mock code autogenerator for Go

Quick Overview

Ginkgo is a BDD-style Go testing framework that aims to make writing expressive and comprehensive tests easier. It provides a rich set of matchers, a flexible structure for organizing tests, and built-in support for asynchronous testing and benchmarking.

Pros

  • Expressive and readable test structure using Describe, Context, and It blocks
  • Rich set of matchers for various assertion types
  • Built-in support for asynchronous testing and benchmarking
  • Integrates well with Go's built-in testing package

Cons

  • Learning curve for developers new to BDD-style testing
  • Can be overkill for simple projects or small test suites
  • Requires additional setup compared to standard Go testing
  • May introduce dependencies that some teams prefer to avoid

Code Examples

  1. Basic test structure:
import (
    . "github.com/onsi/ginkgo/v2"
    . "github.com/onsi/gomega"
)

var _ = Describe("Calculator", func() {
    Context("when adding two numbers", func() {
        It("should return the correct sum", func() {
            result := Add(2, 3)
            Expect(result).To(Equal(5))
        })
    })
})
  1. Asynchronous testing:
It("should eventually complete", func() {
    Eventually(func() bool {
        return IsProcessComplete()
    }).Should(BeTrue())
})
  1. Table-driven tests:
DescribeTable("multiplication",
    func(a, b, expected int) {
        Expect(Multiply(a, b)).To(Equal(expected))
    },
    Entry("positive numbers", 2, 3, 6),
    Entry("negative numbers", -2, 3, -6),
    Entry("zeros", 0, 5, 0),
)

Getting Started

  1. Install Ginkgo:

    go install github.com/onsi/ginkgo/v2/ginkgo
    go get github.com/onsi/gomega/...
    
  2. Bootstrap your test suite:

    cd path/to/your/package
    ginkgo bootstrap
    
  3. Generate a test file:

    ginkgo generate my_file
    
  4. Run your tests:

    ginkgo
    

Competitor Comparisons

9,298

GoMock is a mocking framework for the Go programming language.

Pros of mock

  • Lightweight and focused solely on mocking, making it easier to integrate into existing test suites
  • Generates mock implementations automatically, reducing boilerplate code
  • Seamlessly integrates with Go's built-in testing package

Cons of mock

  • Limited to mocking functionality, lacking broader testing features like BDD-style syntax
  • Requires more manual setup for complex test scenarios compared to Ginkgo's comprehensive framework
  • Less expressive for describing test behavior and expectations

Code Comparison

mock:

ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockObj := NewMockInterface(ctrl)
mockObj.EXPECT().SomeMethod(gomock.Any()).Return(42)

// Use mockObj in your test

Ginkgo:

Describe("MyComponent", func() {
    It("should do something", func() {
        mockObj := &MockObject{}
        mockObj.On("SomeMethod", mock.Anything).Return(42)
        
        // Use mockObj in your test
    })
})

Both libraries provide mocking capabilities, but Ginkgo offers a more expressive, BDD-style syntax for structuring tests. mock focuses specifically on generating mock implementations, while Ginkgo provides a comprehensive testing framework with additional features beyond mocking.

22,996

A toolkit with common assertions and mocks that plays nicely with the standard library

Pros of testify

  • Simpler syntax and easier to learn for developers familiar with Go's built-in testing package
  • Provides a wide range of assertion functions for various data types and scenarios
  • Integrates well with existing Go testing workflows and tools

Cons of testify

  • Less expressive for complex test scenarios compared to Ginkgo's BDD-style syntax
  • Lacks built-in support for test organization features like BeforeEach and AfterEach hooks
  • Does not provide native parallel test execution capabilities

Code Comparison

testify:

func TestSomething(t *testing.T) {
    assert := assert.New(t)
    assert.Equal(123, CalculateValue())
    assert.True(IsValid())
}

Ginkgo:

var _ = Describe("Something", func() {
    It("calculates the correct value", func() {
        Expect(CalculateValue()).To(Equal(123))
        Expect(IsValid()).To(BeTrue())
    })
})

The code comparison shows that testify uses a more traditional Go testing approach, while Ginkgo employs a BDD-style syntax. testify's assertions are more straightforward, but Ginkgo's expectations can be more readable for complex scenarios.

Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.

Pros of Goconvey

  • Provides a web UI for real-time test results and coverage reports
  • Supports automatic test execution on file changes
  • Offers a more familiar assertion syntax for developers coming from other languages

Cons of Goconvey

  • Less idiomatic Go syntax compared to Ginkgo
  • Limited support for advanced testing patterns like table-driven tests
  • May require additional setup and configuration for CI/CD environments

Code Comparison

Ginkgo:

Describe("Math", func() {
    It("should add numbers correctly", func() {
        Expect(1 + 1).To(Equal(2))
    })
})

Goconvey:

Convey("Math", t, func() {
    Convey("should add numbers correctly", func() {
        So(1+1, ShouldEqual, 2)
    })
})

Both Ginkgo and Goconvey are popular testing frameworks for Go, each with its own strengths. Ginkgo follows a more idiomatic Go approach and provides better support for advanced testing patterns, while Goconvey offers a user-friendly web UI and automatic test execution. The choice between the two depends on the specific needs of the project and the team's preferences.

4,921

Automatically generate Go test boilerplate from your source code.

Pros of gotests

  • Automatically generates table-driven tests, reducing boilerplate code
  • Focuses on unit testing, making it simpler for developers new to testing
  • Integrates well with existing Go tooling and IDEs

Cons of gotests

  • Limited to generating unit tests, lacking support for more complex testing scenarios
  • Doesn't provide a full testing framework or advanced features like hooks and custom matchers
  • May require manual adjustments for more sophisticated test cases

Code Comparison

Ginkgo example:

var _ = Describe("Calculator", func() {
    It("adds two numbers", func() {
        result := Add(2, 3)
        Expect(result).To(Equal(5))
    })
})

gotests generated example:

func TestAdd(t *testing.T) {
    tests := []struct {
        name string
        a, b int
        want int
    }{
        {"basic", 2, 3, 5},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Add(tt.a, tt.b); got != tt.want {
                t.Errorf("Add() = %v, want %v", got, tt.want)
            }
        })
    }
}

Ginkgo provides a BDD-style testing framework with rich features, while gotests focuses on generating table-driven tests using Go's standard testing package. Ginkgo offers more flexibility for complex scenarios, whereas gotests simplifies the process of creating basic unit tests.

5,959

A mock code autogenerator for Go

Pros of Mockery

  • Specialized for generating mock interfaces, making it more focused and efficient for mocking tasks
  • Supports generating mocks for unexported interfaces, providing more flexibility in testing
  • Offers a command-line tool for easy integration into development workflows

Cons of Mockery

  • Limited to mocking functionality, whereas Ginkgo provides a full testing framework
  • May require additional setup and configuration compared to Ginkgo's all-in-one approach
  • Less extensive documentation and community support compared to Ginkgo

Code Comparison

Mockery example:

//go:generate mockery --name=Database
type Database interface {
    Get(id string) (string, error)
    Set(id string, value string) error
}

Ginkgo example:

var _ = Describe("Database", func() {
    It("should get and set values", func() {
        db := NewDatabase()
        Expect(db.Set("key", "value")).To(Succeed())
        val, err := db.Get("key")
        Expect(err).NotTo(HaveOccurred())
        Expect(val).To(Equal("value"))
    })
})

Both tools serve different purposes in the Go testing ecosystem. Mockery excels at generating mock interfaces, while Ginkgo provides a comprehensive BDD-style testing framework. The choice between them depends on specific project needs and testing preferences.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Ginkgo

test | Ginkgo Docs


Ginkgo

Ginkgo 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 matcher library. Together, Ginkgo and Gomega let you express the intent behind your specs clearly:

import (
    . "github.com/onsi/ginkgo/v2"
    . "github.com/onsi/gomega"
    ...
)

var _ = Describe("Checking books out of the library", Label("library"), func() {
    var library *libraries.Library
    var book *books.Book
    var valjean *users.User
    BeforeEach(func() {
        library = libraries.NewClient()
        book = &books.Book{
            Title: "Les Miserables",
            Author: "Victor Hugo",
        }
        valjean = users.NewUser("Jean Valjean")
    })

    When("the library has the book in question", func() {
        BeforeEach(func(ctx SpecContext) {
            Expect(library.Store(ctx, book)).To(Succeed())
        })

        Context("and the book is available", func() {
            It("lends it to the reader", func(ctx SpecContext) {
                Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed())
                Expect(valjean.Books()).To(ContainElement(book))
                Expect(library.UserWithBook(ctx, book)).To(Equal(valjean))
            }, SpecTimeout(time.Second * 5))
        })

        Context("but the book has already been checked out", func() {
            var javert *users.User
            BeforeEach(func(ctx SpecContext) {
                javert = users.NewUser("Javert")
                Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed())
            })

            It("tells the user", func(ctx SpecContext) {
                err := valjean.Checkout(ctx, library, "Les Miserables")
                Expect(err).To(MatchError("Les Miserables is currently checked out"))
            }, SpecTimeout(time.Second * 5))

            It("lets the user place a hold and get notified later", func(ctx SpecContext) {
                Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed())
                Expect(valjean.Holds(ctx)).To(ContainElement(book))

                By("when Javert returns the book")
                Expect(javert.Return(ctx, library, book)).To(Succeed())

                By("it eventually informs Valjean")
                notification := "Les Miserables is ready for pick up"
                Eventually(ctx, valjean.Notifications).Should(ContainElement(notification))

                Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed())
                Expect(valjean.Books(ctx)).To(ContainElement(book))
                Expect(valjean.Holds(ctx)).To(BeEmpty())
            }, SpecTimeout(time.Second * 10))
        })  
    })

    When("the library does not have the book in question", func() {
        It("tells the reader the book is unavailable", func(ctx SpecContext) {
            err := valjean.Checkout(ctx, library, "Les Miserables")
            Expect(err).To(MatchError("Les Miserables is not in the library catalog"))
        }, SpecTimeout(time.Second * 5))
    })
})

Jump to the docs to learn more. It's easy to bootstrap and start writing your first specs.

If you have a question, comment, bug report, feature request, etc. please open a GitHub issue, or visit the Ginkgo Slack channel.

Capabilities

Whether 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, RSpec, Jasmine, and Busted. This style of testing is sometimes referred to as "Behavior-Driven Development" (BDD) though Ginkgo's utility extends beyond acceptance-level testing.

With Ginkgo's DSL you can use nestable Describe, Context and When container nodes to help you organize your specs. BeforeEach and AfterEach setup nodes for setup and cleanup. It and Specify subject nodes that hold your assertions. BeforeSuite and AfterSuite nodes to prep for and cleanup after a suite... and much more!.

At runtime, Ginkgo can run your specs in reproducibly random order and has sophisticated support for spec parallelization. In fact, running specs in parallel is as easy as

ginkgo -p

By following established patterns for writing parallel 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.

As your suites grow Ginkgo helps you keep your specs organized with labels and lets you easily run subsets of specs, either programmatically or on the command line. And Ginkgo's reporting infrastructure generates machine-readable output in a variety of formats and allows you to build your own custom reporting infrastructure.

Ginkgo ships with ginkgo, a command line tool 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.

And that's just Ginkgo! Gomega brings a rich, mature, family of assertions and matchers to your suites. With Gomega you can easily mix synchronous and asynchronous assertions 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.

Happy Testing!

License

Ginkgo is MIT-Licensed

Contributing

See CONTRIBUTING.md