-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Er/3250 generic tests #4052
Er/3250 generic tests #4052
Conversation
core/dbt/contracts/graph/unparsed.py
Outdated
@@ -44,6 +44,12 @@ class UnparsedMacro(UnparsedBaseNode, HasSQL): | |||
resource_type: NodeType = field(metadata={'restrict': [NodeType.Macro]}) | |||
|
|||
|
|||
@dataclass | |||
class UnparsedGenericTest(UnparsedBaseNode, HasSQL): | |||
# TODO: should this be nodeType macro? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the long run we're probably going to want different NodeTypes for singular test and generic test. I don't know if that's something that we want to do now or not though.
core/dbt/parser/manifest.py
Outdated
|
||
self.build_macro_resolver() | ||
# Look at changed macros and update the macro.depends_on.macros | ||
self.macro_depends_on() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to do this twice, once for macros and once for tests. It should be done just once, after both macros and tests are in the 'macros' dictionary.
project, files, project.test_paths, '.sql', ParseFileType.SingularTest, saved_files | ||
) | ||
|
||
project_files['GenericTestParser'] = read_files_for_parser( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like a problem to me. Every file in the 'tests' directory is going to be added to both the SingularTestParser and the GenericTestParser. I'm not exactly sure what the implications are, but I think it will make partial parsing for these files impossible. I think we might have to peek into the files and allocate them to either Singular or Generic, not both. I'm going to think about this some more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the main thing I don't like about this approach. It does work as I understand the tests to be structured. Singular tests end up getting ignored by generic tests because they're not in a jinja test block. And I'm purposefully ignoring generic tests in the singular test code by specifically checking to see if they're in jinja blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File objects are saved in the 'files' dictionary under the file_id key, so the second run over the files would save a duplicated file object except with a differe parse_file_type.
We could use a different filetype for the generic tests, but longterm we may want to make "singular" tests look more like generic tests and put them in a file block, so that might not be the right path. We could also put them in a subdirectory of tests, like 'generic' (Jeremy's suggestion). We would also parse all of the tests when the test parser is processed, not at macro processing time, and have to separately do the 'macro_depends_on' for just tests. As long as the generic tests are in 'macros' prior to schema file processing it should be okay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My current vote is for a special directory, tests/generic
. That's a little jank, but it feels like a step in the right direction, and I like it more than having generic tests defined in macros/
forever.
What Gerda and I were discussing is an eventual future where all tests are defined as blocks, some with "singular" construction and others with "generic" construction, and they could be intermixed in the same .sql
files:
-- tests/my_tests.sql
{% test singular_not_null %}
select *
from {{ ref('orders') }}
where id is null
{% endtest %}
{% test not_null(model, column_name) %}
select *
from {{ model }}
where {{ column_name }} is null
{% endtest %}
There's history for this proposal (#2274) that goes pretty far back for all resource types (#184). Snapshots are the only real DAG node that ever made the switchover, from files to blocks. It's something we once imagined for v1.0, but deprioritized. It has the side-effect of making these queries harder, though certainly not impossible, to run in IDEs, since line/cursor location becomes important.
In the meantime, we can take an important step in that direction, without needing to get all the way there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked it to look for a generic
folder in test-paths
. Is this more along the lines of how you were thinking it would work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this looks good. We do end up with some generic tests having a Macro parse _file_type and some with a GenericTest parse file type. I'm not sure that's a problem, but it is something to be watchful for.
8ad1780
to
6ee9771
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The functional change here looks mostly good. Thanks for the flexibility in working toward a way to achieve this functionality ahead of v1.
I noticed that it was quite easy to trip a partial parsing error. Create any test in tests/generic/my_cool_test.sql
, parse the project, edit the file in any way, and re-parse the project (with partial parsing enabled):
Encountered an error:
Compilation Error
dbt found two macros named "test_my_cool_test" in the project "testy".
To fix this error, rename or remove one of the following macros:
- tests/generic/my_cool_test.sql
- tests/generic/my_cool_test.sql
I only have one test there by that name, so it's an issue with not removing the test macro before scheduling it for re-parsing.
In core/dbt/parser/partial.py, the GenericTest filetype does not belong in the mssat_files. It needs to be handled with the 'Macro' files. There are a number of places in core/dbt/parser/partial.py where it checks for a ParseFileType of Macro. Those places also need to check for a ParseFileType of GenericTest. You could make a list of the two of them, like the mssat_files list. |
It would probably be a good idea to add a partial parsing test with a test/generic test file to the 068_partial_parsing_tests. |
6ee9771
to
2017b1d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
The substance of this change looks good to me. As above, I'm seeing an issue with partial parsing. It no longer raises an exception, but every time I edit a test defined in
That's a step in the right direction, but I'd like to resolve that exception before merging. I threw a debugger into the partial parsing code, and it looks like the exception I'm tripping is:
|
2017b1d
to
31c142c
Compare
* removed overlooked breakpoint * first pass * save progress - singualr tests broken * fixed to work with both generic and singular tests * fixed formatting * added a comment * change to use /generic subfolder * fix formatting issues * fixed bug on code consolidation * fixed typo * added test for generic tests * added changelog entry * added logic to treat generic tests like macro tests * add generic test to macro_edges * fixed generic tests to match unique_ids * fixed test automatic commit by git-black, original commits: f79a968
resolves #3250
Description
Adding ability to have generic tests in the
/tests
directory.GenericTest
and renamedTest
to beSingularTest
/tests
directly after macros and before everything else.Checklist
CHANGELOG.md
and added information about my change