2024-12-19 10:10:15 +00:00
---
sidebar_position: 8
2025-01-13 13:48:29 +00:00
title: Testcontainers with Podman
description: Learn how to use Testcontainers with Podman and how to create basic tests using Testcontainers technology!
2025-01-17 07:52:50 +00:00
keywords: [podman, podman-desktop, containers, testcontainers]
tags: [podman, podman-desktop, containers, testcontainers, tests]
2024-12-19 10:10:15 +00:00
---

2025-01-13 13:48:29 +00:00
# What are Testcontainers
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
[Testcontainers ](https://testcontainers.com/ ) is an open source library that allows you to test any containerized dependencies, such as databases, various cloud technologies, or message brokers. For ease of use, Testcontainers has many preconfigured dependencies called modules.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
Besides that, Testcontainers supports various languages in which you can easily write your tests, such as Python, Go, Rust, Ruby, JavaScript, .NET, Java, and others.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
## Common use cases with Testcontainers
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
Thanks to the container technology, you can obtain fresh, clean instances without any complex setup for use cases such as:
2024-12-19 10:10:15 +00:00
- Data access layer integration tests
- UI/Acceptance tests
- Application integration tests
2025-01-13 13:48:29 +00:00
## Setup Testcontainers with Podman
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
Before we start, you need to have installed [Podman ](https://podman.io/ ) and run it in socket listening:
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```shell
2025-01-13 13:48:29 +00:00
$ podman system service --time=0 &
2024-12-19 10:10:15 +00:00
```
2025-01-17 07:52:50 +00:00
Set Testcontainers runtime to Podman by using one of the following options:
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
- Enable the [Docker Compatibility ](https://podman-desktop.io/docs/migrating-from-docker/managing-docker-compatibility ) feature.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
- Create a `.testcontainers.properties` file in your home directory for global configuration of your Testcontainers and add the following line to the configuration file:
2025-01-15 14:14:20 +00:00
- MacOS
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```title=".testcontainers.properties"
2025-01-15 14:14:20 +00:00
docker.host=unix://$(podman machine inspect --format '{{.ConnectionInfo.PodmanSocket.Path}}')
```
2025-01-17 07:52:50 +00:00
Run the following command after configuration:
2025-01-15 14:14:20 +00:00
2025-01-17 07:52:50 +00:00
```bash
2025-01-15 14:14:20 +00:00
$ export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock
```
- Linux:
2025-01-17 07:52:50 +00:00
```title=".testcontainers.properties"
2025-01-15 14:14:20 +00:00
docker.host=unix://${XDG_RUNTIME_DIR}/podman/podman.sock
```
2025-01-17 07:52:50 +00:00
:::note
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
Every language supported by Testcontainers has different properties supported by the .testcontainers.properties file.
:::
> **_OPTIONAL:_** If you are running Podman in rootless mode, you must disable Ryuk by defining this environment variable:
2025-01-13 13:48:29 +00:00
>
2025-01-17 07:52:50 +00:00
> ```bash
2025-01-15 14:14:20 +00:00
> $ export TESTCONTAINERS_RYUK_DISABLED=true
2025-01-13 13:48:29 +00:00
> ```
## Creating a project
2024-12-19 10:10:15 +00:00
2025-01-13 13:48:29 +00:00
This example uses the Redis service and Redis module from Testcontainers. You can create a project and install all the dependencies by following the procedure.
2024-12-19 10:10:15 +00:00
2025-01-13 13:48:29 +00:00
1. Initialize a project.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```bash
2025-01-15 14:14:20 +00:00
$ npm init -y
```
2024-12-19 10:10:15 +00:00
2025-01-13 13:48:29 +00:00
2. Installing dependencies.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```bash
$ npm install testcontainers vitest @testcontainers/redis redis typescript --save-dev
2025-01-15 14:14:20 +00:00
```
2024-12-19 10:10:15 +00:00
2025-01-13 13:48:29 +00:00
3. Update `package.json` file.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```json title="package.json"
2025-01-15 14:14:20 +00:00
...
"scripts": {
"test": "vitest"
},
...
```
2024-12-19 10:10:15 +00:00
2025-01-13 13:48:29 +00:00
4. Create basic CRUD operations using the Redis Node.js library.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```ts title="index.ts"
2025-01-15 14:14:20 +00:00
import { createClient, RedisClientType } from 'redis';
let redisClient: RedisClientType | undefined = undefined;
export async function connectRedis(url: string) {
2025-01-17 07:52:50 +00:00
redisClient = createClient({ url });
await redisClient.connect();
return redisClient;
2025-01-15 14:14:20 +00:00
}
export async function setValue(key: string, value: string): Promise< string | null > {
2025-01-17 07:52:50 +00:00
if (!redisClient) {
throw new Error('Redis client is not connected');
}
return await redisClient.set(key, value);
2025-01-15 14:14:20 +00:00
}
export async function getValue(key: string): Promise< string | null > {
2025-01-17 07:52:50 +00:00
if (!redisClient) {
throw new Error('Redis client is not connected');
}
return redisClient.get(key);
2025-01-15 14:14:20 +00:00
}
export async function deleteValue(key: string[]): Promise< number > {
2025-01-17 07:52:50 +00:00
if (!redisClient) {
throw new Error('Redis client is not connected');
}
return await redisClient.del(key);
2025-01-15 14:14:20 +00:00
}
export async function disconnectRedis() {
2025-01-17 07:52:50 +00:00
if (redisClient) {
await redisClient.quit();
redisClient = undefined;
}
2025-01-15 14:14:20 +00:00
}
```
2024-12-19 10:10:15 +00:00
2025-01-13 13:48:29 +00:00
5. Create basic tests for CRUD operations.
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```ts title="index.spec.ts"
import { afterAll, beforeAll, beforeEach, expect, test } from 'vitest';
import { connectRedis, deleteValue, disconnectRedis, getValue, setValue } from '.';
import { RedisContainer, StartedRedisContainer } from '@testcontainers/redis';
import { Wait } from 'testcontainers';
import { createClient } from 'redis';
2025-01-15 14:14:20 +00:00
let container: StartedRedisContainer;
beforeAll(async () => {
2025-01-17 07:52:50 +00:00
container = await new RedisContainer()
.withExposedPorts(6379)
.withWaitStrategy(Wait.forLogMessage('Ready to accept connections'))
.start();
2025-01-15 14:14:20 +00:00
2025-01-17 07:52:50 +00:00
await connectRedis(`redis://localhost:${container.getMappedPort(6379)}`);
2025-01-15 14:14:20 +00:00
});
afterAll(async () => {
2025-01-17 07:52:50 +00:00
await disconnectRedis();
2025-01-15 14:14:20 +00:00
});
beforeEach(async () => {
2025-01-17 07:52:50 +00:00
// Flushind DB and adding to Redis some values before each test
const client = createClient({ url: `redis://localhost:${container.getMappedPort(6379)}` });
await client.connect();
await client.flushDb();
await client.set('preset-key', 'preset-value');
await client.set('preset-key1', 'preset-value1');
await client.quit();
2025-01-15 14:14:20 +00:00
});
2025-01-17 07:52:50 +00:00
test('set value on server', async () => {
// Set value
const ret = await setValue('key', 'value');
expect(ret).toBe('OK');
2025-01-15 14:14:20 +00:00
2025-01-17 07:52:50 +00:00
// Update value
const ret1 = await setValue('key', 'updated-value');
expect(ret1).toBe('OK');
2025-01-15 14:14:20 +00:00
});
2025-01-17 07:52:50 +00:00
test('get value from server', async () => {
// Get preset value
const value = await getValue('preset-key');
expect(value).toBe('preset-value');
2025-01-15 14:14:20 +00:00
2025-01-17 07:52:50 +00:00
// Get not existing value
const value1 = await getValue('key');
expect(value1).toBeNull();
2025-01-15 14:14:20 +00:00
});
2025-01-17 07:52:50 +00:00
test('delete value on server', async () => {
// Delete two records in a same time
const res = await deleteValue(['preset-key', 'preset-key1']);
expect(res).toBe(2);
2025-01-15 14:14:20 +00:00
2025-01-17 07:52:50 +00:00
// Delete not existing record
const res1 = await deleteValue(['key']);
expect(res1).toBe(0);
2025-01-15 14:14:20 +00:00
});
```
2024-12-19 10:10:15 +00:00
## Running tests
2025-01-13 13:48:29 +00:00
When running Testcontainers for the first time, ensure that you run your tests in `DEBUG` mode by using this command:
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```bash
2024-12-19 10:10:15 +00:00
$ DEBUG=testcontainers* npm test
```
2025-01-13 13:48:29 +00:00
Then, you should be able to see lines similar to the ones below:
2024-12-19 10:10:15 +00:00
2025-01-17 07:52:50 +00:00
```
2024-12-19 10:10:15 +00:00
testcontainers [DEBUG] Loading ".testcontainers.properties" file...
testcontainers [DEBUG] Loaded ".testcontainers.properties" file
testcontainers [DEBUG] Found custom configuration: dockerHost: "unix:///run/user/1000//podman/podman.sock
```
2025-01-17 07:52:50 +00:00
Those lines indicate that Testcontainers found the configuration file, and the containers are created on the Podman engine instead of Docker.
2025-01-13 13:48:29 +00:00
## Conclusion
This tutorial provides a basic step-by-step walkthrough using the Testcontainers technology to run a [Redis ](https://redis.io/ ) server with Podman. More examples can be found in the guides of [Testcontainers ](https://testcontainers.com/guides/ ). If you encounter any problems, feel free to open an issue on Podman Desktop's [GitHub ](https://github.com/podman-desktop/podman-desktop/issues ).