Pact Go
Fast, easy and reliable testing for your APIs and microservices.
Pact is the de-facto API contract testing tool. Replace expensive and brittle end-to-end integration tests with fast, reliable and easy to debug unit tests.
- ⚡ Lightning fast
- 🎈 Effortless full-stack integration testing - from the front-end to the back-end
- 🔌 Supports HTTP/REST and event-driven systems
- 🛠️ Configurable mock server
- 😌 Powerful matching rules prevents brittle tests
- 🤝 Integrates with Pact Broker / Pactflow for powerful CI/CD workflows
- 🔡 Supports 12+ languages
Why use Pact?
Contract testing with Pact lets you:
- ⚡ Test locally
- 🚀 Deploy faster
- ⬇️ Reduce the lead time for change
- 💰 Reduce the cost of API integration testing
- 💥 Prevent breaking changes
- 🔎 Understand your system usage
- 📃 Document your APIs for free
- 🗄 Remove the need for complex data fixtures
- 🤷♂️ Reduce the reliance on complex test environments
Watch our series on the problems with end-to-end integrated tests, and how contract testing can help.
|
Documentation
This readme offers an basic introduction to the library. The full documentation for Pact Go and the rest of the framework is available at https://docs.pact.io/.
Tutorial (60 minutes)
Learn everything in Pact Go in 60 minutes: https://github.com/pact-foundation/pact-workshop-go
Need Help
Installation
# install pact-go as a dev dependency
go get github.com/pact-foundation/pact-go/v2@2.x.x
# NOTE: If using Go 1.19 or later, you need to run go install instead
# go install github.com/pact-foundation/pact-go/v2@2.x.x
# download and install the required libraries. The pact-go will be installed into $GOPATH/bin, which is $HOME/go/bin by default.
pact-go -l DEBUG install
# 🚀 now write some tests!
If the pact-go
command above is not found, make sure that $GOPATH/bin
is in your path. I.e.,
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
You can also keep the library versions up to date by running the version.CheckVersion()
function.
Manual Installation Instructions
Manual
Downlod the latest Pact FFI Library
library for your OS, and install onto a standard library search path (we suggest: /usr/local/lib
on OSX/Linux):
Ensure you have the correct extension for your OS:
- For Mac OSX:
.dylib
(For M1 users, you need the aarch64-apple-darwin
version) - For Linux:
.so
- For Windows:
.dll
wget https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v0.1.2/libpact_ffi-osx-x86_64.dylib.gz
gunzip libpact_ffi-osx-x86_64.dylib.gz
mv libpact_ffi-osx-x86_64.dylib /usr/local/lib/libpact_ffi.dylib
Test the installation:
pact-go help
Usage
Consumer package
The consumer interface is in the package: github.com/pact-foundation/pact-go/v2/consumer
.
Writing a Consumer test
Pact is a consumer-driven contract testing tool, which is a fancy way of saying that the API Consumer
writes a test to set out its assumptions and needs of its API Provider
(s). By unit testing our API client with Pact, it will produce a contract
that we can share to our Provider
to confirm these assumptions and prevent breaking changes.
In this example, we are going to be testing our User API client, responsible for communicating with the UserAPI
over HTTP. It currently has a single method GetUser(id)
that will return a *User
.
Pact tests have a few key properties. We'll demonstrate a common example using the 3A Arrange/Act/Assert
pattern.
func TestUserAPIClient(t *testing.T) {
mockProvider, err := NewV2Pact(MockHTTPProviderConfig{
Consumer: "UserAPIConsumer",
Provider: "UserAPI",
})
assert.NoError(t, err)
mockProvider.
AddInteraction().
Given("A user with ID 10 exists").
UponReceiving("A request for User 10").
WithRequest("GET", S("/user/10")).
WillRespondWith(200).
WithBodyMatch(&User{})
err = mockProvider.ExecuteTest(func(config MockServerConfig) error {
client := newClient(config.Host, config.Port)
user, err := client.GetUser("10")
assert.NoError(t, err)
assert.Equal(t, 10, user.ID)
return err
})
assert.NoError(t, err)
}
You can see (and run) the full version of this in ./examples/basic_test.go
.
For a full example, see the Pactflow terraform provider pact tests.
Provider package
The provider interface is in the package: github.com/pact-foundation/pact-go/v2/provider
Verifying a Provider
A provider test takes one or more pact files (contracts) as input, and Pact verifies that your provider adheres to the contract. In the simplest case, you can verify a provider as per below.
func TestV3HTTPProvider(t *testing.T) {
go startServer()
verifier := HTTPVerifier{}
err := verifier.VerifyProvider(t, VerifyRequest{
ProviderBaseURL: "http://localhost:1234",
PactFiles: []string{
filepath.ToSlash("/path/to/SomeConsumer-SomeProvider.json"),
},
})
assert.NoError(t, err)
}
Compatibility
Specification Compatibility
* v3 support is limited to the subset of functionality required to enable language inter-operable Message support.
Roadmap
The roadmap for Pact and Pact Go is outlined on our main website.
Detail on the native Go implementation can be found here.
Contributing
See CONTRIBUTING.