Skip to content

Commit 1ae815b

Browse files
Add pytest marks for test dependency management
- Register requires_mysql and requires_minio marks in pyproject.toml - Add pytest_collection_modifyitems hook to auto-mark tests based on fixture usage - Remove autouse=True from configure_datajoint fixture so containers only start when needed - Fix test_drop_unauthorized to use connection_test fixture Tests can now run without Docker: pytest -m "not requires_mysql" # Run 192 unit tests Full test suite still works: DJ_USE_EXTERNAL_CONTAINERS=1 pytest tests/ # 471 tests Bump version to 2.0.0a9 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 70f53d4 commit 1ae815b

File tree

4 files changed

+71
-8
lines changed

4 files changed

+71
-8
lines changed

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@ skip = ".git,*.pdf,*.svg,*.csv,*.ipynb,*.drawio"
158158
# astroid -- Python library name (not "asteroid")
159159
ignore-words-list = "rever,numer,astroid"
160160

161-
# pytest-env removed - testcontainers handles container lifecycle automatically
161+
[tool.pytest.ini_options]
162+
markers = [
163+
"requires_mysql: marks tests as requiring MySQL database (deselect with '-m \"not requires_mysql\"')",
164+
"requires_minio: marks tests as requiring MinIO object storage (deselect with '-m \"not requires_minio\"')",
165+
]
162166

163167

164168
[tool.pixi.workspace]

src/datajoint/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# version bump auto managed by Github Actions:
22
# label_prs.yaml(prep), release.yaml(bump), post_release.yaml(edit)
33
# manually set this version will be eventually overwritten by the above actions
4-
__version__ = "2.0.0a8"
4+
__version__ = "2.0.0a9"

tests/conftest.py

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
"""
22
Pytest configuration for DataJoint tests.
33
4-
Containers are automatically started via testcontainers - no manual setup required.
4+
Tests are organized by their dependencies:
5+
- Unit tests: No external dependencies, run with `pytest -m "not requires_mysql"`
6+
- Integration tests: Require MySQL/MinIO, marked with @pytest.mark.requires_mysql
7+
8+
Containers are automatically started via testcontainers when needed.
59
Just run: pytest tests/
610
711
To use external containers instead (e.g., docker-compose), set:
812
DJ_USE_EXTERNAL_CONTAINERS=1
913
DJ_HOST=localhost DJ_PORT=3306 S3_ENDPOINT=localhost:9000 pytest
14+
15+
To run only unit tests (no Docker required):
16+
pytest -m "not requires_mysql"
1017
"""
1118

1219
import logging
@@ -28,6 +35,52 @@
2835
logger = logging.getLogger(__name__)
2936

3037

38+
# =============================================================================
39+
# Pytest Hooks
40+
# =============================================================================
41+
42+
43+
def pytest_collection_modifyitems(config, items):
44+
"""Auto-mark integration tests based on their fixtures."""
45+
# Tests that use these fixtures require MySQL
46+
mysql_fixtures = {
47+
"connection_root",
48+
"connection_root_bare",
49+
"connection_test",
50+
"schema_any",
51+
"schema_any_fresh",
52+
"schema_simp",
53+
"schema_adv",
54+
"schema_ext",
55+
"schema_uuid",
56+
"schema_type_aliases",
57+
"schema_obj",
58+
"db_creds_root",
59+
"db_creds_test",
60+
}
61+
# Tests that use these fixtures require MinIO
62+
minio_fixtures = {
63+
"minio_client",
64+
"s3fs_client",
65+
"s3_creds",
66+
"stores_config",
67+
"mock_stores",
68+
}
69+
70+
for item in items:
71+
# Get all fixtures this test uses (directly or indirectly)
72+
try:
73+
fixturenames = set(item.fixturenames)
74+
except AttributeError:
75+
continue
76+
77+
# Auto-add marks based on fixture usage
78+
if fixturenames & mysql_fixtures:
79+
item.add_marker(pytest.mark.requires_mysql)
80+
if fixturenames & minio_fixtures:
81+
item.add_marker(pytest.mark.requires_minio)
82+
83+
3184
# =============================================================================
3285
# Container Fixtures - Auto-start MySQL and MinIO via testcontainers
3386
# =============================================================================
@@ -177,9 +230,13 @@ def s3_creds(minio_container) -> Dict:
177230
# =============================================================================
178231

179232

180-
@pytest.fixture(scope="session", autouse=True)
233+
@pytest.fixture(scope="session")
181234
def configure_datajoint(db_creds_root):
182-
"""Configure DataJoint to use test database."""
235+
"""Configure DataJoint to use test database.
236+
237+
This fixture is NOT autouse - it only runs when a test requests
238+
a fixture that depends on it (e.g., connection_root_bare).
239+
"""
183240
# Parse host:port from credentials
184241
host_port = db_creds_root["host"]
185242
if ":" in host_port:
@@ -200,7 +257,7 @@ def configure_datajoint(db_creds_root):
200257

201258

202259
@pytest.fixture(scope="session")
203-
def connection_root_bare(db_creds_root):
260+
def connection_root_bare(db_creds_root, configure_datajoint):
204261
"""Bare root connection without user setup."""
205262
connection = dj.Connection(**db_creds_root)
206263
yield connection

tests/integration/test_schema.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ def test_schema_list(schema_any):
6666
assert schema_any.database in schemas
6767

6868

69-
def test_drop_unauthorized():
70-
info_schema = dj.schema("information_schema")
69+
@pytest.mark.requires_mysql
70+
def test_drop_unauthorized(connection_test):
71+
"""Test that dropping information_schema raises AccessError."""
72+
info_schema = dj.schema("information_schema", connection=connection_test)
7173
with pytest.raises(dj.errors.AccessError):
7274
info_schema.drop()
7375

0 commit comments

Comments
 (0)