@@ -76,9 +76,13 @@ class = StreamHandler
7676
7777
7878BLACK_VERSION = "black==23.7.0"
79+ ISORT_VERSION = "isort==5.11.0"
7980BLACK_PATHS = ["google" , "test" , "noxfile.py" , "setup.py" , "samples" ]
80- UNIT_TEST_PYTHON_VERSIONS = ["3.9" , "3.10" , "3.11" , "3.12" , "3.13" , "3.14" ]
81- SYSTEM_TEST_PYTHON_VERSIONS = ["3.9" , "3.14" ]
81+ UNIT_TEST_PYTHON_VERSIONS = ["3.8" , "3.9" , "3.10" , "3.11" , "3.12" , "3.13" , "3.14" ]
82+ ALL_PYTHON = list (UNIT_TEST_PYTHON_VERSIONS )
83+ ALL_PYTHON .extend (["3.7" ])
84+ SYSTEM_TEST_PYTHON_VERSIONS = ["3.12" ]
85+ SYSTEM_COMPLIANCE_MIGRATION_TEST_PYTHON_VERSIONS = ["3.8" , "3.12" , "3.14" ]
8286DEFAULT_PYTHON_VERSION = "3.14"
8387DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 = "3.14"
8488
@@ -209,62 +213,6 @@ def compliance_test_20(session):
209213 )
210214
211215
212- @nox .session (python = SYSTEM_TEST_PYTHON_VERSIONS )
213- def system (session ):
214- """Run SQLAlchemy dialect system test suite."""
215-
216- # Sanity check: Only run tests if the environment variable is set.
217- if not os .environ .get ("GOOGLE_APPLICATION_CREDENTIALS" , "" ) and not os .environ .get (
218- "SPANNER_EMULATOR_HOST" , ""
219- ):
220- session .skip (
221- "Credentials or emulator host must be set via environment variable"
222- )
223-
224- if os .environ .get ("RUN_COMPLIANCE_TESTS" , "true" ) == "false" and not os .environ .get (
225- "SPANNER_EMULATOR_HOST" , ""
226- ):
227- session .skip ("RUN_COMPLIANCE_TESTS is set to false, skipping" )
228-
229- session .install (
230- "pytest" ,
231- "pytest-cov" ,
232- "pytest-asyncio" ,
233- )
234-
235- session .install ("mock" )
236- session .install (".[tracing]" )
237- session .install ("opentelemetry-api" )
238- session .install ("opentelemetry-sdk" )
239- session .install ("opentelemetry-instrumentation" )
240- session .run ("python" , "create_test_database.py" )
241-
242- session .install ("sqlalchemy>=2.0" )
243-
244- session .run ("py.test" , "--quiet" , os .path .join ("test" , "system" ), * session .posargs )
245-
246- session .run ("python" , "drop_test_database.py" )
247-
248-
249- @nox .session (python = UNIT_TEST_PYTHON_VERSIONS )
250- def unit (session ):
251- """Run unit tests."""
252- if session .python in ("3.7" ,):
253- session .skip ("Python 3.7 is no longer supported" )
254- # Run SQLAlchemy dialect compliance test suite with OpenTelemetry.
255- session .install ("setuptools" )
256- session .install ("pytest" )
257- session .install ("mock" )
258- session .install ("." )
259- session .install ("opentelemetry-api" )
260- session .install ("opentelemetry-sdk" )
261- session .install ("opentelemetry-instrumentation" )
262- session .run (
263- "python" , "create_test_config.py" , "my-project" , "my-instance" , "my-database"
264- )
265- session .run ("py.test" , "--quiet" , os .path .join ("test/unit" ), * session .posargs )
266-
267-
268216@nox .session (python = DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 )
269217def mockserver (session ):
270218 """Run mockserver tests."""
@@ -372,3 +320,99 @@ def snippets(session):
372320 os .path .join ("samples" , "snippets_test.py" ),
373321 * session .posargs ,
374322 )
323+
324+ @nox .session (python = ALL_PYTHON )
325+ @nox .parametrize ("test_type" , ["unit" , "mockserver" ])
326+ def unit (session , test_type ):
327+ """Run unit tests."""
328+ if session .python in ("3.7" ,):
329+ session .skip ("Python 3.7 is no longer supported" )
330+
331+ if test_type == "mockserver" and session .python != DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 :
332+ session .skip ("mockserver tests only run on python 3.14" )
333+
334+ if test_type == "mockserver" :
335+ mockserver (session )
336+ return
337+
338+ if test_type == "unit" :
339+ # Run SQLAlchemy dialect compliance test suite with OpenTelemetry.
340+ session .install ("setuptools" )
341+ session .install ("pytest" )
342+ session .install ("mock" )
343+ session .install ("." )
344+ session .install ("opentelemetry-api" )
345+ session .install ("opentelemetry-sdk" )
346+ session .install ("opentelemetry-instrumentation" )
347+ session .run (
348+ "python" , "create_test_config.py" , "my-project" , "my-instance" , "my-database"
349+ )
350+ session .run ("py.test" , "--quiet" , os .path .join ("test/unit" ), * session .posargs )
351+ return
352+
353+ @nox .session (python = SYSTEM_COMPLIANCE_MIGRATION_TEST_PYTHON_VERSIONS )
354+ @nox .parametrize ("test_type" , ["system" , "compliance_14" , "compliance_20" , "migration_14" , "migration_20" ])
355+ def system (session , test_type ):
356+ """Run SQLAlchemy dialect system test suite."""
357+
358+ if not os .environ .get ("GOOGLE_APPLICATION_CREDENTIALS" , "" ) and not os .environ .get (
359+ "SPANNER_EMULATOR_HOST" , ""
360+ ):
361+ session .skip (
362+ "Credentials or emulator host must be set via environment variable"
363+ )
364+
365+ if os .environ .get ("RUN_COMPLIANCE_TESTS" , "true" ) == "false" and not os .environ .get (
366+ "SPANNER_EMULATOR_HOST" , ""
367+ ):
368+ session .skip ("RUN_COMPLIANCE_TESTS is set to false, skipping" )
369+
370+ if test_type == "system" and session .python not in SYSTEM_TEST_PYTHON_VERSIONS :
371+ session .skip ("Standard system tests configured to run exclusively on 3.12" )
372+ if test_type in ["compliance_14" , "migration_14" ] and session .python != UNIT_TEST_PYTHON_VERSIONS [0 ]:
373+ session .skip (f"SQLAlchemy 1.4-based tests configured to run exclusively on { UNIT_TEST_PYTHON_VERSIONS [0 ]} " )
374+ if test_type in ["compliance_20" , "migration_20" ] and session .python != DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 :
375+ session .skip (f"SQLAlchemy 2.0-based tests configured to run exclusively on { DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 } " )
376+
377+ if test_type == "system" :
378+ session .install ("pytest" , "pytest-cov" , "pytest-asyncio" )
379+ session .install ("mock" )
380+ session .install (".[tracing]" )
381+ session .install ("opentelemetry-api" )
382+ session .install ("opentelemetry-sdk" )
383+ session .install ("opentelemetry-instrumentation" )
384+ session .run ("python" , "create_test_database.py" )
385+ session .install ("sqlalchemy>=2.0" )
386+ session .run ("py.test" , "--quiet" , os .path .join ("test" , "system" ), * session .posargs )
387+ session .run ("python" , "drop_test_database.py" )
388+ elif test_type == "compliance_14" :
389+ compliance_test_14 (session )
390+ elif test_type == "compliance_20" :
391+ compliance_test_20 (session )
392+ elif test_type == "migration_14" :
393+ migration_test (session )
394+ elif test_type == "migration_20" :
395+ _migration_test (session )
396+
397+ @nox .session (python = DEFAULT_PYTHON_VERSION )
398+ def mypy (session ):
399+ """Run the type checker."""
400+ session .skip ("mypy tests are not yet supported" )
401+
402+ @nox .session (python = DEFAULT_PYTHON_VERSION )
403+ def core_deps_from_source (session ):
404+ """Run all tests with core dependencies installed from source"""
405+ session .skip ("Core deps from source tests are not yet supported" )
406+
407+ @nox .session (python = DEFAULT_PYTHON_VERSION )
408+ def prerelease_deps (session ):
409+ """Run all tests with prerelease versions of dependencies installed."""
410+ session .skip ("prerelease deps tests are not yet supported" )
411+
412+ @nox .session
413+ def format (session : nox .sessions .Session ) -> None :
414+ session .install (BLACK_VERSION , ISORT_VERSION )
415+ import os
416+ python_files = [path for path in os .listdir ("." ) if path .endswith (".py" )]
417+ session .run ("isort" , "--fss" , * python_files )
418+ session .run ("black" , * python_files )
0 commit comments