diff --git a/docs/INTEGRATION_TESTS.md b/docs/INTEGRATION_TESTS.md
index ef76332951ca9..734d596aecab8 100644
--- a/docs/INTEGRATION_TESTS.md
+++ b/docs/INTEGRATION_TESTS.md
@@ -1,62 +1,79 @@
# Integration Tests
-To run our current integration test suite:
+## Running
-Running the integration tests requires several docker containers to be
-running. You can start the containers with:
+To run all named integration tests:
```shell
-docker-compose up
+make test-integration
```
-To run only the integration tests use:
+To run all tests, including unit and integration tests:
```shell
-make test-integration
+go test -count 1 -race ./...
+```
+
+## Developing
+
+To run integration tests against a service the project uses
+[testcontainers][1]. The makes it very easy to create and cleanup
+container-based tests.
+
+The `testutil/container.go` has a `Container` type that wraps this project to
+easily create containers for testing in Telegraf. A typical test looks like
+the following:
+
+```go
+servicePort := "5432"
+
+container := testutil.Container{
+ Image: "postgres:alpine",
+ ExposedPorts: []string{servicePort},
+ Env: map[string]string{
+ "POSTGRES_HOST_AUTH_METHOD": "trust",
+ },
+ WaitingFor: wait.ForAll(
+ wait.ForLog("database system is ready to accept connections"),
+ wait.ForListeningPort(nat.Port(servicePort)),
+ ),
+}
+
+err := container.Start()
+require.NoError(t, err, "failed to start container")
+
+defer func() {
+ require.NoError(t, container.Terminate(), "terminating container failed")
+}()
```
-Use `make docker-kill` to stop the containers.
-
-Contributing integration tests:
-
-- Add Integration to the end of the test name so it will be run with the above command.
-- Writes tests where no library is being used in the plugin
-- There is poor code coverage
-- It has dynamic code that only gets run at runtime eg: SQL
-
-Current areas we have integration tests:
-
-| Area | What it does |
-|------------------------------------|-------------------------------------------|
-| Inputs: Aerospike | |
-| Inputs: Disque | |
-| Inputs: Dovecot | |
-| Inputs: Mcrouter | |
-| Inputs: Memcached | |
-| Inputs: Mysql | |
-| Inputs: Opcua | |
-| Inputs: Openldap | |
-| Inputs: Pgbouncer | |
-| Inputs: Postgresql | |
-| Inputs: Postgresql extensible | |
-| Inputs: Procstat / Native windows | |
-| Inputs: Prometheus | |
-| Inputs: Redis | |
-| Inputs: Sqlserver | |
-| Inputs: Win perf counters | |
-| Inputs: Win services | |
-| Inputs: Zookeeper | |
-| Outputs: Cratedb / Postgres | |
-| Outputs: Elasticsearch | |
-| Outputs: Kafka | |
-| Outputs: MQTT | |
-| Outputs: Nats | |
-| Outputs: NSQ | |
-
-Areas we would benefit most from new integration tests:
-
-| Area |
-|------------------------------------|
-| SNMP |
-| MYSQL |
-| SQLSERVER |
+The `servicePort` is the port the service is running on and Telegraf will
+connect to. When the port is specified as a single value (e.g. `11211`) then
+testcontainers will generate a random port for the service to start on. This
+way multiple tests can be run and prevent ports from conflicting.
+
+The `test.Container` type requires at least the following three items:
+
+1. An image name from [DockerHub][2], which can include a specific tag or not
+2. An array of port(s) to expose to the test to connect to
+3. A wait stanza. This lays out what testcontainers will wait for to determine
+ that the container has started and is ready for use by the test. It is best
+ to provide not only a port, but also a log message. Ports can come up very
+ early in the container, and the service may not be ready.
+
+There are other optional parameters like `Env` to pass environmental variables
+to the container or `BindMounts` to pass test data into the container as well.
+
+User's should start the container and then defer termination of the container.
+
+[1]: "testcontainers-go"
+[2]: "DockerHub"
+
+## Contributing
+
+When adding integrations tests please do the following:
+
+- Add integration to the end of the test name
+- Use testcontainers when an external service is required
+- Use the testutil.Container to setup and configure testcontainers
+- Ensure the testcontainer wait stanza is well-tested