Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional functional test for unit testing selection, artifacts, etc #8639

Merged
merged 2 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/Under the Hood-20230912-190506.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Under the Hood
body: Add unit testing functional tests
time: 2023-09-12T19:05:06.023126-04:00
custom:
Author: gshank
Issue: "8512"
58 changes: 55 additions & 3 deletions tests/functional/unit_testing/test_unit_testing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from dbt.tests.util import run_dbt
from dbt.tests.util import run_dbt, write_file, get_manifest, get_artifact
from dbt.exceptions import DuplicateResourceNameError

my_model_sql = """
SELECT
Expand Down Expand Up @@ -86,6 +87,11 @@
- {id: 1, string_b: b}
expect:
- {string_c: ab}
config:
tags: test_this
"""

datetime_test = """
- name: test_my_model_datetime
given:
- input: ref('my_model_a')
Expand All @@ -106,17 +112,63 @@ def models(self):
"my_model.sql": my_model_sql,
"my_model_a.sql": my_model_a_sql,
"my_model_b.sql": my_model_b_sql,
"test_my_model.yml": test_my_model_yml,
"test_my_model.yml": test_my_model_yml + datetime_test,
}

@pytest.fixture(scope="class")
def project_config_update(self):
return {"vars": {"my_test": "my_test_var"}}

def test_basic(self, project):
run_dbt(["deps"])
results = run_dbt(["run"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ can't comment one line above but - I don't think the run_dbt(["deps"]) is necessary here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. That was left over from an unnecessary dependency that was removed.

assert len(results) == 3

# Select by model name
results = run_dbt(["unit-test", "--select", "my_model"], expect_pass=False)
assert len(results) == 5

# Test select by test name
results = run_dbt(["unit-test", "--select", "test_name:test_my_model_string_concat"])
assert len(results) == 1

# Select, method not specified
results = run_dbt(["unit-test", "--select", "test_my_model_overrides"])
assert len(results) == 1

# Select using tag
results = run_dbt(["unit-test", "--select", "tag:test_this"])
assert len(results) == 1
Comment on lines +130 to +140
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about splitting these assertions into their own test - perhaps test_selection? They will still require the call to run_dbt(["run"]) as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer that, but having more than one test method per test class leads to flaky tests, which would probably happen here due to the partial parsing test.


# Partial parsing... remove test
write_file(test_my_model_yml, project.project_root, "models", "test_my_model.yml")
results = run_dbt(["unit-test", "--select", "my_model"], expect_pass=False)
assert len(results) == 4

# Partial parsing... put back removed test
write_file(
test_my_model_yml + datetime_test, project.project_root, "models", "test_my_model.yml"
)
results = run_dbt(["unit-test", "--select", "my_model"], expect_pass=False)
assert len(results) == 5

manifest = get_manifest(project.project_root)
assert len(manifest.unit_tests) == 5
# Every unit test has a depends_on to the model it tests
for unit_test_definition in manifest.unit_tests.values():
assert unit_test_definition.depends_on.nodes[0] == "model.test.my_model"

# We should have a UnitTestNode for every test, plus two input models for each test
unit_test_manifest = get_artifact(
project.project_root, "target", "unit_test_manifest.json"
)
assert len(unit_test_manifest["nodes"]) == 15

# Check for duplicate unit test name
write_file(
test_my_model_yml + datetime_test + datetime_test,
project.project_root,
"models",
"test_my_model.yml",
)
with pytest.raises(DuplicateResourceNameError):
run_dbt(["unit-test", "--select", "my_model"])