Skip to content

Commit

Permalink
Create a full external package for function test of a unit test with …
Browse files Browse the repository at this point in the history
…an external node

Previously we were only pseudo creating an external package for testing
how unit tests work with external nodes. This was problematic because the
package didn't actually exist and thus wasn't seen as accessible when running
through dag dependencies. By actually creating the external package, we
ensure that all the built in normal processes happen.
  • Loading branch information
QMalcolm committed Jan 19, 2024
1 parent b57a7f7 commit adeb324
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 25 deletions.
41 changes: 41 additions & 0 deletions tests/functional/unit_testing/fixtures.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

my_model_vars_sql = """
SELECT
a+b as c,
Expand Down Expand Up @@ -679,3 +681,42 @@
CASE WHEN joined.tld IS NULL THEN FALSE ELSE TRUE END AS is_valid_email_address
from joined
"""

external_package__accounts_seed_csv = """user_id,email,email_top_level_domain
1,"example@example.com","example.com"
"""

external_package__external_model_sql = """
SELECT user_id, email, email_top_level_domain FROM {{ ref('accounts_seed') }}
"""


external_package_project_yml = """
name: external_package
version: '1.0'
config-version: 2
model-paths: ["models"] # paths to models
analysis-paths: ["analyses"] # path with analysis files which are compiled, but not run
target-path: "target" # path for compiled code
clean-targets: ["target"] # directories removed by the clean task
test-paths: ["tests"] # where to store test results
seed-paths: ["seeds"] # load CSVs from this directory with `dbt seed`
macro-paths: ["macros"] # where to find macros
profile: user
models:
external_package:
"""


@pytest.fixture(scope="class")
def external_package():
return {
"dbt_project.yml": external_package_project_yml,
"seeds": {"accounts_seed.csv": external_package__accounts_seed_csv},
"models": {
"external_model.sql": external_package__external_model_sql,
},
}
35 changes: 10 additions & 25 deletions tests/functional/unit_testing/test_unit_testing.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import pytest
from unittest import mock
from dbt.tests.util import (
run_dbt,
write_file,
get_manifest,
)
from dbt.contracts.results import NodeStatus
from dbt.exceptions import DuplicateResourceNameError, ParsingError
from dbt.plugins.manifest import PluginNodes, ModelNodeArgs
from fixtures import (
from dbt.tests.fixtures.project import write_project_files
from fixtures import ( # noqa: F401
my_model_sql,
my_model_vars_sql,
my_model_a_sql,
Expand All @@ -21,6 +20,7 @@
test_my_model_yml_invalid,
valid_emails_sql,
top_level_domains_sql,
external_package,
)


Expand Down Expand Up @@ -285,24 +285,15 @@ def test_invalid_input_configuration(self, project):
- {user_id: 4, is_valid_email_address: true}
"""

external_node_seed_csv = """user_id,email,email_top_level_domain
1,"example@example.com","example.com"
"""


class TestUnitTestExternalNode:
@pytest.fixture(scope="class")
def external_model_node(self, unique_schema):
return ModelNodeArgs(
name="external_model",
package_name="external_package",
identifier="external_node_seed",
schema=unique_schema,
)
@pytest.fixture(scope="class", autouse=True)
def setUp(self, project_root, external_package): # noqa: F811
write_project_files(project_root, "external_package", external_package)

@pytest.fixture(scope="class")
def seeds(self):
return {"external_node_seed.csv": external_node_seed_csv}
def packages(self):
return {"packages": [{"local": "external_package"}]}

@pytest.fixture(scope="class")
def models(self):
Expand All @@ -312,18 +303,12 @@ def models(self):
"unit_test_ext_node.yml": unit_test_ext_node_yml,
}

@mock.patch("dbt.plugins.get_plugin_manager")
def test_unit_test_ext_nodes(
self,
get_plugin_manager,
project,
external_model_node,
):
# initial plugin - one external model
external_nodes = PluginNodes()
external_nodes.add_model(external_model_node)
get_plugin_manager.return_value.get_nodes.return_value = external_nodes

# `deps` to install the external package
run_dbt(["deps"], expect_pass=True)
# `seed` need so a table exists for `external_model` to point to
run_dbt(["seed"], expect_pass=True)
# `run` needed to ensure `top_level_domains` exists in database for column getting step
Expand Down

0 comments on commit adeb324

Please sign in to comment.