dbt-tests-adapter suite, packaging, Trusted Adapter Program
Заключительный урок модуля — comprehensive review of adapter testing, packaging, и пути к Trusted Adapter Program (TAP). Это production discipline для serious adapter projects.
pytest: test discovery и AAA pattern Fixtures и scope hierarchy в pytest
dbt-tests-adapter package
Что это: Pip package от dbt Labs с base test classes. Used для adapter conformance testing.
Install:
pip install dbt-tests-adapter
Source: https://github.com/dbt-labs/dbt-adapters/tree/main/dbt-tests-adapter
Содержит ~50 test classes covering:
Basic operations
BaseSimpleMaterializations— view, table, ephemeralBaseEphemeral— ephemeral materialization edge casesBaseValidateConnection— connection validation
Generic tests
BaseGenericTests— unique, not_null, accepted_values, relationshipsBaseSingularTests— singular SQL tests
Materializations
BaseIncremental— basic incrementalBaseIncrementalUniqueKey— incremental с unique_keyBaseIncrementalOnSchemaChange— schema evolutionBaseIncrementalNotSchemaChange— vs schema change
Snapshots
BaseSnapshots— timestamp strategyBaseSnapshotCheckCols— check strategyBaseSnapshotTimestamps— timestamp edge casesBaseSnapshotHardDeletes— hard_deletes config
Seeds
BaseSeeds— basic seedsBaseSeedColumnQuoting— column name quotingBaseSeedTimezone— timezone handling
Concurrency
BaseConcurrency— parallel runs
Schema management
BaseConstraintsRuntimeDdlEnforcement— constraintsBaseConstraintsRollback— rollback on constraint violationBaseModelContractsConstraints— contracts
Docs
BaseDocsGenerate— docs generationBaseDocsGenerateBase— baseBasePersistDocs— persist docs to warehouse
Exposures
BaseExposures— exposures работают
Sources
BaseSourceFreshness— source freshness
Grants
BaseGrants— basic grantsBaseIncrementalGrants— grants on incrementalBaseSnapshotGrants— grants on snapshotsBaseSeedGrants— grants on seeds
Operations
BaseRunOperation— run-operation commandBaseDbtClone— dbt clone command (1.7+)
How to integrate
В scaffold, tests/functional/adapter/test_basic.py:
from dbt.tests.adapter.basic.test_base import BaseSimpleMaterializations
from dbt.tests.adapter.basic.test_singular_tests import BaseSingularTests
from dbt.tests.adapter.basic.test_singular_tests_ephemeral import BaseSingularTestsEphemeral
from dbt.tests.adapter.basic.test_empty import BaseEmpty
from dbt.tests.adapter.basic.test_ephemeral import BaseEphemeral
from dbt.tests.adapter.basic.test_incremental import BaseIncremental
from dbt.tests.adapter.basic.test_generic_tests import BaseGenericTests
from dbt.tests.adapter.basic.test_snapshot_check_cols import BaseSnapshotCheckCols
from dbt.tests.adapter.basic.test_snapshot_timestamp import BaseSnapshotTimestamp
from dbt.tests.adapter.basic.test_adapter_methods import BaseAdapterMethod
from dbt.tests.adapter.basic.test_docs_generate import BaseDocsGenerate, BaseDocsGenerateReferences
class TestSimpleMaterializationsMyAdapter(BaseSimpleMaterializations):
pass
class TestSingularTestsMyAdapter(BaseSingularTests):
pass
class TestSingularTestsEphemeralMyAdapter(BaseSingularTestsEphemeral):
pass
class TestEmptyMyAdapter(BaseEmpty):
pass
class TestEphemeralMyAdapter(BaseEphemeral):
pass
class TestIncrementalMyAdapter(BaseIncremental):
pass
class TestGenericTestsMyAdapter(BaseGenericTests):
pass
class TestSnapshotCheckColsMyAdapter(BaseSnapshotCheckCols):
pass
class TestSnapshotTimestampMyAdapter(BaseSnapshotTimestamp):
pass
class TestBaseAdapterMethodMyAdapter(BaseAdapterMethod):
pass
class TestDocsGenerateMyAdapter(BaseDocsGenerate):
pass
class TestDocsGenReferencesMyAdapter(BaseDocsGenerateReferences):
pass
Каждый class — это inheritance. Tests run automatically.
Run:
pytest tests/functional/adapter/test_basic.py -v
Customization когда tests don’t fit
Sometimes base tests assume specific behavior. Override через fixtures:
class TestSimpleMaterializationsMyAdapter(BaseSimpleMaterializations):
@pytest.fixture(scope='class')
def project_config_update(self):
return {
'models': {
'+materialized': 'view',
}
}
@pytest.fixture(scope='class')
def expected_relation_types(self):
# Override expected relation types if your adapter differs
return {
'view_model': 'VIEW',
'table_model': 'BASE TABLE',
}
Other fixtures можно override:
project_files— model SQL filesseed_files— CSV filesmodels— model configssnapshots— snapshot configstests— test SQL
Opt-out approach
If warehouse genuinely doesn’t support feature, skip test:
class TestSnapshotsMyAdapter(BaseSnapshotCheckCols):
@pytest.mark.skip(reason='MyAdapter does not support check_cols strategy')
def test_snapshot_check_cols(self, project):
pass
Document opt-outs в README. Reasonable opt-outs accepted by TAP review.
Setup для адаптер тестов
Conftest.py (test setup):
# tests/conftest.py
import pytest
pytest_plugins = ['dbt.tests.fixtures.project']
def pytest_addoption(parser):
parser.addoption('--profile', action='store', default='myadapter', type=str)
@pytest.fixture(scope='class')
def dbt_profile_target():
return {
'type': 'myadapter',
'host': os.environ.get('DBT_TEST_HOST', 'localhost'),
'user': os.environ.get('DBT_TEST_USER', 'root'),
'password': os.environ.get('DBT_TEST_PASSWORD', ''),
'database': os.environ.get('DBT_TEST_DATABASE', 'test'),
'schema': os.environ.get('DBT_TEST_SCHEMA', 'public'),
}
Environment variables:
# .env (not committed)
DBT_TEST_HOST=localhost
DBT_TEST_USER=test_user
DBT_TEST_PASSWORD=test_pass
DBT_TEST_DATABASE=test_db
DBT_TEST_SCHEMA=test_schema
Local run:
source .env
pytest tests/functional/adapter/ -v
CI integration
GitHub Actions (генерирован cookiecutter):
# .github/workflows/test.yml
name: Adapter Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
myadapter:
image: myadapter/myadapter-ce:latest
ports:
- 5432:5432
env:
POSTGRES_PASSWORD: test
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install
run: |
pip install -e .
pip install -r dev-requirements.txt
- name: Run tests
run: pytest tests/functional/adapter/ -v
env:
DBT_TEST_HOST: localhost
DBT_TEST_USER: test
DBT_TEST_PASSWORD: test
DBT_TEST_DATABASE: postgres
Packaging для distribution
setup.py (для PyPI release):
from setuptools import setup, find_namespace_packages
VERSION = '1.0.0'
setup(
name='dbt-myadapter',
version=VERSION,
description='A dbt adapter for MyWarehouse',
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
author='Your Name',
author_email='[email protected]',
license='Apache-2.0',
url='https://github.com/your-org/dbt-myadapter',
packages=find_namespace_packages(include=['dbt.*']),
package_data={
'dbt': [
'include/myadapter/dbt_project.yml',
'include/myadapter/sample_profiles.yml',
'include/myadapter/profile_template.yml',
'include/myadapter/macros/*.sql',
'include/myadapter/macros/**/*.sql',
],
},
install_requires=[
'dbt-adapters>=1.7,<2.0',
'dbt-common>=1.10,<2.0',
'dbt-core>=1.8,<2.0',
'pymysql>=1.0',
],
python_requires='>=3.9',
classifiers=[
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: Apache Software License',
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS :: MacOS X',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
],
)
Build и upload:
python setup.py sdist bdist_wheel
twine upload dist/*
Now installable: pip install dbt-myadapter.
AdapterPlugin discovery
# dbt/adapters/myadapter/__init__.py
from dbt.adapters.myadapter.connections import MyConnectionManager, MyCredentials
from dbt.adapters.myadapter.impl import MyAdapter
from dbt.adapters.base import AdapterPlugin
from dbt.include import myadapter
Plugin = AdapterPlugin(
adapter=MyAdapter,
credentials=MyCredentials,
include_path=myadapter.PACKAGE_PATH,
)
How dbt-core discovers:
- User installs
pip install dbt-myadapter. - Pip places package в site-packages:
site-packages/dbt/adapters/myadapter/. - dbt-core scans
dbt.adapters.*namespace. - Finds
Pluginattribute в__init__.py. - Registers in
FACTORY.plugins['myadapter'] = Plugin. - User’s
profiles.yml type: myadapter-> finds Plugin -> instantiates adapter.
Без AdapterPlugin export — adapter не найден.
Trusted Adapter Program (TAP)
What it is: dbt Labs’ program признающий production-ready adapters.
Benefits:
- Listed на docs.getdbt.com/docs/trusted-adapters
- Discoverability через dbt Cloud Marketplace
- Community trust
- Endorsement by dbt Labs
Requirements:
- All dbt-tests-adapter pass (or documented opt-outs)
- Public GitHub repo с CI/CD
- PyPI package with regular releases
- Active maintainership:
- Responsive к issues
- Regular releases following dbt-core versions
- Public roadmap
- Documentation:
- README aligned с getdbt.com style
- Migration guides
- Examples
- Troubleshooting
- Security review:
- No hardcoded secrets
- Sensitive data sanitization
- Authentication best practices
Application process:
- Self-assessment — все criteria met?
- Submit application к dbt Labs (typically через GitHub issue или docs)
- Review — dbt Labs evaluates (1-2 months)
- Feedback — usually requested improvements
- Iterate — address feedback
- Approval — adapter listed
- Maintenance — continue maintenance per program
Timeline: 9-12 months from start to TAP listing.
Examples Trusted Adapters
Current Trusted Adapters (2026):
-
dbt-labs maintained (Tier 1):
- dbt-postgres, dbt-redshift, dbt-snowflake, dbt-bigquery, dbt-spark, dbt-duckdb
-
Community Trusted (Tier 2):
- dbt-databricks (Databricks)
- dbt-trino (Trino / Starburst)
- dbt-clickhouse (ClickHouse)
- dbt-doris (Doris)
- dbt-firebolt (Firebolt)
- dbt-impala (Impala)
- dbt-rockset (Rockset)
- dbt-singlestore (SingleStore)
- dbt-synapse (Azure Synapse)
- dbt-vertica (Vertica)
- dbt-greenplum (Greenplum)
- dbt-iotdb (Apache IoTDB)
- dbt-materialize (Materialize)
-
Community (not Trusted):
- Various proprietary, newer adapters
- Used at your own risk
Maintenance commitments
After TAP listing:
Release cadence:
- Follow dbt-core releases (minor version)
- Patch releases для bug fixes
- Major versions для breaking changes (with deprecation period)
Issue management:
- Acknowledge within 1 week
- Triage и label
- Critical security issues — fast turnaround
Community engagement:
- Slack channel (dbt-community)
- GitHub discussions
- Annual contributor meetings
Documentation:
- Keep up-to-date с dbt-core changes
- Update for new warehouse features
- Migration guides
This is long-term commitment. Adapters не one-shot projects.
Examples: dbt-snowflake structure
dbt-snowflake/
├── setup.py
├── pyproject.toml
├── README.md
├── LICENSE.md
├── CHANGELOG.md
├── .github/
│ └── workflows/
├── dbt/
│ ├── adapters/
│ │ └── snowflake/
│ │ ├── __init__.py
│ │ ├── __version__.py
│ │ ├── connections.py
│ │ ├── impl.py
│ │ ├── relation.py
│ │ ├── column.py
│ │ └── ...
│ └── include/
│ └── snowflake/
│ ├── dbt_project.yml
│ ├── profile_template.yml
│ ├── sample_profiles.yml
│ └── macros/
└── tests/
├── functional/
├── unit/
└── integration/
Standard structure across all Trusted Adapters.
Попробуй сам
- Install dbt-tests-adapter:
pip install dbt-tests-adapter
- Look at source:
find $(pip show dbt-tests-adapter | grep Location | cut -d' ' -f2)/dbt/tests/adapter -name "*.py" | head -20
- Read one test class —
test_base.py:
cat $(pip show dbt-tests-adapter | grep Location | cut -d' ' -f2)/dbt/tests/adapter/basic/test_base.py
Understand structure: setup fixtures, model/seed files, test methods.
-
In your adapter scaffold, add test_basic.py с base classes.
-
Run:
pytest tests/functional/adapter/ -v
Verbose output — see passing/failing tests.
- Iterate based on failures.
Ключевые выводы
-
dbt-tests-adapter — official conformance test suite. ~50 base test classes.
-
Integration через inheritance:
class TestX(BaseY): pass. No test code from вас. -
Customization через fixture overrides когда warehouse differs.
-
Opt-outs для truly unsupported features (с documentation).
-
Packaging: setup.py с namespace package + package_data для macros.
-
AdapterPlugin в
__init__.py— discovery point. -
Trusted Adapter Program — pathway для production credibility. 9-12 months timeline. Requires full tests pass, maintenance commitment, documentation, security review.
-
Trusted Adapters listed: dbt-postgres, dbt-snowflake, dbt-bigquery, dbt-duckdb, dbt-databricks, dbt-trino, etc.
-
Maintenance ongoing: follow dbt-core releases, respond к issues, community engagement.
-
Adapter development = months/years project. Plan accordingly.