Skip to content

Commit 82bcbea

Browse files
committed
ci: Add GitHub Actions workflow and example test
- Add test.yml workflow that runs on push/PR to main - Uses PostgreSQL 17 service container - Runs ruff linting, mypy type checking, and pytest - Add simple example test demonstrating framework usage - Example shows transaction isolation between tests
1 parent ac74c2b commit 82bcbea

2 files changed

Lines changed: 129 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
services:
14+
postgres:
15+
image: postgres:17
16+
env:
17+
POSTGRES_USER: postgres
18+
POSTGRES_PASSWORD: postgres
19+
POSTGRES_DB: postgres
20+
ports:
21+
- 5432:5432
22+
options: >-
23+
--health-cmd pg_isready
24+
--health-interval 10s
25+
--health-timeout 5s
26+
--health-retries 5
27+
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- name: Set up Python
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: "3.12"
35+
36+
- name: Install Poetry
37+
uses: snok/install-poetry@v1
38+
with:
39+
version: latest
40+
virtualenvs-create: true
41+
virtualenvs-in-project: true
42+
43+
- name: Install dependencies
44+
run: poetry install
45+
46+
- name: Run linting
47+
run: poetry run ruff check .
48+
49+
- name: Run type checking
50+
run: poetry run mypy src --ignore-missing-imports
51+
52+
- name: Run tests
53+
env:
54+
PGHOST: localhost
55+
PGPORT: 5432
56+
PGUSER: postgres
57+
PGPASSWORD: postgres
58+
run: poetry run pytest -v

tests/test_example.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
Simple example test demonstrating pysql-test usage.
3+
4+
This is a minimal example showing how to use the testing framework
5+
for PostgreSQL integration tests with automatic database isolation.
6+
"""
7+
8+
import pytest
9+
10+
from pysql_test import get_connections, seed
11+
12+
13+
@pytest.fixture
14+
def db():
15+
"""
16+
Create an isolated test database with sample schema.
17+
18+
Each test gets a fresh database that is automatically
19+
cleaned up after the test completes.
20+
"""
21+
conn = get_connections(
22+
seed_adapters=[
23+
seed.fn(lambda ctx: ctx["pg"].query("""
24+
CREATE TABLE users (
25+
id SERIAL PRIMARY KEY,
26+
name TEXT NOT NULL,
27+
email TEXT UNIQUE
28+
)
29+
"""))
30+
]
31+
)
32+
db = conn.db
33+
db.before_each()
34+
yield db
35+
db.after_each()
36+
conn.teardown()
37+
38+
39+
def test_insert_and_query_user(db):
40+
"""Test inserting and querying a user."""
41+
# Insert a user
42+
db.execute(
43+
"INSERT INTO users (name, email) VALUES (%s, %s)",
44+
("Alice", "alice@example.com"),
45+
)
46+
47+
# Query the user
48+
user = db.one("SELECT * FROM users WHERE name = %s", ("Alice",))
49+
50+
assert user["name"] == "Alice"
51+
assert user["email"] == "alice@example.com"
52+
53+
54+
def test_transaction_isolation(db):
55+
"""Test that changes are rolled back between tests."""
56+
# This insert will be rolled back after the test
57+
db.execute(
58+
"INSERT INTO users (name, email) VALUES (%s, %s)",
59+
("Bob", "bob@example.com"),
60+
)
61+
62+
# Verify the user exists within this test
63+
count = db.one("SELECT COUNT(*) as count FROM users")
64+
assert count["count"] == 1
65+
66+
67+
def test_empty_table_after_rollback(db):
68+
"""Verify previous test's data was rolled back."""
69+
# Table should be empty because previous test's insert was rolled back
70+
count = db.one("SELECT COUNT(*) as count FROM users")
71+
assert count["count"] == 0

0 commit comments

Comments
 (0)