sql
322 lines · 2 tabs
Maria Garcia
Feb 2026
2 tabs
-- Create test database
CREATE DATABASE myapp_test;
-- Test isolation with transactions
/*
beforeEach(async () => {
await db.query('BEGIN');
});
afterEach(async () => {
await db.query('ROLLBACK');
});
test('creates user', async () => {
await db.query('INSERT INTO users (username) VALUES ($1)', ['test']);
const result = await db.query('SELECT * FROM users WHERE username = $1', ['test']);
expect(result.rows).toHaveLength(1);
}); // Rolled back automatically
*/
-- Test fixtures (seed data)
CREATE TABLE test_users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Load fixtures
TRUNCATE test_users CASCADE;
INSERT INTO test_users (id, username, email) VALUES
(1, 'alice', 'alice@test.com'),
(2, 'bob', 'bob@test.com'),
(3, 'carol', 'carol@test.com');
-- Reset sequence
SELECT setval('test_users_id_seq', (SELECT MAX(id) FROM test_users));
-- Factory function
CREATE OR REPLACE FUNCTION create_test_user(
username_prefix TEXT DEFAULT 'user'
)
RETURNS test_users AS $$
DECLARE
new_user test_users;
BEGIN
INSERT INTO test_users (username, email)
VALUES (
username_prefix || '_' || floor(random() * 1000000),
username_prefix || '@test.com'
)
RETURNING * INTO new_user;
RETURN new_user;
END;
$$ LANGUAGE plpgsql;
-- Usage
SELECT * FROM create_test_user('testuser');
-- Clean database helper
CREATE OR REPLACE FUNCTION truncate_all_tables()
RETURNS VOID AS $$
DECLARE
table_name TEXT;
BEGIN
FOR table_name IN
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
LOOP
EXECUTE format('TRUNCATE TABLE %I CASCADE', table_name);
END LOOP;
END;
$$ LANGUAGE plpgsql;
-- Reset database for tests
SELECT truncate_all_tables();
-- Test data builder pattern
CREATE OR REPLACE FUNCTION build_test_order(
p_user_id INT DEFAULT NULL,
p_total DECIMAL DEFAULT 99.99,
p_status VARCHAR DEFAULT 'pending'
)
RETURNS orders AS $$
DECLARE
v_user_id INT;
new_order orders;
BEGIN
IF p_user_id IS NULL THEN
v_user_id := (SELECT id FROM create_test_user('order_user'));
ELSE
v_user_id := p_user_id;
END IF;
INSERT INTO orders (user_id, total, status)
VALUES (v_user_id, p_total, p_status)
RETURNING * INTO new_order;
RETURN new_order;
END;
$$ LANGUAGE plpgsql;
-- Create order with defaults
SELECT * FROM build_test_order();
-- Create order with specific values
SELECT * FROM build_test_order(1, 199.99, 'completed');
-- Assert functions for tests
CREATE OR REPLACE FUNCTION assert_equals(
expected ANYELEMENT,
actual ANYELEMENT,
message TEXT DEFAULT 'Assertion failed'
)
RETURNS VOID AS $$
BEGIN
IF expected IS DISTINCT FROM actual THEN
RAISE EXCEPTION '% - Expected: %, Actual: %',
message, expected, actual;
END IF;
END;
$$ LANGUAGE plpgsql;
-- Test example
DO $$
DECLARE
user_count INT;
BEGIN
SELECT COUNT(*) INTO user_count FROM test_users;
PERFORM assert_equals(3, user_count, 'User count should be 3');
END $$;
-- Snapshot testing (save and compare)
CREATE TABLE test_snapshots (
test_name VARCHAR(100) PRIMARY KEY,
snapshot JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Save snapshot
INSERT INTO test_snapshots (test_name, snapshot)
VALUES (
'user_list',
(SELECT jsonb_agg(row_to_json(u.*)) FROM test_users u)
);
-- Compare snapshot
DO $$
DECLARE
current_data JSONB;
saved_snapshot JSONB;
BEGIN
SELECT jsonb_agg(row_to_json(u.*)) INTO current_data
FROM test_users u;
SELECT snapshot INTO saved_snapshot
FROM test_snapshots
WHERE test_name = 'user_list';
IF current_data IS DISTINCT FROM saved_snapshot THEN
RAISE EXCEPTION 'Snapshot mismatch for user_list';
END IF;
END $$;
-- Parallel test databases
/*
// Node.js example - create database per worker
const workerId = process.env.JEST_WORKER_ID || 1;
const testDb = `myapp_test_${workerId}`;
beforeAll(async () => {
await adminClient.query(`DROP DATABASE IF EXISTS ${testDb}`);
await adminClient.query(`CREATE DATABASE ${testDb}`);
await adminClient.query(`
GRANT ALL PRIVILEGES ON DATABASE ${testDb} TO myapp_user
`);
// Run migrations
await runMigrations(testDb);
});
afterAll(async () => {
await adminClient.query(`DROP DATABASE ${testDb}`);
});
*/
-- Test migrations
-- Keep separate test migration table
CREATE TABLE test_schema_migrations (
version VARCHAR(255) PRIMARY KEY,
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Test slow queries
SET statement_timeout = '100ms';
-- This should fail if slow
SELECT * FROM large_table WHERE unindexed_column = 'value';
RESET statement_timeout;
-- Test constraints
DO $$
BEGIN
-- Should succeed
INSERT INTO users (username, email)
VALUES ('testuser', 'test@example.com');
-- Should fail (duplicate email)
BEGIN
INSERT INTO users (username, email)
VALUES ('another', 'test@example.com');
RAISE EXCEPTION 'Expected unique constraint violation';
EXCEPTION
WHEN unique_violation THEN
NULL; -- Expected
END;
END $$;
-- Test triggers
CREATE TABLE audit_test_log (
id SERIAL PRIMARY KEY,
event TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE OR REPLACE FUNCTION test_audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_test_log (event)
VALUES (TG_OP || ' on ' || TG_TABLE_NAME);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER test_audit
AFTER INSERT OR UPDATE OR DELETE ON test_users
FOR EACH ROW
EXECUTE FUNCTION test_audit_trigger();
-- Test the trigger
INSERT INTO test_users (username, email) VALUES ('trigger_test', 'test@example.com');
-- Verify audit log
SELECT * FROM audit_test_log WHERE event = 'INSERT on test_users';
-- Mock/stub pattern
-- Replace function with mock during test
CREATE OR REPLACE FUNCTION send_email(recipient TEXT, subject TEXT)
RETURNS BOOLEAN AS $$
BEGIN
-- Production: Actually send email
-- Test: Log to table instead
INSERT INTO email_log (recipient, subject)
VALUES (recipient, subject);
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- Test data generators
CREATE OR REPLACE FUNCTION random_string(length INT)
RETURNS TEXT AS $$
SELECT string_agg(
substring('abcdefghijklmnopqrstuvwxyz', (random() * 26)::INT + 1, 1),
''
)
FROM generate_series(1, length);
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION random_email()
RETURNS TEXT AS $$
SELECT random_string(10) || '@test.com';
$$ LANGUAGE SQL;
-- Generate bulk test data
INSERT INTO test_users (username, email)
SELECT
'user_' || i,
'user_' || i || '@test.com'
FROM generate_series(1, 1000) i;
-- Performance testing
\timing on
SELECT COUNT(*) FROM test_users WHERE email LIKE '%test.com';
\timing off
-- Coverage: Check all tables have tests
SELECT
t.tablename,
EXISTS (
SELECT 1 FROM test_snapshots
WHERE test_name LIKE '%' || t.tablename || '%'
) AS has_test
FROM pg_tables t
WHERE t.schemaname = 'public'
ORDER BY has_test, t.tablename;
-- Integration test pattern
DO $$
DECLARE
v_user test_users;
v_order orders;
BEGIN
-- Arrange
v_user := create_test_user('integration');
-- Act
v_order := build_test_order(v_user.id, 150.00, 'pending');
UPDATE orders SET status = 'completed' WHERE id = v_order.id;
-- Assert
PERFORM assert_equals(
'completed',
(SELECT status FROM orders WHERE id = v_order.id),
'Order should be completed'
);
END $$;
2 files · sql
Explain with highlit
Database testing ensures schema and queries work correctly. I use transactions for test isolation—rollback after each test. Test fixtures provide consistent data. Factory patterns generate test data programmatically. Understanding schema migrations in tests prevents environment drift. Separate test database prevents production corruption. Parallel test execution requires database-per-worker. Seed data for development differs from test fixtures. Proper testing catches bugs before production. Essential for CI/CD pipelines, regression prevention. PostgreSQL transaction-based testing enables fast, isolated tests.
Related snips
sql
-- Simple function
CREATE OR REPLACE FUNCTION get_full_name(
first_name VARCHAR,
last_name VARCHAR
)
RETURNS VARCHAR AS $$
Stored procedures and functions in PostgreSQL
postgresql
stored-procedures
functions
by Maria Garcia
2 tabs
ruby
class CommentsController < ApplicationController
before_action :set_post
def create
@comment = @post.comments.build(comment_params)
System test: asserting Turbo Stream responses
rails
hotwire
turbo
by codesnips
4 tabs
rust
use my_crate::add;
#[test]
fn test_public_api() {
assert_eq!(add(3, 4), 7);
}
Integration tests in tests/ directory
rust
testing
integration
by Marcus Chen
1 tab
sql
-- EXPLAIN ANALYZE (actual execution statistics)
EXPLAIN ANALYZE
SELECT u.username, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at >= '2024-01-01'
Advanced query optimization techniques
database
optimization
query-performance
by Maria Garcia
2 tabs
kotlin
package com.example.myapp.data.repository
import com.example.myapp.data.local.PostDao
import com.example.myapp.data.local.PostEntity
import com.example.myapp.data.remote.ApiService
import com.example.myapp.models.Post
Unit testing with JUnit and MockK
kotlin
android
testing
by Alex Chen
2 tabs
sql
-- Publisher: Send notification
NOTIFY new_order, 'Order #12345 created';
-- Subscriber: Listen for notifications
LISTEN new_order;
PostgreSQL LISTEN/NOTIFY for pub-sub messaging
postgresql
listen-notify
pub-sub
by Maria Garcia
2 tabs
Share this code
Here's the card — post it anywhere.