• Stars
    star
    254
  • Rank 160,264 (Top 4 %)
  • Language
    Go
  • License
    Other
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Regression Testing your SQL queries

RegreSQL, Regression Testing your SQL queries

The regresql tool implement a regression testing facility for SQL queries, and supports the PostgreSQL database system. A regression test allows to ensure known results when the code is edited. To enable that we need:

  • some code to test, here SQL queries, each in its own file,
  • a known result set for each SQL query,
  • a regression driver that runs queries again and check their result against the known expected result set.

The RegreSQL tool is that regression driver. It helps with creating the expected result set for each query and then running query files again to check that the results are still the same.

Of course, for the results the be comparable the queries need to be run against a known PostgreSQL database content.

Installing

The regresql tool is written in Go, so:

go get github.com/dimitri/regresql

This command will compile and install the command in your $GOPATH/bin, which defaults to ~/go/bin. See https://golang.org/doc/install if you're new to the Go language.

Basic usage

Basic usage or regresql:

  • regresql init [ -C dir ]

    Creates the regresql main directories and runs all SQL queries found in your target code base (defaults to current directory).

    The -C option changes current directory to dir before running the command.

  • regresql plan [ -C dir ]

    Create query plan files for all queries. Run that command when you add new queries to your repository.

  • regresql update [ -C dir ]

    Updates the expected files from the queries, considering that the output is valid.

  • regresql test [ -C dir ]

    Runs all the SQL queries found in current directory.

    The -C option changes the current directory before running the tests.

  • regresql list [ -C dir ]

    List all SQL files found in current directory.

    The -C option changes the current directory before listing the files.

SQL query files

RegreSQL finds every .sql file in your code repository and runs them against PostgreSQL. It means you're supposed to maintain your queries as separate query files, see the excellent https://github.com/krisajenkins/yesql Clojure library to see how that's done. The project links to many implementation in other languages, including Python, PHP or Go.

SQL files might contain variables, and RegreSQL implements the same support for them as psql, see the PostgreSQL documentation about psql variables and their usage syntax and quoting rules: :foo, :'foo' and :"foo".

Test Suites

By default a Test Suite is a source directory.

File organisation

RegreSQL needs the following files and directories to run:

  • ./regresql where to register needed files

  • ./regresql/regresql.yaml

    Configuration file for the directory in which it's installed. It contains the PostgreSQL connection string where to connect to for running the regression tests and the top level directory where to find the SQL files to test against.

  • ./regresql/expected/path/to/query.yaml

    For each file query.sql found in your source tree, RegreSQL creates a subpath in ./regresql/plans with a query.yaml file. This YAML file contains query plans: that's a list of SQL parameters values to use when testing.

  • ./regresql/expected/path/to/query.out

    For each file query.sql found in your source tree, RegreSQL creates a subpath in ./regresql/expected directory and stores in query.out the expected result set of the query,

  • ./regresql/out/path/to/query.sql

    The result of running the query in query.sql is stored in query.out in the regresql/out directory subpath for it, so that it is possible to compare this result to the expected one in regresql/expected.

Example

In a small local application the command regresql list returns the following SQL source files:

$ regresql list
.
  src/sql/
    album-by-artist.sql
    album-tracks.sql
    artist.sql
    genre-topn.sql
    genre-tracks.sql

After having done the following commands:

$ regresql init postgres:///chinook?sslmode=disable
...

$ regresql update
...

Now we have to edit the YAML plan files to add bindings, here's an example for a query using a single parameter, :name:

$ cat src/sql/album-by-artist.sql
-- name: list-albums-by-artist
-- List the album titles and duration of a given artist
  select album.title as album,
         sum(milliseconds) * interval '1 ms' as duration
    from album
         join artist using(artistid)
         left join track using(albumid)
   where artist.name = :name
group by album
order by album;

$ cat regresql/plans/src/sql/album-by-artist.yaml 
"1":
  name: "Red Hot Chili Peppers"

And we can now run the tests:

$ regresql test
Connecting to 'postgres:///chinook?sslmode=disable'… ✓
TAP version 13
ok 1 - src/sql/album-by-artist.1.out
ok 2 - src/sql/album-tracks.1.out
ok 3 - src/sql/artist.1.out
ok 4 - src/sql/genre-topn.top-3.out
ok 5 - src/sql/genre-topn.top-1.out
ok 6 - src/sql/genre-tracks.out

We can see the following files have been created by the RegreSQL tool:

$ tree regresql/
regresql/
├── expected
│   └── src
│       └── sql
│           ├── album-by-artist.1.out
│           ├── album-tracks.1.out
│           ├── artist.1.out
│           ├── genre-topn.1.out
│           ├── genre-topn.top-1.out
│           ├── genre-topn.top-3.out
│           └── genre-tracks.out
├── out
│   └── src
│       └── sql
│           ├── album-by-artist.1.out
│           ├── album-tracks.1.out
│           ├── artist.1.out
│           ├── genre-topn.1.out
│           ├── genre-topn.top\ 1.out
│           ├── genre-topn.top\ 3.out
│           ├── genre-topn.top-1.out
│           ├── genre-topn.top-3.out
│           └── genre-tracks.out
├── plans
│   └── src
│       └── sql
│           ├── album-by-artist.yaml
│           ├── album-tracks.yaml
│           ├── artist.yaml
│           └── genre-topn.yaml
└── regress.yaml

