Skip to content
Home › SQL Comparisons › tSQLt vs pgTAP
Comparison · Testing & Test Data

tSQLt vs pgTAP

tSQLt and pgTAP are the standard free frameworks for writing database unit tests in SQL, but for different engines: tSQLt for SQL Server, pgTAP for PostgreSQL. Your engine decides which one applies. This page explains how the two approaches differ (test doubles versus TAP assertions), how each is installed and run, and what to watch for on managed cloud services.

Last verified November 2026. Versions checked: tSQLt V1.0.8083.3529 (17 February 2022), pgTAP 1.3.4 (4 October 2025). Licensing and features change; check the official sources for the latest details.

Quick verdict

Short answer

There is no winner here because the two do not compete: use tSQLt if your code lives in SQL Server, and pgTAP if it lives in PostgreSQL. What differs is the style. tSQLt is an xUnit framework built around isolation, with FakeTable, FakeFunction and SpyProcedure so you can test one procedure without its real dependencies. pgTAP emits TAP output and is unusually strong at asserting schema, ownership and privileges as well as query results. Note that tSQLt has had no release since February 2022 and its downloads page names only an older build for Azure SQL Database, while pgTAP 1.3.4 (October 2025) was tested on PostgreSQL 9.1 to 18.

How we know: This comparison is research-based: features, installation steps, release history, platform support and licences were checked on 7 November 2026 against tsqlt.org, the tSQLt GitHub repository, Redgate's SQL Test page, pgtap.org and the pgTAP GitHub repository and Changes file. We have not run either framework; the code samples illustrate documented functions and are not output from our own runs.

tSQLt is an open source (Apache 2.0) unit testing framework for SQL Server, implemented as T-SQL objects plus a CLR assembly that you install into a development database. Tests are stored procedures grouped into test classes (schemas); each test runs inside a transaction that is rolled back afterwards. Redgate sponsors the project and sells SQL Test, an SSMS front end built on it. The latest release on tsqlt.org is V1.0.8083.3529 (17 February 2022).

pgTAP is a PostgreSQL extension, maintained by David E. Wheeler and distributed through PGXN, that adds test functions emitting TAP (Test Anything Protocol) output. Tests can be plain SQL scripts that call plan(), assertions and finish(), or xUnit-style test functions run by runtests(). Suites are run with pg_prove, a Perl command-line tool from CPAN. Version 1.3.4 (4 October 2025) is the latest release, and 1.3.5 is in development. Its README grants permissive, PostgreSQL-style terms.

Choosing between engines? That is a different decision; see SQL Server vs PostgreSQL. If your team tests the database from application code instead, see Testcontainers or DbUnit.

Side by side

AspecttSQLtpgTAP
Target engine SQL Server 2005 SP2 and later, including SQL Server on Linux PostgreSQL 9.1 or later (1.3.4 tested on 9.1 to 18)
Test style xUnit: tests are stored procedures in schema-based test classes TAP scripts with plan() and finish(), or xUnit-style functions via runtests()
Isolation Each test in a transaction, rolled back; test doubles isolate dependencies Scripts usually wrapped in BEGIN and ROLLBACK; runtests() rolls back after each test
Test doubles FakeTable, FakeFunction, SpyProcedure (with optional @CallOriginal) No built-in faking; tests set up their own rows and objects
Schema assertions Limited; focus is on code behaviour Extensive: has_table, columns_are, fk_ok, indexes, functions, owners, privileges, policies
Result assertions AssertEquals, AssertEqualsTable and others is, results_eq, set_eq, bag_eq, row_eq, throws_ok, lives_ok
Installation Script or version-specific DACPAC; PrepareServer.sql once per server (sysadmin) enables CLR and installs a certificate Build or install the extension, then CREATE EXTENSION pgtap (superuser rights typically needed)
Runner and output tSQLt.Run inside the database; plain text or XML results for CI pg_prove (Perl, CPAN) with parallel jobs; TAP output for TAP harnesses
Managed cloud services Downloads page names the older 1.0.5873.27393 build for Azure SQL Database; current build not documented there; Managed Instance not documented Works wherever the provider allows the pgtap extension; check your provider
Release activity No release since 17 February 2022 1.3.4 on 4 October 2025; 1.3.5 in development
Licence and cost Apache 2.0, free; Redgate SQL Test is a paid GUI on top Permissive PostgreSQL-style terms, free; pg_prove also free

