This library proves a test interface for hasql library. Hasql is very performant Postgres client library for Haskell, that allows to write raw SQL queries. Ability to write raw queries allows to use the full set of the database engine features and easy debug and analysis using external tools.
However when writing raw queries it's very easy to make a mistake and this mistake will not be checked by the compiler. This library tries to solve the problem by introducing helpers to test queries.
The library provides some basic tests of the database queries:
explain tests
- tests that checks that we can call explain on the query this test will guarantee that the database can parse the query and run it in the current schema. This test also automatically checks parameters encoding.
At this moment there is no automation that would allow to gather all the queries across the project. So usually the simplest way is to export all the queries from the module:
module A
( ...
, queries
) where
queries :: (String, SomeQuery)
queries =
[ "queryName" =>> queryName
, "anotherQuery" =>> anotherQuery
]
And use that function in the test suite:
module Main (main) where
import Test.Tasty
import Test.Tasty.HUnit
import A qualified
main = defaultMain $
withResource (startupPostgres) (teardownPostgres) $ mkDb ->
withResource (mkDb >>= allocateConnection) (freeConnection) $ conn ->
tests conn
tests :: IO HC.Connection -> TestGroup
tests mkConn = testGroup "explain-tests" $
[ testGroup "A" $ A.queries <&> \(name, SomeQuery q) ->
testCase name $ mkConn >>= explain q
]
There are a plenty of the approaches that can allow to use the library with nix, but we prefer the following:
- Add the package to the
haskellPackages
set by any means - Write a wrapper that will add a dependency on the Postgres server of the required version:
```nix
{ hpkgs # haskell packages set
, haskell # haskell lib
, postgresql_11 # postgres version
}:
haskell.lib.overrideCabal hpkgs.db-tests (drv: {
# Add postgres server to the tests dependencies:
testDepends = (drv.testDepends or []) ++ [postgresql_11];
# have streaming logs, very useful for CI
testTarget = "--show-details=streaming";
doCheck = true;
# there can be any other modifications:
#
# enableSharedExecutables = false;
# enableSeparateDataOutput = true;
# enableSeparateDocOutput = true;
# enableLibraryProfiling = false;
# isLibrary = true;
# doHaddock = false;
})
# Tricks
1. In order to substitute the parameters we require all the parameters to have
`Arbitrary` instance, however it's not always possible as not all parameters may
have a sane instance. In such cases it worth mapping the query input. It can be
done by applying `lmap` from `profunctors` package: