I have learned that using an actual database in integration tests slows them down significantly. So, I have to use an in memory database which may significantly increase speed of my integration tests.
I'm using Springboot for application development. How do I configure PostgreSQL for testing purposes? Is there any in memory database which is highly compatible with PostgreSQL's syntax?
If there is none, how should I perform integration tests.
You can actually get a real Postgres to perform quiet well in a testing environment.
I would also suggest you use a dockerized database, but use tmpfs to memory-map the data folder:
docker run --name postgres95 -p 5432:5432 --tmpfs /var/lib/postgresql/data:rw -e POSTGRES_PASSWORD=admin -d postgres:9.5.6
This is as close to "in-memory" that you can get using the real thing.
I believe that one of the main problems with slow integration tests is not the performance of the database itself, but the time it takes to set it up for each test.
I wrote a little library to help you quickly restore a database to a 'clean' state. This way you only need to run costly database migrations once, and then you can quickly restore the database for each test.
We used it in a productive system to get a 4x speedup in our integration tests:
https://github.com/ayedo/postgres-db-restore
Some of my db tests on real postgres take 10ms each. and i do multiple commits in each test. so:
To have coverage of postgres-native features you need the same db (as you noticed, h2 and other in-memory db are not very compatible). postgres doesn't have in-memory mode. For functional tests the real database itself is not much slower than any in-memory databases. The difference usually lies in startup time (for postgres 9.6 it's ~4s). But if your testing lifecycle is smart and you can lower number of db starts to 1 or 0 (by having development db always ready), then the problem stops being noticeable.
so get the real postgres and setup its lifecycle correctly. there are some tools that can help you solve some of the problems:
testcontainers will help you provide real db.
dbunit - will help you clean the data between tests
cons:
testegration - intents to provide you full, ready to use and extensible lifecycle (disclosure: i'm a creator).
cons:
another step would be to move db to memory on the OS level. again, first startup time would be similar as everything needs to be loaded. some starting points here and here
cons:
This question asks for opinions, but here goes:
If you want to test an application that will use PostgreSQL, you will have to use PostgreSQL for your tests. SQL dialects and behaviour just vary too much between different database management systems.
You can make PostgreSQL quite fast if you use a database that is small enough to fit into RAM, which should be possible for integration tests that just target the functionality, not the overall performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With