Top Related Projects
A toolkit with common assertions and mocks that plays nicely with the standard library
Simple error handling primitives
GoMock is a mocking framework for the Go programming language.
Ginkgo's Preferred Matcher Library
A Modern Testing Framework for Go
Professional lightweight testing mini-framework for Go.
Quick Overview
go-cmp is a Go package for comparing arbitrary values. It provides a set of comparison functions and customizable options to perform deep equality checks and generate human-readable diff reports. The library is particularly useful for writing tests and implementing custom comparison logic.
Pros
- Flexible and customizable comparison options
- Generates detailed, human-readable diff reports
- Supports comparison of complex data structures, including nested structs and slices
- Integrates well with Go's testing framework
Cons
- Requires some initial setup and configuration for complex comparisons
- May have a slight performance overhead compared to simple equality checks
- Limited built-in support for certain types (e.g., time.Time)
- Learning curve for advanced features and customizations
Code Examples
- Basic comparison of two structs:
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func TestPersonComparison(t *testing.T) {
person1 := Person{Name: "Alice", Age: 30}
person2 := Person{Name: "Alice", Age: 31}
if diff := cmp.Diff(person1, person2); diff != "" {
t.Errorf("Person mismatch (-want +got):\n%s", diff)
}
}
- Comparing slices with custom options:
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
func TestSliceComparison(t *testing.T) {
slice1 := []int{1, 2, 3, 4}
slice2 := []int{4, 3, 2, 1}
opt := cmpopts.SortSlices(func(a, b int) bool { return a < b })
if diff := cmp.Diff(slice1, slice2, opt); diff != "" {
t.Errorf("Slice mismatch (-want +got):\n%s", diff)
}
}
- Comparing maps with custom transformer:
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
func TestMapComparison(t *testing.T) {
map1 := map[string]int{"a": 1, "b": 2}
map2 := map[string]int{"a": 1, "b": 3}
transformer := cmp.Transformer("abs", func(in int) int {
if in < 0 {
return -in
}
return in
})
if diff := cmp.Diff(map1, map2, transformer); diff != "" {
t.Errorf("Map mismatch (-want +got):\n%s", diff)
}
}
Getting Started
To use go-cmp in your Go project, follow these steps:
-
Install the package:
go get github.com/google/go-cmp/cmp
-
Import the package in your Go file:
import "github.com/google/go-cmp/cmp"
-
Use the
cmp.Diff()
function to compare values:if diff := cmp.Diff(expected, actual); diff != "" { t.Errorf("Values mismatch (-want +got):\n%s", diff) }
For more advanced usage and customization options, refer to the package documentation and examples in the GitHub repository.
Competitor Comparisons
A toolkit with common assertions and mocks that plays nicely with the standard library
Pros of testify
- Provides a wider range of testing utilities beyond comparison (e.g., mocking, suite support)
- More extensive assertion functions for various data types and scenarios
- Offers a fluent, chainable API for writing expressive tests
Cons of testify
- Larger dependency with more code to maintain
- May encourage overuse of assertions, potentially leading to brittle tests
- Less focused on deep, structural comparisons compared to go-cmp
Code Comparison
testify:
assert.Equal(t, expected, actual)
assert.Contains(t, slice, element)
assert.NotNil(t, object)
go-cmp:
if diff := cmp.Diff(expected, actual); diff != "" {
t.Errorf("Mismatch (-want +got):\n%s", diff)
}
Summary
testify offers a comprehensive testing toolkit with a wide range of assertions and utilities, making it suitable for projects requiring extensive testing features. go-cmp, on the other hand, focuses specifically on deep comparisons with a more minimalist approach. The choice between the two depends on the project's needs, with testify being more feature-rich but potentially heavier, while go-cmp provides a lightweight solution for precise comparisons.
Simple error handling primitives
Pros of errors
- Focuses on error handling and wrapping, providing a more comprehensive error management solution
- Offers stack trace functionality, making debugging easier
- Widely adopted in the Go community for error handling
Cons of errors
- Limited to error handling, not a general-purpose comparison tool
- May add overhead to error creation and handling in some cases
- Requires explicit wrapping of errors to maintain stack traces
Code Comparison
errors:
import "github.com/pkg/errors"
err := errors.New("original error")
wrappedErr := errors.Wrap(err, "additional context")
fmt.Printf("%+v\n", wrappedErr)
go-cmp:
import "github.com/google/go-cmp/cmp"
diff := cmp.Diff(want, got)
if diff != "" {
t.Errorf("Mismatch (-want +got):\n%s", diff)
}
Summary
errors is specialized for error handling and provides stack traces, while go-cmp is a general-purpose comparison tool for testing. errors is more focused but limited to error management, whereas go-cmp offers flexible comparison options for various data types. The choice between them depends on the specific needs of your project: error handling or deep comparisons in tests.
GoMock is a mocking framework for the Go programming language.
Pros of mock
- Specifically designed for mocking in Go, providing a more comprehensive mocking solution
- Offers a command-line tool (mockgen) to generate mock implementations automatically
- Supports stubbing of method calls with custom behavior and return values
Cons of mock
- Steeper learning curve due to more complex API and concepts
- Requires additional setup and code generation steps
- May introduce more dependencies and complexity to your project
Code Comparison
mock:
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockObj := NewMockInterface(ctrl)
mockObj.EXPECT().SomeMethod(gomock.Any()).Return(42)
go-cmp:
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Mismatch (-want +got):\n%s", diff)
}
Summary
While mock is a powerful tool for creating and managing mocks in Go tests, go-cmp focuses on providing deep equality comparisons for complex data structures. mock offers more features for mocking but requires more setup, while go-cmp is simpler to use for comparing values but lacks mocking capabilities. Choose based on your specific testing needs and project complexity.
Ginkgo's Preferred Matcher Library
Pros of Gomega
- More expressive and readable assertions with a fluent API
- Built-in support for asynchronous testing and eventually consistent assertions
- Extensive set of matchers for various data types and scenarios
Cons of Gomega
- Steeper learning curve due to its more complex API
- Potentially slower execution compared to simpler assertion libraries
- Requires additional dependencies and setup
Code Comparison
Gomega:
Expect(result).To(Equal(expectedValue))
Expect(someSlice).To(ContainElement(element))
Expect(someFunction).To(Panic())
go-cmp:
if diff := cmp.Diff(expected, actual); diff != "" {
t.Errorf("Mismatch (-want +got):\n%s", diff)
}
Key Differences
- Gomega offers a more expressive and readable syntax for assertions
- go-cmp focuses on deep equality comparisons and generating detailed diffs
- Gomega provides built-in support for asynchronous testing, while go-cmp is primarily for synchronous comparisons
- go-cmp is part of the official Google Go repositories, potentially offering better long-term support and integration with other Google tools
Both libraries have their strengths, and the choice between them depends on specific project requirements, team preferences, and testing needs.
A Modern Testing Framework for Go
Pros of Ginkgo
- Provides a full-featured BDD testing framework for Go
- Offers powerful test organization with nested Describe and Context blocks
- Includes built-in support for asynchronous testing and parallel test execution
Cons of Ginkgo
- Steeper learning curve due to its extensive feature set
- May be overkill for simple projects or those preferring a minimalist approach
- Requires additional setup and configuration compared to standard Go testing
Code Comparison
Ginkgo test example:
var _ = Describe("Calculator", func() {
It("can add two numbers", func() {
result := Add(2, 3)
Expect(result).To(Equal(5))
})
})
go-cmp usage example:
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Result mismatch (-want +got):\n%s", diff)
}
Summary
Ginkgo is a comprehensive BDD testing framework for Go, offering rich features for test organization and execution. go-cmp, on the other hand, is a focused library for comparing Go values and generating human-readable diffs. While Ginkgo provides a complete testing solution, go-cmp excels at deep comparisons and producing detailed diff output. The choice between them depends on project requirements and team preferences.
Professional lightweight testing mini-framework for Go.
Pros of is
- Simpler API with a more concise syntax for common assertions
- Built-in support for testing HTTP handlers and responses
- Colorized output for better readability in test results
Cons of is
- Less flexibility for complex comparisons
- Fewer options for customizing diff output
- Not as widely adopted or maintained as go-cmp
Code Comparison
is:
is := is.New(t)
is.Equal(got, want)
is.NoErr(err)
go-cmp:
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Mismatch (-want +got):\n%s", diff)
}
Summary
is provides a more straightforward and readable approach for basic assertions, making it ideal for simple test cases. It also offers built-in HTTP testing utilities. However, go-cmp offers greater flexibility and customization options for complex comparisons, making it more suitable for advanced testing scenarios. go-cmp is also more widely adopted and actively maintained within the Go community.
The choice between the two libraries depends on the specific needs of your project, with is being more suitable for quick and simple tests, while go-cmp excels in scenarios requiring detailed and customizable comparisons.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Package for equality of Go values
This package is intended to be a more powerful and safer alternative to
reflect.DeepEqual
for comparing whether two values are semantically equal.
The primary features of cmp
are:
-
When the default behavior of equality does not suit the needs of the test, custom equality functions can override the equality operation. For example, an equality function may report floats as equal so long as they are within some tolerance of each other.
-
Types that have an
Equal
method may use that method to determine equality. This allows package authors to determine the equality operation for the types that they define. -
If no custom equality functions are used and no
Equal
method is defined, equality is determined by recursively comparing the primitive kinds on both values, much likereflect.DeepEqual
. Unlikereflect.DeepEqual
, unexported fields are not compared by default; they result in panics unless suppressed by using anIgnore
option (seecmpopts.IgnoreUnexported
) or explicitly compared using theAllowUnexported
option.
See the documentation for more information.
This is not an official Google product.
Install
go get -u github.com/google/go-cmp/cmp
License
BSD - See LICENSE file
Top Related Projects
A toolkit with common assertions and mocks that plays nicely with the standard library
Simple error handling primitives
GoMock is a mocking framework for the Go programming language.
Ginkgo's Preferred Matcher Library
A Modern Testing Framework for Go
Professional lightweight testing mini-framework for Go.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot