Testing the Extension
Relevant source files
The following files were used as context for generating this wiki page:
Testing the Meltano dbt extension focuses on verifying the integration between the Meltano Extension Developer Kit (EDK) and the underlying dbt CLI. The primary goal is to ensure that the extension correctly handles environment configurations, initialization of project files, and the logic governing pre-invoke hooks which automate standard dbt workflows.
The test suite utilizes pytest along with mocking to validate that commands like dbt clean and dbt deps are executed or skipped according to the extension's configuration settings and the specific command being invoked.
Sources: tests/test_dbt_ext.py:1-40, pyproject.toml:26-30
Test Infrastructure and Dependencies
The testing environment is defined within the project configuration, specifying the necessary tools for development and quality assurance.
| Tool | Purpose | Source |
|---|---|---|
pytest | Primary testing framework for executing unit tests. | pyproject.toml:27 |
monkeypatch | Used to safely set environment variables like DBT_EXT_TYPE during tests. | tests/test_dbt_ext.py:9 |
unittest.mock | Used to mock the dbt_invoker and verify command execution. | tests/test_dbt_ext.py:1 |
ruff | Linting and static analysis tool defined in dev dependencies. | pyproject.toml:28 |
Core Logic Validation
The extension's logic is primarily tested through two main areas: application metadata and the pre-invoke hook mechanism.
Application Metadata
Tests verify that the typer application is correctly initialized with the expected name. This ensures that the CLI interface presented to Meltano is consistent.
Sources: tests/test_dbt_ext.py:8-12, dbt_ext/main.py:18-22
Pre-invoke Hook Logic
The pre_invoke method in the dbt class contains logic to automatically run dbt clean and dbt deps before other commands. Testing verifies three specific conditions:
- Explicit Skip: When
DBT_EXT_SKIP_PRE_INVOKEis set totrue, no pre-invoke commands should run. - Command Exclusion: Commands like
depsandcleanthemselves should not trigger the pre-invoke hook to avoid infinite recursion or redundant work. - Execution: Standard commands (e.g.,
run,test,build) should trigger bothcleananddepssequentially if skipping is not enabled.
The following sequence diagram illustrates how the pre_invoke logic is validated during a test run for a standard command like dbt run.
Configuration Testing
Testing also involves ensuring the extension reacts correctly to the environment variables and settings defined in the Meltano manifest (discovery.yml or meltano.yml).
Environment Variable Handling
The extension requires DBT_EXT_TYPE to be set to identify the database profile. If missing, the extension is designed to raise a MissingProfileTypeError.
def test_app_name(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("DBT_EXT_TYPE", "test")
from dbt_ext.main import app
assert app.info.name == "dbt"
Sources: tests/test_dbt_ext.py:9-12, dbt_ext/extension.py:34-45
Configurable Settings
The following table maps the settings defined in the project to the environment variables that the test suite manipulates to verify behavior.
| Setting Name | Environment Variable | Default | Expected Behavior in Tests |
|---|---|---|---|
skip_pre_invoke | DBT_EXT_SKIP_PRE_INVOKE | false | If true, dbt clean/deps are not called. |
type | DBT_EXT_TYPE | N/A | Must be set for the extension to initialize. |
project_dir | DBT_PROJECT_DIR | transform | Defines the cwd for the dbt invoker. |
Sources: README.md:16-30, dbt_ext/extension.py:40-49
Conclusion
Testing the dbt extension ensures that the automation provided by the Meltano EDK wrapper—specifically the synchronization of dependencies via dbt deps and environment cleanup via dbt clean—functions correctly without interfering with native dbt commands. By mocking the Invoker class, the tests provide high confidence in the extension's internal state management and command flow.
README.md provides the manual verification steps often performed alongside these automated tests.
Sources: tests/test_dbt_ext.py:1-40, dbt_ext/extension.py:53-83