roynalnaruto

roynalnaruto

Best Practice for testing database?

Hello. I am writing my first server in elixir, and I am using the influxDB for storing time series data. So far I have enjoyed programming in elixir. But I am struggling to test my system.

I have read this article: Mocks and explicit contracts « Plataformatec Blog
and it did help me write Mock modules for HTTP servers (for some HTTP requests my server makes) in order to test my GET/POST queries.

But I am struggling to understand how I can simulate my database by creating a mock module. If I decide to do that, I will also have to parse the SQL queries, so that the Mock supports all sorts of queries that I may wish to add in future (and also to make the Mock re-usable for anybody else who wants to test it the way I do).

The other way (simpler/less time consuming) is to simply have the DB run in the background while running tests. And create a different database for test purposes. But is this bad test design?

What are the best practices for testing database queries in elixir? And can somebody point me to an article, github project, etc. where I can refer it and learn?

Thank you.

Most Liked

aenglisc

aenglisc

Personally, I like setting up a docker environment.

An example from a pet project:

docker-compose.yml

version: '3.3'

services:

  app:
    build:
      context: .
      dockerfile: Dockerfile
    working_dir: /app
    command: 'mix phx.server'
    ports:
      - '4000:4000'
    volumes:
      - '~/.bash-history:/.bash-history'
      - '.:/app:cached'
      - '/tmp:/tmp:delegated'
      - '.bashrc:/root/.bashrc:cached'
      - '/var/run/docker.sock:/var/run/docker.sock:cached'
      - '/var/tmp:/var/tmp:cached'
      - '/tmp:/tmp:cached'
    depends_on:
      - db

  db:
    image: postgres:11-alpine
    volumes:
      - 'pgdata:/var/lib/postgres/data'

volumes:
  pgdata:

Makefile

start:
	docker-compose up -d

stop:
	docker-compose down

build:
	docker-compose build app

shell:
	docker-compose run --rm app bash

install:
	docker-compose run --rm app mix deps.get

install-assets:
	docker-compose run --rm app bash -c "cd assets && npm install && node node_modules/webpack/bin/webpack.js --mode development"

compile:
	docker-compose run --rm app bash -c "mix do compile, phx.digest"

db-setup:
	docker-compose run --rm app mix ecto.setup

db-reset:
	docker-compose run --rm app mix ecto.reset

start-interactive:
	docker-compose run --rm --service-ports app iex -S mix phx.server

test:
	docker-compose run --rm app mix test

setup: build install install-assets compile db-setup

.PHONY: test
LostKobrakai

LostKobrakai

The difficulty lies in the details.

If you can assert correctness purely based on the query alone you could use a mock, but at least for SQL this is really hard as even simple changes in the order of building up a query are likely to make the logic of comparing a query fail, but could very well still result in the same proper results when handled by an actual db. Such differences defeat the purpose of a testsuite allowing you to refactor safely; Or you’d need to basically reimplement the db’s query engine. This is different to e.g. a mocked API (which is the subject of the blogpost), as the inputs there are likely to be way less complex to assert against than sql.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

This is very normal, and is also the way that people test when using Postgres as a database.

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement