Profile
Back to NewsBack
GitHub Trending 7 min
Reader Mode
pact-foundation/pact-go: Golang version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.

pact-foundation/pact-go: Golang version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.

4 hours ago

!logo

Pact Go

Test</a> codecov</a> Go Report Card</a> GoDoc</a>

Fast, easy and reliable testing for your APIs and microservices.


Pact Go Demo


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

  • Join our community slack workspace.
  • Stack Overflow: https://stackoverflow.com/questions/tagged/pact
  • Say 👋 on Twitter: [@pact_up]

Installation

# install pact-go as a dev dependency
go get github.com/pact-foundation/pact-go/v2

install the pact-go CLI

go install github.com/pact-foundation/pact-go/v2

pact-go will be installed into $GOPATH/bin, which is $HOME/go/bin by default.

download and install the required libraries.

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.

Set PACT_GO_LIB_DOWNLOAD_PATH env var if you have installed the library in a non-standard location.

Pre-Requisites

Pre-Requisites

  • cgo
- Pact relies on C shared libraries compiled from Rust - CGO_ENABLED=1 (check with go env)

Linux

  • Install gcc package

MacOS

  • Install the Xcode Command line tools
By default, pact-go install will attempt to install in /usr/local/lib.

Note this is not user-writable, so pact-go install must be run with sudo.

An alternative is to install to /tmp via pact-go -l DEBUG install --libDir /tmp

Windows

  • Install gcc
- choco install mingw - scoop install mingw
  • Add location of the pact-go installed shared library to
- PATH - CGO_LDFLAGS ##### Powershell
  • $env:Path += ";$env:TMP"
  • $env:CGO_LDFLAGS = "-L$env:TMP"
  • Command Prompt
  • set PATH="%PATH%;%TMP%"
  • set CGO_LDFLAGS="-L%TMP%"

Manual Installation Instructions

Manual

Download the latest Pact FFI Library [library] for your OS, and install onto a standard library search path (we suggest: /usr/local/lib on MacOS/Linux):

Ensure you have the correct extension for your OS:

  • For Mac OS: .dylib (For M1 users, you need the aarch64 version) - ( Called aarch64-apple-darwin in version prior to v0.4.21 )
  • For Linux: .so
  • For Windows: .dll
wget https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v0.4.21/libpact_ffi-macos-x86_64.dylib.gz
gunzip libpact_ffi-macos-x86_64.dylib.gz
mv libpact_ffi-macos-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) {
	// Specify the two applications in the integration we are testing
	// NOTE: this can usually be extracted out of the individual test for re-use)
	mockProvider, err := NewV2Pact(MockHTTPProviderConfig{
		Consumer: "UserAPIConsumer",
		Provider: "UserAPI",
	})
	assert.NoError(t, err)

// Arrange: Setup our expected interactions mockProvider. AddInteraction(). Given("A user with ID 10 exists"). UponReceiving("A request for User 10"). WithRequest("GET", S("/user/10")). WillRespondWith(200). WithBodyMatch(&User{})

// Act: test our API client behaves correctly err = mockProvider.ExecuteTest(t, func(config MockServerConfig) error { // Initialise the API client and point it at the Pact mock server // Pact spins up a dedicated mock server for each test client := newClient(config.Host, config.Port)

// Execute the API client user, err := client.GetUser("10")

// Assert: check the result 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) {
	// 1. Start your Provider API in the background
	go startServer()

verifier := HTTPVerifier{}

// Verify the Provider with local Pact Files // The console will display if the verification was successful or not, the // assertions being made and any discrepancies with the contract err := verifier.VerifyProvider(t, VerifyRequest{ ProviderBaseURL: "http://localhost:1234", PactFiles: []string{ filepath.ToSlash("/path/to/SomeConsumer-SomeProvider.json"), }, })

// Ensure the verification succeeded assert.NoError(t, err) }

!----------

Compatibility

Specification Compatibility

| Version | Stable | [Spec] Compatibility | Install | | ------- | ------ | -------------------- | ------------------ | | 2.0.x | Yes | 2, 3, 4 | See [installation] | | 1.0.x | Yes | 2, 3\* | 1.x.x [1xx] | | 0.x.x | Yes | Up to v2 | 0.x.x [stable] |

_\*_ v3 support is limited to the subset of functionality required to enable language inter-operable [Message support].

Supported Platforms

| OS | Architecture | Supported | Pact-Go Version | | ------------- | ------------ | --------- | ---------------- | | MacOS | x86_64 | ✅ | All | | MacOS | arm64 | ✅ | All | | Linux (libc) | x86_64 | ✅ | All | | Linux (libc) | arm64 | ✅ | All | | Linux (musl) | x86_64 | ✅ | v2.2.0 | | Linux (musl) | arm64 | ✅ | v2.2.0 | | Windows | x86_64 | ✅ | All | | Windows | x86 | ❌ | - | | Windows | arm64 | ❌ | - |

⚠️ - Known issues

- Linux (musl) provider verification is known to experience segmentation faults, reproducible in our CI system.
- Assistance is greatly appreciated if musl support is important to you.

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. Maintainers cutting a release should see RELEASING.


[spec]: https://github.com/pact-foundation/pact-specification [1xx]: https://github.com/pact-foundation/pact-go/ [stable]: https://github.com/pact-foundation/pact-go/tree/release/0.x.x [alpha]: https://github.com/pact-foundation/pact-go/tree/release/1.1.x [troubleshooting]: https://github.com/pact-foundation/pact-go/wiki/Troubleshooting [pact wiki]: https://github.com/pact-foundation/pact-ruby/wiki [getting started with pact]: http://dius.com.au/2016/02/03/microservices-pact/ [pact website]: http://docs.pact.io/ [slack channel]: https://gophers.slack.com/messages/pact/ [@pact_up]: https://twitter.com/pact_up [pact specification v2]: https://github.com/pact-foundation/pact-specification/tree/version-2 [pact specification v3]: https://github.com/pact-foundation/pact-specification/tree/version-3 [library]: https://github.com/pact-foundation/pact-reference/releases [cli tools]: https://github.com/pact-foundation/pact-reference/releases [installation]: #installation [message support]: https://github.com/pact-foundation/pact-specification/tree/version-3#introduces-messages-for-services-that-communicate-via-event-streams-and-message-queues [changelog]: https://github.com/pact-foundation/pact-go/blob/master/CHANGELOG.md [pact broker]: https://github.com/pact-foundation/pact_broker [hosted broker]: pact.dius.com.au [can-i-deploy tool]: https://github.com/pact-foundation/pact_broker/wiki/Provider-verification-results [pactflow]: https://pactflow.io

Chat with me