Hacker News new | ask | show | jobs
by c0balt 841 days ago
Going to the sections for language interactions shows a lot more stuff, e.g., the first full go example: https://testcontainers.com/guides/getting-started-with-testc...

Shows how you can embed the declaration of db for testing in a unit test:

> pgContainer, err := postgres.RunContainer(ctx, > testcontainers.WithImage("postgres:15.3-alpine"), > postgres.WithInitScripts(filepath.Join("..", "testdata", "init-db.sql")), > postgres.WithDatabase("test-db"), > postgres.WithUsername("postgres"), > postgres.WithPassword("postgres"), > testcontainers.WithWaitStrategy( > wait.ForLog("database system is ready to accept connections").

This does look quite neat for setting up test specific database instances instead of spawning one outside of the test context with docker(compose). It should also make it possible to run tests that require their own instance in parallel.

2 comments

On Hacker News you need to indent code examples with four spaces - like this:

    pgContainer, err := postgres.RunContainer(
        ctx, testcontainers.WithImage("postgres:15.3-alpine"
    ),
    postgres.WithInitScripts(filepath.Join("..", "testdata", "init-db.sql")),
     postgres.WithDatabase("test-db"),
     postgres.WithUsername("postgres"),
     postgres.WithPassword("postgres"),
     testcontainers.WithWaitStrategy(
      wait.ForLog("database system is ready to accept connections").
And, to quote non-code text, you have to do it manually; there is no formatting operator and the code-indent method won’t work (unreadable at many browser widths). I tend to do it like so:

> *Paragraph one.*

> *Paragraph two. Etc.*

Which produces the desired effect:

> Paragraph ‘one’.

> Paragraph two.

(To use a * in a paragraph that’s italic-wrapped, backslash it.)

This seems great but is actually quite slow. This will create a new container, with a new postgres server, and a new database in that server, for each test. You'll then need to run migrations in that database. This ends up being a huge pain in the ass.

A better approach is to create a single postgres server one-time before running all of your tests. Then, create a template database on that server, and run your migrations on that template. Now, for each unit test, you can connect to the same server and create a new database from that template. This is not a pain in the ass and it is very fast: you run your migrations one time, and pay a ~20ms cost for each test to get its own database.

I've implemented this for golang here — considering also implementing this for Django and for Typescript if there is enough interest. https://github.com/peterldowns/pgtestdb