Git Product home page Git Product logo

regresql's Introduction

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.

regresql's People

Contributors

dimitri avatar nerzhul avatar radim avatar qu4tro avatar

Stargazers

Eduardo Rodriguez avatar Pierre Dahmani avatar Manuel Barros Reyes  avatar Rodrigo Alves Vieira avatar Jens Krafczyk avatar Jayron Soares avatar Kacper Stypik avatar Ibrahim Koz avatar  avatar  avatar Yuan He avatar Stefan avatar  avatar hrckov avatar Hassan Shaikley avatar Simon Goulder avatar  avatar  avatar  avatar  avatar João Fernando Apel Miguel avatar Mark Sadegi avatar timothy avatar David Johnson avatar Kyle Smith avatar Rinat Mukhtarov avatar Raghu Ugare avatar Rowan Molony avatar krinoid avatar Tyler Souza  avatar  avatar Jules BOURDAIS avatar Antonio Fernandes avatar  avatar Steven Kalt avatar Juan Ca Sardin Avendaño avatar  avatar Metin Ağaoğlu avatar nei da silva  avatar Christina Khnaisser avatar Ayoub avatar Maksim Gramin avatar Andreas Motl avatar Yorgos Pagles avatar Christian Rotzoll avatar Valentin Mouret avatar Kristoffer-Andre Kalliainen avatar  avatar Jimmy Briggs avatar Jeff Carpenter avatar Knut Hühne avatar Adam Zell avatar Tinkerrr avatar Will May avatar Benji York avatar Leonid Shirmanov avatar Jamie Sparks avatar Martin Alexanderson avatar Eron Lloyd avatar Adam Eury avatar Kersten Lorenz avatar Akhmatyarov Artur avatar Mr.HyperBit avatar Wildan Zulfikar avatar Blazej Floch avatar vivek avatar Stelios Georgiou avatar Marco Arnold avatar Ian Maurer avatar Andrew Duca avatar Nathan Probst avatar Omar avatar Evgeniy Terekhin avatar Philip Parodayco avatar Elio Esteves Duarte avatar Paul Mestemaker avatar Florian Wilhelm avatar Luis Hernández Castillo avatar gaurav patel avatar Oliver Frolovs avatar Masayuki Morita avatar Kazuma Watanabe avatar Koji Nakayama avatar Nikolaos Korasidis avatar Emiel van de Laar avatar Jean-Baptiste Musso avatar Jesse Carter avatar Alexander Akhmetov avatar Vitor Abner avatar Arttu Kosonen avatar Rob Wells avatar Eko Fedriyanto avatar Paweł Henek avatar onceknown avatar Ziganshina Alfiya avatar Vincent Carrier avatar Biel Simon Rojas avatar Claudio Onoue avatar Bekmamat avatar Zikani Nyirenda Mwase avatar

Watchers

Marcello Nuccio avatar Noam  Vergain avatar  avatar Lury avatar Maksim Gramin avatar Bruno Friedmann avatar Jefferson Santos avatar James Cloos avatar Jason Schuchert avatar Nguyen Hoang Nguyen Duc avatar  avatar Adan Echemendia Montero avatar Hong duc avatar  avatar

regresql's Issues

Enable AWS IAM authentication for the init method

Enable the regresql init method to work with AWS IAM authentication. Im not sure what the best method would be but a flag to use iam may be appropriate. Then a function similar to the following could be used to generate the necessary tokens.

package main

import (
	"database/sql"
	"fmt"

	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/service/rds/rdsutils"
	_ "github.com/lib/pq"
)

func main() {
    dbName := "app"
    dbUser := "jane_doe"
    dbHost := "mydb.123456789012.us-east-1.rds.amazonaws.com"
    dbPort := 5432
    dbEndpoint := fmt.Sprintf("%s:%d", dbHost, dbPort)
    region := "us-east-1"

    creds := credentials.NewEnvCredentials()
    authToken, err := rdsutils.BuildAuthToken(dbEndpoint, region, dbUser, creds)
    if err != nil {
        panic(err)
    }

    dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s",
        dbHost, dbPort, dbUser, authToken, dbName,
    )

    db, err := sql.Open("postgres", dsn)
    if err != nil {
        panic(err)
    }

    err = db.Ping()
    if err != nil {
        panic(err)
    }
}

See the AWS IAM docs for more details on handling connections.

Ignore paths?

Is it possible to add a configuration to regresql to ignore certain paths? We have .sql files in our repository that are schema migration files that aren't to be tested.

Random test errors

I keep getting these random errors. Is it something I'm doing wrong? Or a bug on regresql?

image

Provide precompiled binaries

Hi Dimitri,

it would be much convenient if each release came with precompiled binaries.

Cheers, and thanks for your work !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.