|
| 1 | +## SQLAlchemy Dialect Compliance Test Suite with Databricks |
| 2 | + |
| 3 | +The contents of the `test/` directory follow the SQLAlchemy developers' [guidance] for running the reusable dialect compliance test suite. Since not every test in the suite is applicable to every dialect, two options are provided to skip tests: |
| 4 | + |
| 5 | +- Any test can be skipped by subclassing its parent class, re-declaring the test-case and adding a `pytest.mark.skip` directive. |
| 6 | +- Any test that is decorated with a `@requires` decorator can be skipped by marking the indicated requirement as `.closed()` in `requirements.py` |
| 7 | + |
| 8 | +We prefer to skip test cases directly with the first method wherever possible. We only mark requirements as `closed()` if there is no easier option to avoid a test failure. This principally occurs in test cases where the same test in the suite is parametrized, and some parameter combinations are conditionally skipped depending on `requirements.py`. If we skip the entire test method, then we skip _all_ permutations, not just the combinations we don't support. |
| 9 | + |
| 10 | +## Regression, Unsupported, and Future test cases |
| 11 | + |
| 12 | +We maintain three files of test cases that we import from the SQLAlchemy source code: |
| 13 | + |
| 14 | +* **`_regression.py`** contains all the tests cases with tests that we expect to pass for our dialect. Each one is marked with `pytest.mark.reiewed` to indicate that we've evaluated it for relevance. This file only contains base class declarations. |
| 15 | +* **`_unsupported.py`** contains test cases that fail because of missing features in Databricks. We mark them as skipped with a `SkipReason` enumeration. If Databricks comes to support these features, those test or entire classes can be moved to `_regression.py`. |
| 16 | +* **`_future.py`** contains test cases that fail because of missing features in the dialect itself, but which _are_ supported by Databricks generally. We mark them as skipped with a `FutureFeature` enumeration. These are features that have not been prioritised or that do not violate our acceptance criteria. All of these test cases will eventually move to either `_regression.py`. |
| 17 | + |
| 18 | +In some cases, only certain tests in class should be skipped with a `SkipReason` or `FutureFeature` justification. In those cases, we import the class into `_regression.py`, then import it from there into one or both of `_future.py` and `_unsupported.py`. If a class needs to be "touched" by regression, unsupported, and future, the class will be imported in that order. If an entire class should be skipped, then we do not import it into `_regression.py` at all. |
| 19 | + |
| 20 | +## Running the reusable dialect tests |
| 21 | + |
| 22 | +``` |
| 23 | +poetry shell |
| 24 | +cd src/databricks/sqlalchemy/test |
| 25 | +python -m pytest test_suite.py --dburi \ |
| 26 | + "databricks://token:$access_token@$host?http_path=$http_path&catalog=$catalog&schema=$schema" |
| 27 | +``` |
| 28 | + |
| 29 | +Whatever schema you pass in the `dburi` argument should be empty. Some tests also require the presence of an empty schema named `test_schema`. Note that we plan to implement our own `provision.py` which SQLAlchemy can automatically use to create an empty schema for testing. But for now this is a manual process. |
| 30 | + |
| 31 | +You can run only reviewed tests by appending `-m "reviewed"` to the test runner invocation. |
| 32 | + |
| 33 | +You can run only the unreviewed tests by appending `-m "not reviewed"` instead. |
| 34 | + |
| 35 | +Note that because these tests depend on SQLAlchemy's custom pytest plugin, they are not discoverable by IDE-based test runners like VSCode or PyCharm and must be invoked from a CLI. |
| 36 | + |
| 37 | +## Running local unit and e2e tests |
| 38 | + |
| 39 | +Apart from the SQLAlchemy reusable suite, we maintain our own unit and e2e tests under the `test_local/` directory. These can be invoked from a VSCode or Pycharm since they don't depend on a custom pytest plugin. Due to pytest's lookup order, the `pytest.ini` which is required for running the reusable dialect tests, also conflicts with VSCode and Pycharm's default pytest implementation and overrides the settings in `pyproject.toml`. So to run these tests, you can delete or rename `pytest.ini`. |
| 40 | + |
| 41 | + |
| 42 | +[guidance]: "https://github.com/sqlalchemy/sqlalchemy/blob/rel_2_0_22/README.dialects.rst" |
0 commit comments