Key differences

Isolation with test doubles versus assertions on everything

tSQLt is built around isolating the unit under test. FakeTable replaces a real table with an empty copy without constraints, so a test inserts only the two or three columns it cares about. SpyProcedure replaces a dependent procedure and records how it was called, and FakeFunction does the same for functions. This makes it practical to test one stored procedure in a large legacy database without building valid data for every foreign key:

-- T-SQL (tSQLt): one test in a test class
EXEC tSQLt.NewTestClass 'testOrders';
GO
CREATE PROCEDURE testOrders.[test GetOrderTotal sums order lines]
AS
BEGIN
    EXEC tSQLt.FakeTable 'dbo.OrderLines';
    INSERT INTO dbo.OrderLines (OrderID, Amount) VALUES (1, 10.00), (1, 5.00);

    DECLARE @actual money = dbo.GetOrderTotal(1);

    EXEC tSQLt.AssertEquals 15.00, @actual;
END;
GO
EXEC tSQLt.Run 'testOrders';

pgTAP has no faking layer. Instead it offers a very wide set of assertions, many of them about the schema itself: that tables, columns, keys, indexes and functions exist with the expected definitions, and that owners, privileges and row-level security policies are what you expect. That makes it well suited to checking every migration, not only function behaviour. Tests insert their own rows inside a transaction that is rolled back:

-- PostgreSQL (pgTAP): a plain SQL test script
BEGIN;
SELECT plan(3);

SELECT has_table('public', 'orders', 'orders table exists');
SELECT col_not_null('public', 'orders', 'customer_id', 'customer_id is NOT NULL');

INSERT INTO order_lines (order_id, amount) VALUES (1, 10.00), (1, 5.00);
SELECT results_eq(
    'SELECT order_total(1)',
    $$VALUES (15.00::numeric)$$,
    'order_total sums order lines'
);

SELECT * FROM finish();
ROLLBACK;

Installing and running

tSQLt installs into each development database by script or by a SQL Server version-specific DACPAC (added in V1.0.7942, September 2021, which also certified SQL Server on Linux). Its quick start says to run PrepareServer.sql once per server with sysadmin rights; it enables CLR and installs a certificate so strict CLR security does not need to be turned off. The project is clear that tSQLt should never be installed in production. Tests run inside the database with tSQLt.Run or tSQLt.RunAll, and results can be written as XML for a CI server.

pgTAP is a normal PostgreSQL extension: build it from source with make and pg_config (or use a package), then run CREATE EXTENSION pgtap in the test database, which typically needs superuser rights. Tests are files run by pg_prove, which calls psql, can run several files in parallel with -j, and can execute xUnit-style test functions with --runtests. Because pg_prove is Perl from CPAN, CI images need Perl and the TAP::Parser::SourceHandler::pgTAP distribution.

Managed cloud databases

This is where the two differ most in practice. tSQLt's downloads page offers the older 1.0.5873.27393 build as "the version working with SQL 2005 (and currently Azure SQL Databases)" and makes no compatibility claim for the latest build, which relies on a CLR assembly and a server certificate. Support for Azure SQL Managed Instance is not documented. If your target is Azure SQL Database, one option is to run the tSQLt suite against SQL Server in a container or VM in CI, and confirm with the project before installing the current build on the cloud database itself.

pgTAP works on any PostgreSQL where you can create the extension. Managed services decide which extensions they allow, so check your provider's extension list; where pgtap is not offered, one option is to run the suite against a PostgreSQL container of the same major version in CI.

Project activity and ecosystem

tSQLt has been quiet since V1.0.8083.3529 in February 2022. In our view it is stable rather than abandoned: it remains the framework underneath Redgate SQL Test, and much existing T-SQL test code depends on it. Still, factor in that newer SQL Server releases are not explicitly addressed in its release notes. pgTAP has kept pace with PostgreSQL: 1.3.4 fixed upgrade paths and a test failure on PostgreSQL 18, and 1.3.5 is in development. Its TAP output plugs into any TAP harness, while tSQLt's XML output plugs into common CI servers.

Pricing and licensing

tSQLt is free and open source under the Apache License 2.0. Redgate SQL Test, an optional SSMS add-in built on tSQLt, is a paid product: Redgate lists it at $303 per user per year for 1-4 users, and it is included in SQL Toolbelt Essentials ($1,410 per user per year for 1-4 users). The tSQLt downloads page links a 28-day SQL Test trial.

