Skip to content

Commit 75ccd76

Browse files
authored
Merge pull request #541 from dbt-msft/540-units-tests-not-working-as-expected
540 units tests not working as expected
2 parents 9e33d21 + d2ef335 commit 75ccd76

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{% macro sqlserver__get_unit_test_sql(main_sql, expected_fixture_sql, expected_column_names) -%}
2+
3+
USE [{{ target.database }}];
4+
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = '{{ target.schema }}')
5+
BEGIN
6+
EXEC('CREATE SCHEMA [{{ target.schema }}]')
7+
END
8+
9+
{% set test_view %}
10+
[{{ target.schema }}.testview_{{ range(1300, 19000) | random }}]
11+
{% endset %}
12+
{% set test_sql = main_sql.replace("'", "''")%}
13+
EXEC('create view {{test_view}} as {{ test_sql }};')
14+
15+
{% set expected_view %}
16+
[{{ target.schema }}.expectedview_{{ range(1300, 19000) | random }}]
17+
{% endset %}
18+
{% set expected_sql = expected_fixture_sql.replace("'", "''")%}
19+
EXEC('create view {{expected_view}} as {{ expected_sql }};')
20+
21+
-- Build actual result given inputs
22+
{% set unittest_sql %}
23+
with dbt_internal_unit_test_actual as (
24+
select
25+
{% for expected_column_name in expected_column_names %}{{expected_column_name}}{% if not loop.last -%},{% endif %}{%- endfor -%}, {{ dbt.string_literal("actual") }} as {{ adapter.quote("actual_or_expected") }}
26+
from
27+
{{ test_view }}
28+
),
29+
-- Build expected result
30+
dbt_internal_unit_test_expected as (
31+
select
32+
{% for expected_column_name in expected_column_names %}{{expected_column_name}}{% if not loop.last -%}, {% endif %}{%- endfor -%}, {{ dbt.string_literal("expected") }} as {{ adapter.quote("actual_or_expected") }}
33+
from
34+
{{ expected_view }}
35+
)
36+
-- Union actual and expected results
37+
select * from dbt_internal_unit_test_actual
38+
union all
39+
select * from dbt_internal_unit_test_expected
40+
{% endset %}
41+
42+
EXEC('{{- escape_single_quotes(unittest_sql) -}}')
43+
44+
EXEC('drop view {{test_view}};')
45+
EXEC('drop view {{expected_view}};')
46+
47+
{%- endmacro %}

dbt/include/sqlserver/macros/readme.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,7 @@ DBT expects a limit function, but the sqlserver syntax does not support it. Fabr
4848
## `sqlserver__snapshot_merge_sql`
4949

5050
Restores logic to the merge statement logic like the dbt core. Merge will probably be slower then the existing logic
51+
52+
## unit tests
53+
54+
To accomidate the nested CTE situation, we create a temp view for the actual/expected and use those both in the test.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import pytest
2+
from dbt.tests.adapter.unit_testing.test_case_insensitivity import BaseUnitTestCaseInsensivity
3+
from dbt.tests.adapter.unit_testing.test_invalid_input import BaseUnitTestInvalidInput
4+
from dbt.tests.adapter.unit_testing.test_types import BaseUnitTestingTypes
5+
from dbt.tests.util import run_dbt, write_file
6+
7+
my_model_sql = """
8+
select
9+
tested_column from {{ ref('my_upstream_model')}}
10+
"""
11+
12+
my_upstream_model_sql = """
13+
select
14+
{sql_value} as tested_column
15+
"""
16+
17+
test_my_model_yml = """
18+
unit_tests:
19+
- name: test_my_model
20+
model: my_model
21+
given:
22+
- input: ref('my_upstream_model')
23+
rows:
24+
- {{ tested_column: {yaml_value} }}
25+
expect:
26+
rows:
27+
- {{ tested_column: {yaml_value} }}
28+
"""
29+
30+
31+
class TestUnitTestCaseInsensitivity(BaseUnitTestCaseInsensivity):
32+
pass
33+
34+
35+
class TestUnitTestInvalidInput(BaseUnitTestInvalidInput):
36+
pass
37+
38+
39+
class TestUnitTestingTypes(BaseUnitTestingTypes):
40+
@pytest.fixture
41+
def data_types(self):
42+
# sql_value, yaml_value
43+
return [
44+
["1", "1"],
45+
["'1'", "1"],
46+
["1", "true"],
47+
["CAST('2020-01-02' AS DATE)", "2020-01-02"],
48+
["CAST('2013-11-03 00:00:00-0' AS DATETIME2(6))", "2013-11-03 00:00:00-0"],
49+
["CAST('2013-11-03 00:00:00-0' AS DATETIME2(6))", "2013-11-03 00:00:00-0"],
50+
["CAST('1' AS numeric)", "1"],
51+
]
52+
53+
def test_unit_test_data_type(self, project, data_types):
54+
for sql_value, yaml_value in data_types:
55+
# Write parametrized type value to sql files
56+
write_file(
57+
my_upstream_model_sql.format(sql_value=sql_value),
58+
"models",
59+
"my_upstream_model.sql",
60+
)
61+
62+
# Write parametrized type value to unit test yaml definition
63+
write_file(
64+
test_my_model_yml.format(yaml_value=yaml_value),
65+
"models",
66+
"schema.yml",
67+
)
68+
69+
results = run_dbt(["run", "--select", "my_upstream_model"])
70+
assert len(results) == 1
71+
72+
try:
73+
run_dbt(["test", "--select", "my_model"])
74+
except Exception:
75+
raise AssertionError(f"unit test failed when testing model with {sql_value}")

0 commit comments

Comments
 (0)