đī¸ Spin up entire dependency stack
đ Setup initial dependency state â easily!
đ Test against actual, close to production software
âŗ Spend no time writing mocks
đšī¸ Test actual program behavior and side effects
Gnomock is an integration and end-to-end testing toolkit. It uses Docker to create temporary containers for application dependencies, setup their initial state and clean them up in the end. Gnomock allows to test the code with no mocks wherever possible.
The power of Gnomock is in a variety of Presets, each implementing a specific database, service or other tools. Each preset provides ways of setting up its initial state as easily as possible: SQL schema creation, test data upload into S3, sending test events to Splunk, etc.
The name "Gnomock" stands for "no mock", with a "G" for "Go" đŧ. It also sounds like "gnome", that's why the friendly garden gnome artwork (by Michael Zolotov)
See for yourself how easy and fast it is to write tests that use actual services running in ephemeral Docker containers:
Gnomock can be used in two different ways:
Both ways require an active Docker daemon running locally in the same environment.
External DOCKER_HOST
support is experimental. It cannot be reliably tested at this moment, but it might work.
See the following example to get started:
go get github.com/orlangure/gnomock
Setting up a Postgres container with schema setup example:
package db_test
import (
"database/sql"
"fmt"
"testing"
_ "github.com/lib/pq" // postgres driver
"github.com/orlangure/gnomock"
"github.com/orlangure/gnomock/preset/postgres"
)
func TestDB(t *testing.T) {
p := postgres.Preset(
postgres.WithUser("gnomock", "gnomick"),
postgres.WithDatabase("mydb"),
postgres.WithQueriesFile("/var/project/db/schema.sql"),
)
container, _ := gnomock.Start(p)
t.Cleanup(func() { _ = gnomock.Stop(container) })
connStr := fmt.Sprintf(
"host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
container.Host, container.DefaultPort(),
"gnomock", "gnomick", "mydb",
)
db, _ := sql.Open("postgres", connStr)
// db has the required schema and data, and is ready to use
}
See package reference. For Preset documentation, refer to Presets section.
If you use Go, please refer to Using Gnomock in Go applications section. Otherwise, refer to documentation.
The power of Gnomock is in the Presets. Existing Presets with their supported* versions are listed below.
* Supported versions are tested as part of CI pipeline. Other versions might work as well.
Preset | Go package | Go API | Supported versions | arm64 |
---|---|---|---|---|
Localstack (AWS) | Go package | Reference | 0.12.2 , 0.13.1 , 0.14.0 , 2.3.0 , 3.1.0 |
â |
Splunk | Go package | Reference | 8.0.2 |
â |
Redis | Go package | Reference | 5.0.10 , 6.0.9 , 7.2.4 |
â |
Memcached | Go package | Reference | 1.6.9 , 1.6.23 |
â |
MySQL | Go package | Reference | 5.7.32 , 8.0.22 |
â |
MariaDB | Go package | Reference | 10.5.8 , 11.2.2 |
â |
PostgreSQL | Go package | Reference | 10.15 , 11.10 , 12.5 , 13.1 , 14.11 , 15.6 , 16.2 |
â |
Microsoft SQL Server | Go package | Reference | 2017-latest , 2019-latest |
â |
MongoDB | Go package | Reference | 3.6.21 , 4.4 , 5.0 |
â |
RabbitMQ | Go package | Reference | 3.8.9-alpine , 3.8.9-management-alpine , 3.13-alpine |
â |
Kafka | Go package | Reference | 3.3.1-L0 , 3.6.1-L0 |
â |
Elasticsearch | Go package | Reference | 8.13.0 , 7.17.21 |
â |
Kubernetes | Go package | Reference | v1.26.3-k3s1 |
â |
CockroachDB | Go package | Reference | v19.2.11 , v20.1.10 , v21.2.17 , v22.2.19 , v23.1.20 |
â |
InfluxDB | Go package | Reference | 2.7.6-alpine |
â |
Cassandra | Go package | Reference | 4.0 , 3 |
â |
Vault | Go package | Reference | 1.10 , 1.11 , 1.12 , 1.13 |
â |
Azurite | Go package | Reference | 3.30.0 |
â |
It is possible to use Gnomock directly from Go code without any presets. HTTP API only allows to setup containers using presets that exist in this repository.
Gnomock is not the only project that aims to simplify integration and end-to-end testing by using ephemeral docker containers:
testcontainers/testcontainers-go
ory/dockertest
These projects are amazing, and they give plenty of flexibility and power to their users. There are many things that are possible with them, but are impossible with Gnomock. Still, below is a short list of things that sometimes give Gnomock an advantage:
It happens a lot locally if your internet isn't fast enough to pull docker images used in tests. In CI, such as in Github Actions, the images are downloaded very quickly. To work around this issue locally, pull the image manually before running the tests. You only need to do it once, the images stay in local cache until deleted. For example, to pull Postgres 11 image, run:
docker pull postgres:11
It can happen if the containers can't become ready to use before they time out. By default, Gnomock uses fairly high timeouts for new containers (for starting and for setting them up). If you choose to change default timeout using WithTimeout
(timeout
in HTTP), it is possible that the values you choose are too short.
It happens when you try to start up a lot of containers at the same time. The system, especially in CI environments such as Github Actions, cannot handle the load, and containers fail to become healthy before they time-out. That's the reason Gnomock has a few separate build jobs, each running only a small subset of tests, one package at a time.
If you run gnomock
as a server, you need to make sure the files you use in your setup are available inside gnomock
container. Use -v $(pwd):$(pwd)
argument to docker run
to mount the current working directory under the same path inside the gnomock
container. If you prefer to keep a permanent gnomock
container running, you can mount your entire $HOME
directory (or any other directory where you keep the code).
This is a free and open source project that hopefully helps its users, at least a little. Even though I don't need donations to support it, I understand that there are people that wish to give back anyway. If you are one of them, I encourage you to plant some trees with Tree Nation đ˛ đŗ đ´
If you want me to know about your contribution, make sure to use orlangure+gnomock@gmail.com
as the recipient email.
Thank you!