9 directories, 21 files

History

This tool is inspired by the PostgreSQL regression testing framework. It's been written in the process of the Mastering PostgreSQL book as an example of an SQL framework for unit testing and regression testing.

License

The RegreSQL utility is released under The PostgreSQL License.

More Repositories

1

pgloader

Migrate to PostgreSQL in a single command!
Common Lisp
5,353
star
2

el-get

Manage the external elisp bits and pieces upon which you depend!
Emacs Lisp
1,646
star
3

pgcopydb

Copy a Postgres database to a target Postgres server (pg_dump | pg_restore on steroids)
C
1,159
star
4

pgcharts

Turn your PostgreSQL queries into Charts
Common Lisp
393
star
5

switch-window

Offer a *visual* way to choose a window to switch to
Emacs Lisp
288
star
6

emacs-kicker

A minimal kick start init file for emacs
Emacs Lisp
145
star
7

prefix

Prefix Range module for PostgreSQL
C
98
star
8

pgextwlist

PostgreSQL Extension Whitelisting
C
94
star
9

sudoku

Solving Every Sudoku Puzzle
Python
58
star
10

preprepare

PostgreSQL prepare statements made pooling friendly
C
45
star
11

tpch-citus

Drivers to run TPC-H with Citus and PostgreSQL
C
31
star
12

nba

Aggregating NBA data
Common Lisp
30
star
13

pg_staging

Setup and maintain your staging environments from your production backups!
Python
28
star
14

cssh

ClusterSSH meets Emacs
Emacs Lisp
27
star
15

cl-abnf

ABNF Parser Generator, per RFC2234
Common Lisp
27
star
16

pgdevenv-el

PostgreSQL Development Tool for Emacs
Emacs Lisp
23
star
17

ql-to-deb

Update cl-* debian packages from Quicklisp releases.
Common Lisp
23
star
18

mbsync-el

Wrap calling mbsync in Emacs Lisp, with a gnus hook
Emacs Lisp
23
star
19

libphp-pgq

PHP level API for PGQ PostgreSQL Queing solution
PHP
17
star
20

pg_basebackup

Make your PostgreSQL base backup from a plain connection to the server (as superuser)
Python
17
star
21

kids

Helping kids discover computing
Common Lisp
16
star
22

base36

PostgreSQL base36 data type input/output support, internally a bigint.
C
14
star
23

getddl

Get the DDL from a live database and split them in files and directories
Python
14
star
24

apt.postgresql.org

debian packaging scripts for PostgreSQL.org
Shell
13
star
25

tapoueh.org

Sources of the tapoueh.org web site, using Hugo
HTML
13
star
26

taop.xyz

The Art of PostgreSQL
HTML
13
star
27

pginstall

The PostgreSQL Extension Installer
Common Lisp
11
star
28

emacs.d

My Emacs Setup
Emacs Lisp
9
star
29

pgsql-linum-format

a linum-mode hook to display PostgreSQL functions line numbers
Emacs Lisp
8
star
30

pgconfs

dim's PostgreSQL Conferences Slides, the sources.
PostScript
8
star
31

cl-db3

A Common Lisp lib to read dbf files version 3.
Common Lisp
7
star
32

pubnames

The Most Popular Pub Names
Common Lisp
7
star
33

subcommands.c

Another single-file header C lib: command line, file paths manipulation API, run subprograms.
C
7
star
34

AdventOfCode

Implementation of Advent Of Code puzzles in Common Lisp, just for fun.
Common Lisp
7
star
35

masteringpostgresql.com

My new book, still in the making.
CSS
7
star
36

plconvert

Convert code in between non standard database Procedural Languages.
Common Lisp
6
star
37

mailq-el

Emacs major mode for `mailq' interaction
Emacs Lisp
5
star
38

toy-parser

How to build a parser and have a compiler for free, in Common Lisp.
Common Lisp
5
star
39

mysqltopgsql.com

How to migrate from MySQL to PostgreSQL
HTML
5
star
40

pgsrc-el

PostgreSQL source editing facilities for Emacs
Emacs Lisp
3
star
41

rcirc-groups

an emacs buffer in rcirc-groups major mode
Emacs Lisp
3
star
42

cl-ixf

Parse IBM IXF file format.
Common Lisp
2
star
43

go-hello-world

Concurrent Hello World, in Common Lisp
Common Lisp
2
star
44

artisan-mysql

Common Lisp Native Driver for MySQL
Common Lisp
2
star
45

preventddl

set preventddl.enable to true;
PLpgSQL
1
star
46

cl-pgdumpfile

Common Lisp library that knows how to read a PostgreSQL dump file in custom format.
Common Lisp
1
star
47

Citus-tutorial

Automate the Citus tutorial steps into a single command.
Makefile
1
star
48

pgloader.io

Public Website for the pgloader project.
SCSS
1
star
49

pgaf_debian

debian packaging for apt.pg.o for pg_auto_failover
1
star