Skip to content

Commit 3464e71

Browse files
committed
Add integration test CI and skip integration tests by default
- Mark PostgreSQL integration tests with @pytest.mark.integration - Configure pytest to skip integration tests by default with addopts - Create .github/workflows/integration.yml for PostgreSQL integration CI - Update docker-compose to use pytest -m integration - Fix ruff errors (unused imports and variables) - Update tests/db/README.md with marker-based test running instructions Normal pytest runs now skip integration tests (566 tests pass, 10 deselected). Integration tests run separately in CI with postgres service.
1 parent eedb7e7 commit 3464e71

7 files changed

Lines changed: 68 additions & 17 deletions

File tree

.github/workflows/integration.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Integration Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
postgres-integration:
11+
runs-on: ubuntu-latest
12+
13+
services:
14+
postgres:
15+
image: postgres:16-alpine
16+
env:
17+
POSTGRES_USER: test
18+
POSTGRES_PASSWORD: test
19+
POSTGRES_DB: sidemantic_test
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: Install uv
32+
uses: astral-sh/setup-uv@v5
33+
with:
34+
enable-cache: true
35+
36+
- name: Set up Python
37+
run: uv python install 3.12
38+
39+
- name: Install dependencies
40+
run: uv sync --extra postgres --extra dev
41+
42+
- name: Run PostgreSQL integration tests
43+
env:
44+
POSTGRES_TEST: "1"
45+
POSTGRES_URL: "postgres://test:test@localhost:5432/sidemantic_test"
46+
run: uv run pytest -m integration -v

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ services:
2525
environment:
2626
POSTGRES_TEST: "1"
2727
POSTGRES_URL: "postgres://test:test@postgres:5432/sidemantic_test"
28-
command: pytest tests/db/test_postgres_integration.py -v
28+
command: pytest -m integration -v
2929

3030
volumes:
3131
postgres_data:

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ ignore = ["E501", "N807"] # N807: dunder methods like __init__ are supposed to
8686
[tool.pytest.ini_options]
8787
testpaths = ["tests"]
8888
pythonpath = ["."]
89+
markers = [
90+
"integration: marks tests as integration tests requiring external services (deselect with '-m \"not integration\"')",
91+
]
92+
addopts = "-m 'not integration'" # Skip integration tests by default
8993

9094
[tool.uv]
9195
prerelease = "if-necessary"

tests/db/README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ pytest tests/db/test_semantic_layer_adapters.py -v
1010

1111
### PostgreSQL Integration Tests
1212

13-
PostgreSQL tests require a running Postgres instance and the `postgres` extra dependencies.
13+
PostgreSQL tests are marked with `@pytest.mark.integration` and skipped by default. They require a running Postgres instance and the `postgres` extra dependencies.
1414

1515
**Using Docker Compose (recommended):**
1616
```bash
17-
# Start Postgres and run tests
17+
# Start Postgres and run integration tests
1818
docker compose up test --build --abort-on-container-exit
1919

2020
# Or run tests locally against dockerized Postgres
2121
docker compose up -d postgres
22-
POSTGRES_TEST=1 uv run --extra postgres pytest tests/db/test_postgres_integration.py -v
22+
POSTGRES_TEST=1 uv run --extra postgres pytest -m integration -v
2323
```
2424

2525
**Manual setup:**
@@ -31,10 +31,12 @@ uv sync --extra postgres
3131
export POSTGRES_TEST=1
3232
export POSTGRES_URL="postgres://test:test@localhost:5432/sidemantic_test"
3333

34-
# Run tests
35-
uv run pytest tests/db/test_postgres_integration.py -v
34+
# Run integration tests only
35+
uv run pytest -m integration -v
3636
```
3737

38+
**Note:** Normal `pytest` runs will skip integration tests automatically. Use `-m integration` to run them explicitly.
39+
3840
## Test Coverage
3941

4042
- **test_duckdb_adapter.py**: Tests for DuckDB adapter implementation

tests/db/test_postgres_adapter.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ def test_postgres_adapter_missing_dependency():
1818

1919
def test_postgres_adapter_from_url_parsing():
2020
"""Test URL parsing (without actually connecting)."""
21-
# Test that URL parsing works correctly
22-
# We can't test actual connection without a postgres instance
23-
url = "postgres://user:pass@localhost:5432/testdb"
24-
2521
# Just verify the from_url method exists and accepts the URL format
2622
# It will fail on connection but that's ok for this test
2723
assert hasattr(PostgreSQLAdapter, "from_url")

tests/db/test_postgres_integration.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Integration tests for PostgreSQL adapter against real database.
22
3-
Run with: docker compose up -d && pytest tests/db/test_postgres_integration.py -v
3+
Run with: docker compose up -d && pytest -m integration tests/db/test_postgres_integration.py -v
44
"""
55

66
import os
@@ -9,11 +9,14 @@
99

1010
from sidemantic import Dimension, Metric, Model, SemanticLayer
1111

12-
# Skip all tests if POSTGRES_TEST environment variable not set
13-
pytestmark = pytest.mark.skipif(
14-
os.getenv("POSTGRES_TEST") != "1",
15-
reason="Set POSTGRES_TEST=1 and run docker compose up -d to run Postgres integration tests",
16-
)
12+
# Mark all tests in this module as integration tests
13+
pytestmark = [
14+
pytest.mark.integration,
15+
pytest.mark.skipif(
16+
os.getenv("POSTGRES_TEST") != "1",
17+
reason="Set POSTGRES_TEST=1 and run docker compose up -d to run Postgres integration tests",
18+
),
19+
]
1720

1821
# Use environment variable for URL (different in docker vs local)
1922
POSTGRES_URL = os.getenv("POSTGRES_URL", "postgres://test:test@localhost:5433/sidemantic_test")

tests/db/test_semantic_layer_adapters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import pytest
44

5-
from sidemantic import Dimension, Metric, Model, SemanticLayer
5+
from sidemantic import Metric, Model, SemanticLayer
66
from sidemantic.db.duckdb import DuckDBAdapter
77

88

0 commit comments

Comments
 (0)