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

PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

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
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49134 226
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
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
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

We're in Beta

About us Mission Statement