pgTAP is free under permissive terms in its README that allow use, copying, modification and distribution for any purpose without fee. The pg_prove runner is also free from CPAN. There is no paid edition of either.

Pricing checked on the vendors' official pages on 7 November 2026. Prices change; confirm before buying.

Where each one leads

tSQLt strengths

  • Test doubles (FakeTable, FakeFunction, SpyProcedure) make isolated tests of single procedures practical
  • Automatic transaction and rollback per test, with no cleanup code
  • Tests written in T-SQL, the language of the code under test
  • Optional commercial SSMS front end (Redgate SQL Test) and DACPAC installation
  • XML results for CI servers

pgTAP strengths

  • Broad schema, ownership, privilege and policy assertions, useful for migration checks
  • Standard TAP output readable by existing TAP harnesses
  • Recent release tested on PostgreSQL 9.1 to 18
  • pg_prove runs test files in parallel
  • Installs as an ordinary PostgreSQL extension, with no CLR-style server change

Limitations

tSQLt limitations

  • No release since February 2022
  • Needs CLR and a sysadmin-run PrepareServer step; must not be installed in production
  • Downloads page names only an older build for Azure SQL Database; Managed Instance not documented
  • Fewer built-in schema assertions than pgTAP

pgTAP limitations

  • No built-in fakes or spies; tests must create the rows and objects they need
  • CREATE EXTENSION usually needs superuser rights
  • pg_prove depends on Perl and CPAN modules
  • Availability on managed PostgreSQL services varies by provider

When to choose each

Choose tSQLt if

  • Your business logic lives in SQL Server stored procedures, functions or views
  • You need to test one procedure in isolation from large, constraint-heavy tables
  • You want to verify that a procedure calls another (for example an audit procedure)
  • Your team uses SSMS and may want Redgate SQL Test as a GUI

Choose pgTAP if

  • Your database is PostgreSQL and you want tests written in SQL
  • You want every migration checked for expected tables, columns, keys and indexes
  • You need to verify grants, ownership or row-level security policies per role
  • You already use TAP harnesses or want parallel test runs in CI

When neither is right

  • You prefer to test the database from your application's own test framework: use Testcontainers for throwaway databases, or DbUnit on Java.
  • You need data quality tests on warehouse models rather than unit tests of database code: see Datafold vs dbt tests.
  • You need large volumes of realistic data to test against, not assertions: see Redgate SQL Data Generator vs dbForge Data Generator.
  • You run MySQL or Oracle: neither framework applies; test from application code or with engine-specific tools.

Final recommendation

Bottom line

Pick by engine: tSQLt for SQL Server, pgTAP for PostgreSQL. If you run both engines, expect two styles of test. tSQLt tests lean on fakes and spies to isolate T-SQL code; plan for its CLR requirement, keep it out of production, and run suites against SQL Server in CI if your target is Azure SQL Database. pgTAP tests lean on assertions, including schema and privilege checks that make it a strong migration guard; plan for extension rights on managed services and a Perl-capable CI image for pg_prove.

Frequently asked questions

Can I use tSQLt on PostgreSQL or pgTAP on SQL Server?

No. tSQLt is written in T-SQL with a CLR assembly and runs only on SQL Server. pgTAP is a PostgreSQL extension. Each framework targets one engine.

Is tSQLt still maintained?

The latest release on tsqlt.org is V1.0.8083.3529 from 17 February 2022, and no newer release notes had been published by 7 November 2026. It remains available, Apache 2.0 licensed, and is the basis of Redgate SQL Test.

Does tSQLt work on Azure SQL Database?

The tSQLt downloads page offers the older 1.0.5873.27393 build as the one that works with Azure SQL Database and makes no such claim for the latest build. One option is to run the suite against SQL Server in a container or VM in CI instead.

Which PostgreSQL versions does pgTAP support?

The README requires PostgreSQL 9.1 or later, and the 1.3.4 release notes (4 October 2025) say it was tested on PostgreSQL 9.1 through 18.

Does pgTAP have something like tSQLt FakeTable?

Not built in. pgTAP tests usually insert the rows they need inside a transaction that is rolled back, or use setup functions with runtests(). Its strength is assertions, including schema and privilege checks.

Sources

Checked November 2026.

How we research comparisons: our editorial method.

More comparisons

Browse all SQL comparisons or the tools directory.