DEV Community

Cover image for πŸš€ Level up your testing game with TestContainers
Yashodhan Singh
Yashodhan Singh

Posted on

πŸš€ Level up your testing game with TestContainers

As software developers, writing tests is an important part of our daily routine. We need to make sure our code works as expected and can handle different scenarios. One important aspect of testing is to make sure our code interacts with databases correctly. However, testing with a real database can be a challenge. It can be time-consuming to set up, difficult to manage, and may have unintended consequences.

That's where TestContainers comes in! πŸŽ‰

TestContainers is an open-source library that allows you to run containers for your tests. With TestContainers, you can spin up a database container in seconds, run your tests, and dispose of the container. It eliminates the hassle of setting up a real database, and ensures that your tests are isolated and repeatable.

Let's see how we can use TestContainers to test our code that interacts with databases.

πŸ’‘ Simple Example:

Let's start with a simple example. We'll use TestContainers to run a PostgreSQL database and write tests to insert and retrieve data from the database. First, we need to install TestContainers and the PostgreSQL client:

npm install --save-dev testcontainers jest pg
Enter fullscreen mode Exit fullscreen mode

Next, let's write the tests:

const { GenericContainer } = require('testcontainers');
const Client = require('pg').Client;

describe('Test database', () => {
  let client;
  let container;

  beforeAll(async () => {
    container = await new GenericContainer('postgres', '12')
      .withEnv('POSTGRES_USER', 'postgres')
      .withEnv('POSTGRES_PASSWORD', 'secret')
      .withExposedPorts(5432)
      .start();

    const host = await container.getContainerIpAddress();
    const port = container.getMappedPort(5432);
    const password = 'secret';
    const database = 'testdb';

    client = new Client({
      host,
      port,
      user: 'postgres',
      password,
      database,
    });

    await client.connect();
  });

  afterAll(async () => {
    await client.end();
    await container.stop();
  });

  test('Insert data into the database', async () => {
    await client.query('CREATE TABLE test (id serial, message text)');
    const res = await client.query("INSERT INTO test (message) values ('hello world')");
    expect(res.rowCount).toBe(1);
  });

  test('Retrieve data from the database', async () => {
    const res = await client.query('SELECT * FROM test');
    expect(res.rows[0].message).toBe('hello world');
  });
});

Enter fullscreen mode Exit fullscreen mode

In this example, we use the beforeAll hook to start the PostgreSQL container and connect to the database. The afterAll hook stops the container and closes the connection. In the tests, we use the client to interact with the database.

πŸŽ‰ Conclusion:

TestContainers is a fantastic tool for testing code that interacts with databases. It makes it easy to spin up a container, run your tests, and dispose of the container. With TestContainers, you can ensure that your tests are isolated, repeatable, and fast. Give it a try, and level up your testing game! πŸš€

Check out the TestContainers library here: TestContainers on GitHub

Let me know if you have any questions or feedback! 😊

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay