PostgreSQLでpgTAPをWindows環境で動かす方法とSQL関数のユニットテスト実践
✅ はじめに
PostgreSQLの関数をユニットテストしたいとき、pgTAPという強力なツールがあります。
Linuxでは情報が豊富ですが、Windows環境でのpgTAP運用事例はほぼ皆無でした。
そこで、Windows + psqlでpgTAPを使ってSQL関数のテストを実行する方法を整理しました。
✅ pgTAPとは?
- PostgreSQL用のユニットテストフレームワーク
 - TAP(Test Anything Protocol)に準拠
 - SQL関数やトリガをテストできる
 - CI/CD(GitHub Actionsなど)との相性が良い
 
✅ pgTAPの使用上の注意点
- pgtapは、開発・テスト環境でのみ利用するのが原則です。
 - 後の手順でCREATE EXTENSION pgtap を実行すると、
pgTAPのすべてのテスト関数(数百個)がスキーマに作成されます。 - 注意点:pgTAPを本番DBに入れると、本番スキーマに不要な関数が大量に混在する恐れがあります。
 
✅ WindowsでpgTAPを使う流れ
- pgTAPのソースを入手
 - WSL2でビルド
 - WindowsにSQLをコピーしてインストール
 - psqlでテスト実行
 - pgTAPのアンインストール
 
✅ 1. pgTAPをダウンロード
公式GitHubリポジトリからソースコードを取得します。
git clone https://github.com/theory/pgtap.git
cd pgtap
✅ 2. WSL2でビルド
Windowsでmakeは難しいため、WSL2のUbuntu環境でビルドします。
Ubuntu環境作成をするには、MicrosoftStoreでUbuntuを選択し、「入手」する方法が簡単です。
WSL2でUbuntuを初めて起動すると、下記のようにusernameとpasswordを入力すると、
Ubuntuが起動します。
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: XXXX
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.6.87.2-microsoft-standard-WSL2 x86_64)
makeコマンドがインストールされていない場合は、下記のコマンドでインストールします。
sudo apt-get update
sudo apt-get install make 
pgtapがWIndowsのダウンロードフォルダにある場合は、下記コマンドにて
移動およびmakeコマンドでビルドをします。
cd /mnt/c/Users/<ユーザー名>/Downloads/pgtap
make
ビルド成功後、sql/pgtap--<version>.sqlが生成されます。
このファイルがpgTAPの本体です。
✅ 3. Windowsにコピーして拡張として認識させる
ビルドで生成された以下のファイルをWindowsのPostgreSQLディレクトリにコピーします。
control ファイルは、GitHubの pgtap.control をそのまま利用可能です。
pgtap--1.X.X.sqlはmakeコマンドにてビルドする必要があります。
pgtap.controlpgtap--1.X.X.sql
コピー先:
C:\Program Files\PostgreSQL\<version>\share\extension\
✅ 4. PostgreSQLでインストール
psqlで対象データベースに接続し、以下を実行します。
CREATE EXTENSION pgtap;
バージョン確認:
SELECT pgtap_version();
✅ ユニットテスト実践(例:SQL関数)
サンプル関数:
CREATE OR REPLACE FUNCTION public.test(orig smallint, newval smallint)
RETURNS smallint LANGUAGE plpgsql IMMUTABLE AS $$
BEGIN
    IF orig = 999 THEN
        IF newval IS NULL THEN
            RETURN 3;
        ELSE
            RETURN newval;
        END IF;
    ELSE
        RETURN orig;
    END IF;
END;
$$;
✅ pgTAPテストコード
test.sql:
BEGIN;
SELECT plan(4);
SELECT is(fnc_test(999::smallint, NULL::smallint), 3::smallint, 'orig=999, newval=NULL -> returns 3');
SELECT is(fnc_test(999::smallint, 5::smallint), 5::smallint, 'orig=999, newval=5 -> returns 5');
SELECT is(fnc_test(100::smallint, NULL::smallint), 100::smallint, 'orig=100, newval=NULL -> returns orig');
SELECT is(fnc_test(50::smallint, 10::smallint), 50::smallint, 'orig=50, newval=10 -> returns orig');
SELECT * FROM finish();
ROLLBACK;
✅ 実行方法
psql -d <DB名> -U <ユーザ名> -f <実行ファイル名>.sql -o <出力ファイル名>
実行失敗例: テストコードで戻り値の型変換をしなかった場合
psql:xxx.sql:xx: ERROR:  関数is(smallint, integer, unknown)は存在しません
LINE 1: SELECT is( fnc_test(999::SMALLINT, 0::SMALLINT), ...
               ^
HINT:  指定した名前と引数型に合致する関数がありません。明示的な型変換が必要かもしれません。
実行失敗例:DBがSJISで構築、実行ファイルをUTF-8形式で保存した場合
psql:xxx.sql:5: ERROR:  符号化方式"SJIS"に対する不正なバイト列です: 0x92 0x20
実行失敗例:テストコードでBEGIN; の後に SELECT plan(N); を記述しなかった場合
psql:xxx.sql:5: ERROR:  You tried to run a test without a plan! Gotta have a plan
、このエラーが発生することがあります。
出力例:
ok 1 - orig=999, newval=NULL -> returns 3
ok 2 - orig=999, newval=5 -> returns 5
ok 3 - orig=100, newval=NULL -> returns orig
ok 4 - orig=50, newval=10 -> returns orig
1..4
✅ 5. pgTAPのアンインストール
ユニットテストが終了したらpgTAPをアンインストールします。
pgTAP が拡張として登録されている場合、まず以下で確認します。
\dx
pgtap が表示されれば、次のコマンドでアンインストールできます。
DROP EXTENSION pgtap CASCADE;
CASCADE を付けると、pgTAP が作成したスキーマ(通常は tap)や型・関数もまとめて削除されます。
拡張が正しく登録されていれば、これだけでアンインストール完了。
✅ ポイント
- 
pgTAPの
is()は型一致必須 → smallint同士にキャスト - Windowsは
CREATE EXTENSIONを使うためにpgtap.control + SQLを配置する必要あり - 
CI/CDに組み込みやすい(
proveやGitHub Actions連携可) 
✅ まとめ
- WindowsでpgTAPを動かすにはWSL2でビルド → Windowsにコピー → CREATE EXTENSION
 - 
psqlで簡単にテストできる - PostgreSQL関数の品質を担保する強力な手段
 
🔗 参考リンク
続き:「pgTAP 実践編(テンプレートでの自動テスト構築)」へ 🚀
Discussion