Repository: dbt-labs/dbt-core (language: python)

Issue:
Allow instances of generic data tests to be documented
### Describe the feature
Currently, you can document pretty much everything _but_ a [data test](https://docs.getdbt.com/docs/build/data-tests#overview) - if you try, it fails on a parsing error. This ticket is for [generic data tests](https://docs.getdbt.com/docs/build/data-tests#generic-data-tests). A separate ticket addresses [singular data tests](https://docs.getdbt.com/docs/build/data-tests#singular-data-tests): https://github.com/dbt-labs/dbt-core/issues/9005

### Acceptance criteria
- You can add a description to a generic test
- You can use a docs block to capture your test description
- That description shows up in the docs site

### Examples
```
version: 2

models:
  - name: orders
    columns:
      - name: order_id
        tests:
          - unique
            description: The order_id is unique for every row in the orders model
          - not_null
            description: '{{ doc("not_null_test") }}'
```

### Concerns

- adding documentation to tests will slow down parsing (full parse), particularly for really common tests like unique and not_null
- We have special processing to speed up unique and not_null test parsing. Would that have to change?
- Ensure the solution is performant
Allow instances of generic data tests to be documented
### Describe the feature
Currently, you can document pretty much everything _but_ a [data test](https://docs.getdbt.com/docs/build/data-tests#overview) - if you try, it fails on a parsing error. This ticket is for [generic data tests](https://docs.getdbt.com/docs/build/data-tests#generic-data-tests). A separate ticket addresses [singular data tests](https://docs.getdbt.com/docs/build/data-tests#singular-data-tests): https://github.com/dbt-labs/dbt-core/issues/9005

### Acceptance criteria
- You can add a description to a generic test
- You can use a docs block to capture your test description
- That description shows up in the docs site

### Examples
```
version: 2

models:
  - name: orders
    columns:
      - name: order_id
        tests:
          - unique
            description: The order_id is unique for every row in the orders model
          - not_null
            description: '{{ doc("not_null_test") }}'
```

### Concerns

- adding documentation to tests will slow down parsing (full parse), particularly for really common tests like unique and not_null
- We have special processing to speed up unique and not_null test parsing. Would that have to change?
- Ensure the solution is performant


Discussion / hints:
I would say that for me a `tests:` label would imply all kind of tests, including schema tests, but looking at the current naming it looks like the most reasonable.
Current names related to tests:
* data tests are in the `tests` folder, not data-tests
* in `dbt_project`we specify a folder for `test-paths`, not data-test-paths
I know we've discussed putting schema tests in the tests directory instead of the macros directory, but I don't recall what the resolution of that was. Is that on the roadmap somewhere?
@gshank @kwigley I'd like to use our discussion of this issue as a jumping-off point to discuss other test-related work we scoped out earlier this year, and to determine whether / which of these should go on the v1.0 list as well.

The ones that come to my mind are:
- https://github.com/fishtown-analytics/dbt/issues/3234
- https://github.com/fishtown-analytics/dbt/issues/3249
- https://github.com/fishtown-analytics/dbt/issues/3250
- https://github.com/fishtown-analytics/dbt/issues/3259
- https://github.com/fishtown-analytics/dbt/issues/3348

All of those would represent a breaking change to some degree. There's ways we can offer backwards compatibility; easier for some, harder for others.
Work: 
- New parser for tests
- Work will need to be done in partial parsing
- Involve doc blocks (perf hit)
This issue has been marked as Stale because it has been open for 180 days with no activity. If you would like the issue to remain open, please remove the stale label or comment on the issue, or it will be closed in 7 days.
I think the ticket activity doesn't reflect the demand for this feature, there has been at least 6 users asking about in on Slack this past year: https://getdbt.slack.com/archives/CBSQTAPLG/p1631304882432300

It might be because the wording used in the ticket has changed:
schema test → generic test
data test → singular test

I think custom tests are code as much as models and macros are, so documenting them is equally important.

> @jtcohen6: I think a new tests: key in .yml files is exactly how we'd want to do this. Singular tests wouldn't be too hard. Generic tests would be trickier, since the good version (IMO) allows for templated descriptions that includes the values of {{ model }}, {{ column_name }}, and potentially other arguments.

IMO, having the static description as is in written in the YAML without replacing the values would already be nice and useful, the more complex version could be kept for later.
I came to +1 this post.  Looking forward to support for documenting Singular Tests.  Thanks!
+1 from me too.
+1 from my side as well. It's quite important to be able to document what a test does.
+1 from me as well.
+1 from me too. 
+1
+1 
+1
+1
+1
+1
+1
+1 from me too.
+1
+1
+1 from me
+1 please
+1
+1
+1 please
+1 please!
The compiler doesn't complain when I set the description in a singular test's config block, but when the docs are rendered, it says "This test is not currently documented". 🤔

When you get to this, I'd like you to add `test-paths` to the default `doc-paths` so that I don't need to do anything weird to get the compiler to pick up the doc blocks for my tests.
+1
+1 from me too.  Given that tests are included in the docs, and that it's just good practice, it should be possible to document singular tests.
+1
+1
+1 please!
+1 from me!
+1
+1 

This should be a bug, not a feature request imo. As others have mentioned, dbt docs supports descriptions for tests, but it is not yet implemented in dbt core. When I write a custom generic test, the user sees the following under "Description"

> This test is not currently documented

This phrasing implies the ability to document the test exists.
+1
+1
+1
+1
+1

Also thought think this should be categorized as a bug.
+1
+1. My boss is going to think I'm lazy if he sees that "This test is not currently documented", so we should add that capability to `dbt-core` for sure.
Also need this. We are trying to let business users read the test output in a more user-friendly way. Adding a description to the test would allow developers to make a human-readable assertion.
+1
+1
+1
+1
+1
> +1
> 
> This should be a bug, not a feature request imo. As others have mentioned, dbt docs supports descriptions for tests, but it is not yet implemented in dbt core. When I write a custom generic test, the user sees the following under "Description"
> 
> > This test is not currently documented
> 
> This phrasing implies the ability to document the test exists.

@jomccr   Please note that generic tests can be documented as a Macro (inside `macros:` block in yaml). It is singular tests that cannot be documented as far as I know!!

You can create a `macros.yml` file inside `macros/` which refer both to macros and generic tests and it works, does not matter if your generic test is inside `macros` or `tests/generic` folder. 

As an example I'm providing the file `tests/generic/test_not_empty_string.sql` whose content is [1] and the yaml code that documents it [2], which is placed inside `macros/macros.yml`. I'm attaching the screenshot of the documentation as well:

![image](https://github.com/dbt-labs/dbt-core/assets/52705438/845efdbf-26af-4a9d-80da-a84d5b088d35)


[1]:
```
{% test not_empty_string(model, column_name) %}

/*
    Complementary test to default `not_null` test as it checks that there is not an empty string
*/

with only_relevant_column as (
    SELECT
        {{ column_name }}
    FROM
        {{ model }}
)

SELECT
    *
FROM
    only_relevant_column
WHERE
    {{ column_name }} = ''

{% endtest %}
```
[2]:
```
  - name: test_not_empty_string
    description: Complementary test to default `not_null` test as it checks that there is not an empty string. It only accepts columns of type string. It is deprecated as this functionality has been included in the custom implementation of `not_null`
    arguments:
      - name: model
        type: string
        description: Model Name
      - name: column_name
        type: string
        description: Column name that should not be an empty string
```
> > +1
> > This should be a bug, not a feature request imo. As others have mentioned, dbt docs supports descriptions for tests, but it is not yet implemented in dbt core. When I write a custom generic test, the user sees the following under "Description"
> > > This test is not currently documented
> > 
> > 
> > This phrasing implies the ability to document the test exists.
> 
> @jomccr Please note that generic tests can be documented as a Macro (inside `macros:` block in yaml). It is singular tests that cannot be documented as far as I know!!
> 
> You can create a `macros.yml` file inside `macros/` which refer both to macros and generic tests and it works, does not matter if your generic test is inside `macros` or `tests/generic` folder.
> 
> As an example I'm providing the file `tests/generic/test_not_empty_string.sql` whose content is [1] and the yaml code that documents it [2], which is placed inside `macros/macros.yml`. I'm attaching the screenshot of the documentation as well:
> 
> ![image](https://private-user-images.githubusercontent.com/52705438/292663386-845efdbf-26af-4a9d-80da-a84d5b088d35.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDQyMTc4NDUsIm5iZiI6MTcwNDIxNzU0NSwicGF0aCI6Ii81MjcwNTQzOC8yOTI2NjMzODYtODQ1ZWZkYmYtMjZhZi00YTlkLTgwZGEtYTg0ZDViMDg4ZDM1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAxMDIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMTAyVDE3NDU0NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWZiMjE1NGIxNDIzYzg5MTQxNzVmYjZmZTk3OWVlMjdiZTFjNzg4NjkzOTYxZjJmNTVhZTBiN2YwOWU5MWFmYTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.AAtLen3n4s2XfsktmStYbsk3jvq0A0-yJAk1XHsdnWQ)
> 
> [1]:
> 
> ```
> {% test not_empty_string(model, column_name) %}
> 
> /*
>     Complementary test to default `not_null` test as it checks that there is not an empty string
> */
> 
> with only_relevant_column as (
>     SELECT
>         {{ column_name }}
>     FROM
>         {{ model }}
> )
> 
> SELECT
>     *
> FROM
>     only_relevant_column
> WHERE
>     {{ column_name }} = ''
> 
> {% endtest %}
> ```
> 
> [2]:
> 
> ```
>   - name: test_not_empty_string
>     description: Complementary test to default `not_null` test as it checks that there is not an empty string. It only accepts columns of type string. It is deprecated as this functionality has been included in the custom implementation of `not_null`
>     arguments:
>       - name: model
>         type: string
>         description: Model Name
>       - name: column_name
>         type: string
>         description: Column name that should not be an empty string
> ```

This documents your test "as a macro" >> but is the same documentation generated when you view the test, linked in the model documentation?
+1 to be able to add descriptions to singular tests
I have finally got this to work in dbt cloud but it is not obvious.

My generic test (macro) is called check_row_count_not_zero and is stored under tests/generic.

To document this I have to update the macros.yml in the macros folder, note the name has to have the prefix test_

  - name: test_check_row_count_not_zero
    description: A generic test that will throw and error is a model has zero rows.
    arguments:
      - name: model
        type: char
        description: The name of the model to test for zero rows.

With this the documentation now shows

Description
A generic test that will throw and error is a model has zero rows.
+1 to be able to add descriptions to singular tests
+1 to be able to add descriptions to singular tests
+1 to be able to add descriptions to singular tests
@dbeatty10 , this thread makes me wonder, what is the official way dbt Labs tracks feature requests?  Most platforms have an idea page with an upvote count and their product team works on the most upvoted ideas.  In this case, everyone is randomly "+1"ing and there's no way for anyone to tell this is a popular idea.

Should we be doing something else?
I would say that for me a `tests:` label would imply all kind of tests, including schema tests, but looking at the current naming it looks like the most reasonable.
Current names related to tests:
* data tests are in the `tests` folder, not data-tests
* in `dbt_project`we specify a folder for `test-paths`, not data-test-paths
I know we've discussed putting schema tests in the tests directory instead of the macros directory, but I don't recall what the resolution of that was. Is that on the roadmap somewhere?
@gshank @kwigley I'd like to use our discussion of this issue as a jumping-off point to discuss other test-related work we scoped out earlier this year, and to determine whether / which of these should go on the v1.0 list as well.

The ones that come to my mind are:
- https://github.com/fishtown-analytics/dbt/issues/3234
- https://github.com/fishtown-analytics/dbt/issues/3249
- https://github.com/fishtown-analytics/dbt/issues/3250
- https://github.com/fishtown-analytics/dbt/issues/3259
- https://github.com/fishtown-analytics/dbt/issues/3348

All of those would represent a breaking change to some degree. There's ways we can offer backwards compatibility; easier for some, harder for others.
Work: 
- New parser for tests
- Work will need to be done in partial parsing
- Involve doc blocks (perf hit)
This issue has been marked as Stale because it has been open for 180 days with no activity. If you would like the issue to remain open, please remove the stale label or comment on the issue, or it will be closed in 7 days.
I think the ticket activity doesn't reflect the demand for this feature, there has been at least 6 users asking about in on Slack this past year: https://getdbt.slack.com/archives/CBSQTAPLG/p1631304882432300

It might be because the wording used in the ticket has changed:
schema test → generic test
data test → singular test

I think custom tests are code as much as models and macros are, so documenting them is equally important.

> @jtcohen6: I think a new tests: key in .yml files is exactly how we'd want to do this. Singular tests wouldn't be too hard. Generic tests would be trickier, since the good version (IMO) allows for templated descriptions that includes the values of {{ model }}, {{ column_name }}, and potentially other arguments.

IMO, having the static description as is in written in the YAML without replacing the values would already be nice and useful, the more complex version could be kept for later.
I came to +1 this post.  Looking forward to support for documenting Singular Tests.  Thanks!
+1 from me too.
+1 from my side as well. It's quite important to be able to document what a test does.
+1 from me as well.
+1 from me too. 
+1
+1 
+1
+1
+1
+1
+1
+1 from me too.
+1
+1
+1 from me
+1 please
+1
+1
+1 please
+1 please!
The compiler doesn't complain when I set the description in a singular test's config block, but when the docs are rendered, it says "This test is not currently documented". 🤔

When you get to this, I'd like you to add `test-paths` to the default `doc-paths` so that I don't need to do anything weird to get the compiler to pick up the doc blocks for my tests.
+1
+1 from me too.  Given that tests are included in the docs, and that it's just good practice, it should be possible to document singular tests.
+1
+1
+1 please!
+1 from me!
+1
+1 

This should be a bug, not a feature request imo. As others have mentioned, dbt docs supports descriptions for tests, but it is not yet implemented in dbt core. When I write a custom generic test, the user sees the following under "Description"

> This test is not currently documented

This phrasing implies the ability to document the test exists.
+1
+1
+1
+1
+1

Also thought think this should be categorized as a bug.
+1
+1. My boss is going to think I'm lazy if he sees that "This test is not currently documented", so we should add that capability to `dbt-core` for sure.
Also need this. We are trying to let business users read the test output in a more user-friendly way. Adding a description to the test would allow developers to make a human-readable assertion.
+1
+1
+1
+1
+1
> +1
> 
> This should be a bug, not a feature request imo. As others have mentioned, dbt docs supports descriptions for tests, but it is not yet implemented in dbt core. When I write a custom generic test, the user sees the following under "Description"
> 
> > This test is not currently documented
> 
> This phrasing implies the ability to document the test exists.

@jomccr   Please note that generic tests can be documented as a Macro (inside `macros:` block in yaml). It is singular tests that cannot be documented as far as I know!!

You can create a `macros.yml` file inside `macros/` which refer both to macros and generic tests and it works, does not matter if your generic test is inside `macros` or `tests/generic` folder. 

As an example I'm providing the file `tests/generic/test_not_empty_string.sql` whose content is [1] and the yaml code that documents it [2], which is placed inside `macros/macros.yml`. I'm attaching the screenshot of the documentation as well:

![image](https://github.com/dbt-labs/dbt-core/assets/52705438/845efdbf-26af-4a9d-80da-a84d5b088d35)


[1]:
```
{% test not_empty_string(model, column_name) %}

/*
    Complementary test to default `not_null` test as it checks that there is not an empty string
*/

with only_relevant_column as (
    SELECT
        {{ column_name }}
    FROM
        {{ model }}
)

SELECT
    *
FROM
    only_relevant_column
WHERE
    {{ column_name }} = ''

{% endtest %}
```
[2]:
```
  - name: test_not_empty_string
    description: Complementary test to default `not_null` test as it checks that there is not an empty string. It only accepts columns of type string. It is deprecated as this functionality has been included in the custom implementation of `not_null`
    arguments:
      - name: model
        type: string
        description: Model Name
      - name: column_name
        type: string
        description: Column name that should not be an empty string
```
> > +1
> > This should be a bug, not a feature request imo. As others have mentioned, dbt docs supports descriptions for tests, but it is not yet implemented in dbt core. When I write a custom generic test, the user sees the following under "Description"
> > > This test is not currently documented
> > 
> > 
> > This phrasing implies the ability to document the test exists.
> 
> @jomccr Please note that generic tests can be documented as a Macro (inside `macros:` block in yaml). It is singular tests that cannot be documented as far as I know!!
> 
> You can create a `macros.yml` file inside `macros/` which refer both to macros and generic tests and it works, does not matter if your generic test is inside `macros` or `tests/generic` folder.
> 
> As an example I'm providing the file `tests/generic/test_not_empty_string.sql` whose content is [1] and the yaml code that documents it [2], which is placed inside `macros/macros.yml`. I'm attaching the screenshot of the documentation as well:
> 
> ![image](https://private-user-images.githubusercontent.com/52705438/292663386-845efdbf-26af-4a9d-80da-a84d5b088d35.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDQyMTc4NDUsIm5iZiI6MTcwNDIxNzU0NSwicGF0aCI6Ii81MjcwNTQzOC8yOTI2NjMzODYtODQ1ZWZkYmYtMjZhZi00YTlkLTgwZGEtYTg0ZDViMDg4ZDM1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAxMDIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMTAyVDE3NDU0NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWZiMjE1NGIxNDIzYzg5MTQxNzVmYjZmZTk3OWVlMjdiZTFjNzg4NjkzOTYxZjJmNTVhZTBiN2YwOWU5MWFmYTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.AAtLen3n4s2XfsktmStYbsk3jvq0A0-yJAk1XHsdnWQ)
> 
> [1]:
> 
> ```
> {% test not_empty_string(model, column_name) %}
> 
> /*
>     Complementary test to default `not_null` test as it checks that there is not an empty string
> */
> 
> with only_relevant_column as (
>     SELECT
>         {{ column_name }}
>     FROM
>         {{ model }}
> )
> 
> SELECT
>     *
> FROM
>     only_relevant_column
> WHERE
>     {{ column_name }} = ''
> 
> {% endtest %}
> ```
> 
> [2]:
> 
> ```
>   - name: test_not_empty_string
>     description: Complementary test to default `not_null` test as it checks that there is not an empty string. It only accepts columns of type string. It is deprecated as this functionality has been included in the custom implementation of `not_null`
>     arguments:
>       - name: model
>         type: string
>         description: Model Name
>       - name: column_name
>         type: string
>         description: Column name that should not be an empty string
> ```

This documents your test "as a macro" >> but is the same documentation generated when you view the test, linked in the model documentation?
+1 to be able to add descriptions to singular tests
I have finally got this to work in dbt cloud but it is not obvious.

My generic test (macro) is called check_row_count_not_zero and is stored under tests/generic.

To document this I have to update the macros.yml in the macros folder, note the name has to have the prefix test_

  - name: test_check_row_count_not_zero
    description: A generic test that will throw and error is a model has zero rows.
    arguments:
      - name: model
        type: char
        description: The name of the model to test for zero rows.

With this the documentation now shows

Description
A generic test that will throw and error is a model has zero rows.
+1 to be able to add descriptions to singular tests
+1 to be able to add descriptions to singular tests
+1 to be able to add descriptions to singular tests
@dbeatty10 , this thread makes me wonder, what is the official way dbt Labs tracks feature requests?  Most platforms have an idea page with an upvote count and their product team works on the most upvoted ideas.  In this case, everyone is randomly "+1"ing and there's no way for anyone to tell this is a popular idea.

Should we be doing something else?

Fix patch:
diff --git a/.changes/unreleased/Fixes-20241014-212135.yaml b/.changes/unreleased/Fixes-20241014-212135.yaml
new file mode 100644
index 00000000000..8cc700095ba
--- /dev/null
+++ b/.changes/unreleased/Fixes-20241014-212135.yaml
@@ -0,0 +1,6 @@
+kind: Fixes
+body: Allow instances of generic data tests to be documented
+time: 2024-10-14T21:21:35.767115+01:00
+custom:
+    Author: aranke
+    Issue: "2578"


Test patch:
diff --git a/core/dbt/parser/generic_test_builders.py b/core/dbt/parser/generic_test_builders.py
index 6bca8300dae..1c9478734bf 100644
--- a/core/dbt/parser/generic_test_builders.py
+++ b/core/dbt/parser/generic_test_builders.py
@@ -136,6 +136,17 @@ def __init__(
         if self.namespace is not None:
             self.package_name = self.namespace
 
+        # If the user has provided a description for this generic test, use it
+        # Then delete the "description" argument to:
+        # 1. Avoid passing it into the test macro
+        # 2. Avoid passing it into the test name synthesis
+        # Otherwise, use an empty string
+        self.description: str = ""
+
+        if "description" in self.args:
+            self.description = self.args["description"]
+            del self.args["description"]
+
         # If the user has provided a custom name for this generic test, use it
         # Then delete the "name" argument to avoid passing it into the test macro
         # Otherwise, use an auto-generated name synthesized from test inputs
diff --git a/core/dbt/parser/schema_generic_tests.py b/core/dbt/parser/schema_generic_tests.py
index 9f2538f06f0..58be6dc94be 100644
--- a/core/dbt/parser/schema_generic_tests.py
+++ b/core/dbt/parser/schema_generic_tests.py
@@ -96,6 +96,7 @@ def create_test_node(
         test_metadata: Dict[str, Any],
         file_key_name: str,
         column_name: Optional[str],
+        description: str,
     ) -> GenericTestNode:
 
         HASH_LENGTH = 10
@@ -134,6 +135,7 @@ def get_hashable_md(data: Union[str, int, float, List, Dict]) -> Union[str, List
             "column_name": column_name,
             "checksum": FileHash.empty().to_dict(omit_none=True),
             "file_key_name": file_key_name,
+            "description": description,
         }
         try:
             GenericTestNode.validate(dct)
@@ -229,6 +231,7 @@ def parse_generic_test(
             column_name=column_name,
             test_metadata=metadata,
             file_key_name=file_key_name,
+            description=builder.description,
         )
         self.render_test_update(node, config, builder, schema_file_id)
 
diff --git a/tests/functional/generic_test_description/fixtures.py b/tests/functional/generic_test_description/fixtures.py
new file mode 100644
index 00000000000..2be2f2313ba
--- /dev/null
+++ b/tests/functional/generic_test_description/fixtures.py
@@ -0,0 +1,34 @@
+models__my_model_sql = """
+with my_cte as (
+    select 1 as id, 'blue' as color
+    union all
+    select 2 as id, 'green' as red
+    union all
+    select 3 as id, 'red' as red
+)
+select * from my_cte
+"""
+
+models__schema_yml = """
+models:
+  - name: my_model
+    columns:
+      - name: id
+        tests:
+          - unique:
+              description: "id must be unique"
+          - not_null
+      - name: color
+        tests:
+          - accepted_values:
+              values: ['blue', 'green', 'red']
+              description: "{{ doc('color_accepted_values') }}"
+"""
+
+models__doc_block_md = """
+{% docs color_accepted_values %}
+
+The `color` column must be one of 'blue', 'green', or 'red'.
+
+{% enddocs %}
+"""
diff --git a/tests/functional/generic_test_description/test_generic_test_description.py b/tests/functional/generic_test_description/test_generic_test_description.py
new file mode 100644
index 00000000000..cf68ff1c33c
--- /dev/null
+++ b/tests/functional/generic_test_description/test_generic_test_description.py
@@ -0,0 +1,32 @@
+import pytest
+
+from dbt.tests.util import get_artifact, run_dbt
+from tests.functional.generic_test_description.fixtures import (
+    models__doc_block_md,
+    models__my_model_sql,
+    models__schema_yml,
+)
+
+
+class TestBuiltinGenericTestDescription:
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {
+            "my_model.sql": models__my_model_sql,
+            "schema.yml": models__schema_yml,
+            "doc_block.md": models__doc_block_md,
+        }
+
+    def test_compile(self, project):
+        run_dbt(["compile"])
+        manifest = get_artifact(project.project_root, "target", "manifest.json")
+        assert len(manifest["nodes"]) == 4
+
+        nodes = {node["alias"]: node for node in manifest["nodes"].values()}
+
+        assert nodes["unique_my_model_id"]["description"] == "id must be unique"
+        assert nodes["not_null_my_model_id"]["description"] == ""
+        assert (
+            nodes["accepted_values_my_model_color__blue__green__red"]["description"]
+            == "The `color` column must be one of 'blue', 'green', or 'red'."
+        )
diff --git a/tests/unit/parser/test_parser.py b/tests/unit/parser/test_parser.py
index b9b414ebac2..d5f809252b3 100644
--- a/tests/unit/parser/test_parser.py
+++ b/tests/unit/parser/test_parser.py
@@ -279,6 +279,7 @@ def assertEqualNodes(node_one, node_two):
             - not_null:
                 severity: WARN
             - accepted_values:
+                description: Only primary colors are allowed in here
                 values: ['red', 'blue', 'green']
             - foreign_package.test_case:
                 arg: 100
@@ -631,6 +632,7 @@ def test__parse_basic_model_tests(self):
         self.assertEqual(tests[0].tags, [])
         self.assertEqual(tests[0].refs, [RefArgs(name="my_model")])
         self.assertEqual(tests[0].column_name, "color")
+        self.assertEqual(tests[0].description, "Only primary colors are allowed in here")
         self.assertEqual(tests[0].package_name, "snowplow")
         self.assertTrue(tests[0].name.startswith("accepted_values_"))
         self.assertEqual(tests[0].fqn, ["snowplow", tests[0].name])
@@ -654,7 +656,7 @@ def test__parse_basic_model_tests(self):
         self.assertEqual(tests[1].tags, [])
         self.assertEqual(tests[1].refs, [RefArgs(name="my_model")])
         self.assertEqual(tests[1].column_name, "color")
-        self.assertEqual(tests[1].column_name, "color")
+        self.assertEqual(tests[1].description, "")
         self.assertEqual(tests[1].fqn, ["snowplow", tests[1].name])
         self.assertTrue(tests[1].name.startswith("foreign_package_test_case_"))
         self.assertEqual(tests[1].package_name, "snowplow")