From 61fdb9ca30f95f168ac1443389cc2f49b45c2fbd Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:46:24 -0500 Subject: [PATCH 01/84] Adding multi cell --- .../cloud/about-cloud/regions-ip-addresses.md | 17 +++++++++++++++-- website/sidebars.js | 2 +- .../static/img/docs/dbt-cloud/find-account.png | Bin 0 -> 149254 bytes 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 website/static/img/docs/dbt-cloud/find-account.png diff --git a/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md b/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md index cc1c2531f56..641078f7602 100644 --- a/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md +++ b/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md @@ -1,6 +1,7 @@ --- -title: "Regions & IP addresses" -id: "regions-ip-addresses" +title: "Access, Regions, & IP addresses" +sidebar: "Access, Regions, & IP Addresses" +id: "access-regions-ip-addresses" description: "Available regions and ip addresses" --- @@ -20,6 +21,18 @@ dbt Cloud is [hosted](/docs/cloud/about-cloud/architecture) in multiple regions [^1]: These regions support [multi-tenant](/docs/cloud/about-cloud/tenancy) deployment environments hosted by dbt Labs. +## Accessing your account + +To login to dbt Cloud, use the URL that applies to your environment. Your access URL used will depend on a few factors including location and tenancy: +- **US multi-tenant:** Use your unique URL that starts with your account prefix, followed by `us1.dbt.com`. For example, `abc123.us1.dbt.com`. + - If you are unsure of your access URL, navigate to `us1.dbt.com` and enter your credentials. If you are a member of a single account, you will be logged in and your URL will be displayed in the browser. If you are a member of muliple accounts, you will be presented with a list of options, along with the appropriate login URLs for each + + + +- **EMEA multi-tenant:** Use the URL `emea.dbt.com`. +- **APAC multi-tenant:** Use the URL `au.dbt.com`. +- **Worldwide single-tenant and VPC:** Use the vanity URL provided during your onboarding. + ### Locating your dbt Cloud IP addresses There are two ways to view your dbt Cloud IP addresses: diff --git a/website/sidebars.js b/website/sidebars.js index 473dfe85e04..d02370efe30 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -28,7 +28,7 @@ const sidebarSettings = { "docs/cloud/about-cloud/dbt-cloud-features", "docs/cloud/about-cloud/architecture", "docs/cloud/about-cloud/tenancy", - "docs/cloud/about-cloud/regions-ip-addresses", + "docs/cloud/about-cloud/access-regions-ip-addresses", "docs/cloud/about-cloud/browsers", ], }, // About dbt Cloud directory diff --git a/website/static/img/docs/dbt-cloud/find-account.png b/website/static/img/docs/dbt-cloud/find-account.png new file mode 100644 index 0000000000000000000000000000000000000000..8d9bb5c21d21122ed667404b04c5d59f5f31b7a8 GIT binary patch literal 149254 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Ν!Y!X98 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 Date: Fri, 1 Dec 2023 14:26:50 -0500 Subject: [PATCH 02/84] Updating links to access --- contributing/content-style-guide.md | 6 +++--- website/docs/docs/build/metrics.md | 2 +- website/docs/docs/cloud/billing.md | 2 +- website/docs/docs/cloud/cloud-cli-installation.md | 2 +- .../docs/cloud/connect-data-platform/about-connections.md | 2 +- .../connect-redshift-postgresql-alloydb.md | 2 +- .../docs/docs/cloud/dbt-cloud-ide/develop-in-the-cloud.md | 2 +- website/docs/docs/cloud/git/connect-gitlab.md | 2 +- website/docs/docs/cloud/git/setup-azure.md | 4 ++-- website/docs/docs/cloud/manage-access/invite-users.md | 2 +- .../docs/docs/cloud/manage-access/set-up-bigquery-oauth.md | 2 +- .../docs/cloud/manage-access/set-up-databricks-oauth.md | 2 +- .../docs/docs/cloud/manage-access/set-up-snowflake-oauth.md | 6 +++--- .../docs/cloud/manage-access/set-up-sso-google-workspace.md | 2 +- website/docs/docs/cloud/manage-access/set-up-sso-okta.md | 4 ++-- website/docs/docs/dbt-cloud-apis/discovery-querying.md | 4 ++-- website/docs/docs/dbt-cloud-apis/migrating-to-v2.md | 2 +- website/docs/docs/dbt-cloud-apis/sl-jdbc.md | 2 +- .../release-notes/03-Oct-2023/api-v2v3-limit.md | 2 +- .../docs/dbt-versions/release-notes/03-Oct-2023/sl-ga.md | 2 +- .../release-notes/05-Aug-2023/sl-revamp-beta.md | 2 +- .../dbt-versions/release-notes/07-June-2023/admin-api-rn.md | 2 +- .../release-notes/09-April-2023/api-endpoint-restriction.md | 2 +- .../dbt-versions/release-notes/10-Mar-2023/apiv2-limit.md | 2 +- .../release-notes/11-Feb-2023/feb-ide-updates.md | 2 +- .../26-Sept-2022/liststeps-endpoint-deprecation.md | 2 +- website/docs/docs/deploy/dashboard-status-tiles.md | 6 +++--- website/docs/docs/deploy/run-visibility.md | 2 +- website/docs/docs/deploy/webhooks.md | 4 ++-- .../docs/docs/running-a-dbt-project/using-the-dbt-ide.md | 2 +- website/docs/docs/use-dbt-semantic-layer/tableau.md | 2 +- website/docs/faqs/API/rotate-token.md | 4 ++-- website/docs/faqs/Accounts/transfer-account.md | 4 ++-- ...how-to-use-databricks-workflows-to-run-dbt-cloud-jobs.md | 2 +- website/docs/guides/starburst-galaxy-qs.md | 2 +- website/snippets/_new-sl-setup.md | 2 +- website/snippets/_sl-connect-and-query-api.md | 2 +- website/snippets/_sl-plan-info.md | 2 +- website/snippets/_v2-sl-prerequisites.md | 6 +++--- website/snippets/login_url_note.md | 2 +- website/snippets/sl-public-preview-banner.md | 2 +- website/vercel.json | 2 +- 42 files changed, 56 insertions(+), 56 deletions(-) diff --git a/contributing/content-style-guide.md b/contributing/content-style-guide.md index 0d2bf243d45..ac8bc8192fa 100644 --- a/contributing/content-style-guide.md +++ b/contributing/content-style-guide.md @@ -544,14 +544,14 @@ The file or URL paths begin with: - /reference/ - /community/ -Let's use the Regions & IP Addresses URL as an example: https://docs.getdbt.com/docs/cloud/about-cloud/regions-ip-addresses +Let's use the Regions & IP Addresses URL as an example: https://docs.getdbt.com/docs/cloud/about-cloud/access-regions-ip-addresses If we need to reference this on another page, we can remove the domain entirely: -`For more information about server availability, please refer to our [Regions & IP Addresses page](/docs/cloud/about-cloud/regions-ip-addresses)` +`For more information about server availability, please refer to our [Regions & IP Addresses page](/docs/cloud/about-cloud/access-regions-ip-addresses)` The reader will see: -For more information about server availability, please refer to our [Regions & IP Addresses page](/docs/cloud/about-cloud/regions-ip-addresses) +For more information about server availability, please refer to our [Regions & IP Addresses page](/docs/cloud/about-cloud/access-regions-ip-addresses) You can link to a specific section of the doc with a `#` at the end of the path. Enter the section’s title after the `#`, with individual words separated by hyphens. Let's use the incremental models page, https://docs.getdbt.com/docs/build/incremental-models, as an example: diff --git a/website/docs/docs/build/metrics.md b/website/docs/docs/build/metrics.md index 7afcb41c2e4..87470ba3265 100644 --- a/website/docs/docs/build/metrics.md +++ b/website/docs/docs/build/metrics.md @@ -20,7 +20,7 @@ The dbt Semantic Layer has undergone a [significant revamp](https://www.getdbt.c The dbt_metrics package has been [deprecated](https://docs.getdbt.com/blog/deprecating-dbt-metrics) and replaced with [MetricFlow](/docs/build/about-metricflow?version=1.6), a new framework for defining metrics in dbt. This means dbt_metrics is no longer supported after dbt v1.5 and won't receive any code fixes. We will also remove the dbt_metrics spec and docs when it's fully deprecated. **Who does this affect?**

-Anyone who uses the dbt_metrics package or is integrated with the legacy Semantic Layer. The new Semantic Layer is available to [Team or Enterprise](https://www.getdbt.com/pricing/) multi-tenant dbt Cloud plans [hosted in North America](/docs/cloud/about-cloud/regions-ip-addresses). You must be on dbt v1.6 or higher to access it. All users can define metrics using MetricFlow. Users on dbt Cloud Developer plans or dbt Core can only use it to define and test metrics locally, but can't dynamically query them with integrated tools. +Anyone who uses the dbt_metrics package or is integrated with the legacy Semantic Layer. The new Semantic Layer is available to [Team or Enterprise](https://www.getdbt.com/pricing/) multi-tenant dbt Cloud plans [hosted in North America](/docs/cloud/about-cloud/access-regions-ip-addresses). You must be on dbt v1.6 or higher to access it. All users can define metrics using MetricFlow. Users on dbt Cloud Developer plans or dbt Core can only use it to define and test metrics locally, but can't dynamically query them with integrated tools. **What should you do?**

If you've defined metrics using dbt_metrics or integrated with the legacy Semantic Layer, we **highly** recommend you [upgrade your dbt version](/docs/dbt-versions/upgrade-core-in-cloud) to dbt v1.6 or higher to use MetricFlow or the new dbt Semantic Layer. To migrate to the new Semantic Layer, refer to the dedicated [migration guide](/guides/sl-migration) for more info. diff --git a/website/docs/docs/cloud/billing.md b/website/docs/docs/cloud/billing.md index 31b7689ceb9..e88a2a2d8dd 100644 --- a/website/docs/docs/cloud/billing.md +++ b/website/docs/docs/cloud/billing.md @@ -7,7 +7,7 @@ pagination_next: null pagination_prev: null --- -dbt Cloud offers a variety of [plans and pricing](https://www.getdbt.com/pricing/) to fit your organization’s needs. With flexible billing options that appeal to large enterprises and small businesses and [server availability](/docs/cloud/about-cloud/regions-ip-addresses) worldwide, dbt Cloud is the fastest and easiest way to begin transforming your data. +dbt Cloud offers a variety of [plans and pricing](https://www.getdbt.com/pricing/) to fit your organization’s needs. With flexible billing options that appeal to large enterprises and small businesses and [server availability](/docs/cloud/about-cloud/access-regions-ip-addresses) worldwide, dbt Cloud is the fastest and easiest way to begin transforming your data. ## How does dbt Cloud pricing work? diff --git a/website/docs/docs/cloud/cloud-cli-installation.md b/website/docs/docs/cloud/cloud-cli-installation.md index f3294477611..eaee8b6246b 100644 --- a/website/docs/docs/cloud/cloud-cli-installation.md +++ b/website/docs/docs/cloud/cloud-cli-installation.md @@ -23,7 +23,7 @@ dbt commands are run against dbt Cloud's infrastructure and benefit from: ## Prerequisites -The dbt Cloud CLI is available in all [deployment regions](/docs/cloud/about-cloud/regions-ip-addresses) and for both multi-tenant and single-tenant accounts (Azure single-tenant not supported at this time). +The dbt Cloud CLI is available in all [deployment regions](/docs/cloud/about-cloud/access-regions-ip-addresses) and for both multi-tenant and single-tenant accounts (Azure single-tenant not supported at this time). - Ensure you are using dbt version 1.5 or higher. Refer to [dbt Cloud versions](/docs/dbt-versions/upgrade-core-in-cloud) to upgrade. - Note that SSH tunneling for [Postgres and Redshift](/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb) connections and [Single sign-on (SSO)](/docs/cloud/manage-access/sso-overview) doesn't support the dbt Cloud CLI yet. diff --git a/website/docs/docs/cloud/connect-data-platform/about-connections.md b/website/docs/docs/cloud/connect-data-platform/about-connections.md index 93bbf83584f..d388bae4549 100644 --- a/website/docs/docs/cloud/connect-data-platform/about-connections.md +++ b/website/docs/docs/cloud/connect-data-platform/about-connections.md @@ -28,7 +28,7 @@ These connection instructions provide the basic fields required for configuring ## IP Restrictions -dbt Cloud will always connect to your data platform from the IP addresses specified in the [Regions & IP addresses](/docs/cloud/about-cloud/regions-ip-addresses) page. +dbt Cloud will always connect to your data platform from the IP addresses specified in the [Regions & IP addresses](/docs/cloud/about-cloud/access-regions-ip-addresses) page. Be sure to allow traffic from these IPs in your firewall, and include them in any database grants. diff --git a/website/docs/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb.md b/website/docs/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb.md index 06b9dd62f1a..03303ea8d52 100644 --- a/website/docs/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb.md +++ b/website/docs/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb.md @@ -46,7 +46,7 @@ Make sure the location of the instance is the same Virtual Private Cloud (VPC) a To configure the SSH tunnel in dbt Cloud, you'll need to provide the hostname/IP of your bastion server, username, and port, of your choosing, that dbt Cloud will connect to. Review the following steps: -- Verify the bastion server has its network security rules set up to accept connections from the [dbt Cloud IP addresses](/docs/cloud/about-cloud/regions-ip-addresses) on whatever port you configured. +- Verify the bastion server has its network security rules set up to accept connections from the [dbt Cloud IP addresses](/docs/cloud/about-cloud/access-regions-ip-addresses) on whatever port you configured. - Set up the user account by using the bastion servers instance's CLI, The following example uses the username `dbtcloud:` ```shell diff --git a/website/docs/docs/cloud/dbt-cloud-ide/develop-in-the-cloud.md b/website/docs/docs/cloud/dbt-cloud-ide/develop-in-the-cloud.md index 9fc382f0217..b3df77a140e 100644 --- a/website/docs/docs/cloud/dbt-cloud-ide/develop-in-the-cloud.md +++ b/website/docs/docs/cloud/dbt-cloud-ide/develop-in-the-cloud.md @@ -105,7 +105,7 @@ The IDE uses developer credentials to connect to your data platform. These devel Set up your developer credentials: -1. Navigate to your **Credentials** under **Your Profile** settings, which you can access at `https://YOUR_ACCESS_URL/settings/profile#credentials`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +1. Navigate to your **Credentials** under **Your Profile** settings, which you can access at `https://YOUR_ACCESS_URL/settings/profile#credentials`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. 2. Select the relevant project in the list. 3. Click **Edit** on the bottom right of the page. 4. Enter the details under **Development Credentials**. diff --git a/website/docs/docs/cloud/git/connect-gitlab.md b/website/docs/docs/cloud/git/connect-gitlab.md index e55552e2d86..f68f09ae73d 100644 --- a/website/docs/docs/cloud/git/connect-gitlab.md +++ b/website/docs/docs/cloud/git/connect-gitlab.md @@ -63,7 +63,7 @@ In GitLab, when creating your Group Application, input the following: | **Confidential** | ✔️ | | **Scopes** | ✔️ api | -Replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +Replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. The application form in GitLab should look as follows when completed: diff --git a/website/docs/docs/cloud/git/setup-azure.md b/website/docs/docs/cloud/git/setup-azure.md index 843371be6ea..ab75ee40ada 100644 --- a/website/docs/docs/cloud/git/setup-azure.md +++ b/website/docs/docs/cloud/git/setup-azure.md @@ -31,7 +31,7 @@ Once the Azure AD app is added to dbt Cloud and the service user is connected, t 4. Provide a name for your app. We recommend using, "dbt Labs Azure DevOps App". 5. Select **Accounts in any organizational directory (Any Azure AD directory - Multitenant)** as the Supported Account Types. Many customers ask why they need to select Multitenant instead of Single tenant, and they frequently get this step wrong. Microsoft considers Azure DevOps (formerly called Visual Studio) and Azure Active Directory as separate tenants, and in order for this Active Directory application to work properly, you must select Multitenant. -6. Add a redirect URI by selecting **Web** and, in the field, entering `https://YOUR_ACCESS_URL/complete/azure_active_directory`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +6. Add a redirect URI by selecting **Web** and, in the field, entering `https://YOUR_ACCESS_URL/complete/azure_active_directory`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. 7. Click **Register**. @@ -59,7 +59,7 @@ You also need to add another redirect URI to your Azure AD application. This red 1. Navigate to your Azure AD application. 2. Select the link next to **Redirect URIs** -3. Click **Add URI** and add the URI, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: +3. Click **Add URI** and add the URI, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/complete/azure_active_directory_service_user` 4. Click **Save**. diff --git a/website/docs/docs/cloud/manage-access/invite-users.md b/website/docs/docs/cloud/manage-access/invite-users.md index 21be7010a30..bf44decfdcc 100644 --- a/website/docs/docs/cloud/manage-access/invite-users.md +++ b/website/docs/docs/cloud/manage-access/invite-users.md @@ -35,7 +35,7 @@ You must have proper permissions to invite new users: ## User experience -dbt Cloud generates and sends emails from `support@getdbt.com` to the specified addresses. Make sure traffic from the `support@getdbt.com` email is allowed in your settings to avoid emails from going to spam or being blocked. This is the originating email address for all [instances worldwide](/docs/cloud/about-cloud/regions-ip-addresses). +dbt Cloud generates and sends emails from `support@getdbt.com` to the specified addresses. Make sure traffic from the `support@getdbt.com` email is allowed in your settings to avoid emails from going to spam or being blocked. This is the originating email address for all [instances worldwide](/docs/cloud/about-cloud/access-regions-ip-addresses). The email contains a link to create an account. When the user clicks on this they will be brought to one of two screens depending on whether SSO is configured or not. diff --git a/website/docs/docs/cloud/manage-access/set-up-bigquery-oauth.md b/website/docs/docs/cloud/manage-access/set-up-bigquery-oauth.md index 87018b14d56..a6b8808ccaa 100644 --- a/website/docs/docs/cloud/manage-access/set-up-bigquery-oauth.md +++ b/website/docs/docs/cloud/manage-access/set-up-bigquery-oauth.md @@ -34,7 +34,7 @@ On the **Credentials** page, you can see your existing keys, client IDs, and ser Set up an [OAuth consent screen](https://support.google.com/cloud/answer/6158849) if you haven't already. Then, click **+ Create Credentials** at the top of the page and select **OAuth client ID**. -Fill in the application, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: +Fill in the application, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: | Config | Value | | ------ | ----- | diff --git a/website/docs/docs/cloud/manage-access/set-up-databricks-oauth.md b/website/docs/docs/cloud/manage-access/set-up-databricks-oauth.md index 679133b7844..e790c234696 100644 --- a/website/docs/docs/cloud/manage-access/set-up-databricks-oauth.md +++ b/website/docs/docs/cloud/manage-access/set-up-databricks-oauth.md @@ -45,7 +45,7 @@ These parameters and descriptions will help you authenticate with your username | **USERNAME** | Your Databricks username (account admin level) | | **PASSWORD** | Your Databricks password (account admin level) | | **ACCOUNT_ID** | Your Databricks [account ID](https://docs.databricks.com/en/administration-guide/account-settings/index.html#locate-your-account-id) | -| **YOUR_ACCESS_URL** | The [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your dbt Cloud account region and plan | +| **YOUR_ACCESS_URL** | The [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your dbt Cloud account region and plan | | **NAME** | The integration name (i.e 'databricks-dbt-cloud') After running the `curl`, you'll get an API response that includes the `client_id` and `client_secret` required in the following section. At this time, this is the only way to retrieve the secret. If you lose the secret, then the integration needs to be [deleted](https://docs.databricks.com/api/account/customappintegration/delete) and re-created. diff --git a/website/docs/docs/cloud/manage-access/set-up-snowflake-oauth.md b/website/docs/docs/cloud/manage-access/set-up-snowflake-oauth.md index 5b9abb6058a..444374cc47e 100644 --- a/website/docs/docs/cloud/manage-access/set-up-snowflake-oauth.md +++ b/website/docs/docs/cloud/manage-access/set-up-snowflake-oauth.md @@ -17,7 +17,7 @@ To enable Snowflake OAuth, you will need to create a [security integration](http ### Create a security integration -In Snowflake, execute a query to create a security integration. Please find the complete documentation on creating a security integration for custom clients [here](https://docs.snowflake.net/manuals/sql-reference/sql/create-security-integration.html#syntax). In the following example `create or replace security integration` query, replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +In Snowflake, execute a query to create a security integration. Please find the complete documentation on creating a security integration for custom clients [here](https://docs.snowflake.net/manuals/sql-reference/sql/create-security-integration.html#syntax). In the following example `create or replace security integration` query, replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. ``` CREATE OR REPLACE SECURITY INTEGRATION DBT_CLOUD @@ -42,7 +42,7 @@ CREATE OR REPLACE SECURITY INTEGRATION DBT_CLOUD | ENABLED | Required | | OAUTH_CLIENT | Required | | OAUTH_CLIENT_TYPE | Required | -| OAUTH_REDIRECT_URI | Required. Use the access URL that corresponds to your server [region](/docs/cloud/about-cloud/regions-ip-addresses). If dbt Cloud is deployed on-premises, use the domain name of your application instead of the access URL. | +| OAUTH_REDIRECT_URI | Required. Use the access URL that corresponds to your server [region](/docs/cloud/about-cloud/access-regions-ip-addresses). If dbt Cloud is deployed on-premises, use the domain name of your application instead of the access URL. | | OAUTH_ISSUE_REFRESH_TOKENS | Required | | OAUTH_REFRESH_TOKEN_VALIDITY | Required. This configuration dictates the number of seconds that a refresh token is valid for. Use a smaller value to force users to re-authenticate with Snowflake more frequently. | @@ -103,7 +103,7 @@ This error might be because of a configuration issue in the Snowflake OAuth flow * In the Snowflake OAuth flow, `role` in the profile config is not optional, as it does not inherit from the project connection config. So each user must supply their role, regardless of whether it is provided in the project connection. #### Server error 500 -If you experience a 500 server error when redirected from Snowflake to dbt Cloud, double-check that you have allow listed [dbt Cloud's IP addresses](/docs/cloud/about-cloud/regions-ip-addresses) on a Snowflake account level. +If you experience a 500 server error when redirected from Snowflake to dbt Cloud, double-check that you have allow listed [dbt Cloud's IP addresses](/docs/cloud/about-cloud/access-regions-ip-addresses) on a Snowflake account level. Enterprise customers who have single-tenant deployments will have a different range of IP addresses (network CIDR ranges) to allow list. diff --git a/website/docs/docs/cloud/manage-access/set-up-sso-google-workspace.md b/website/docs/docs/cloud/manage-access/set-up-sso-google-workspace.md index 19779baf615..e4ff998015c 100644 --- a/website/docs/docs/cloud/manage-access/set-up-sso-google-workspace.md +++ b/website/docs/docs/cloud/manage-access/set-up-sso-google-workspace.md @@ -96,7 +96,7 @@ Settings. account using GSuite auth. Optionally, you may specify a CSV of domains which are _all_ authorized to access your dbt Cloud account (eg. `dbtlabs.com, fishtowndata.com`) - **Slug**: Enter your desired login slug. Users will be able to log into dbt - Cloud by navigating to `https://YOUR_ACCESS_URL/enterprise-login/LOGIN-SLUG`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. The `LOGIN-SLUG` must + Cloud by navigating to `https://YOUR_ACCESS_URL/enterprise-login/LOGIN-SLUG`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. The `LOGIN-SLUG` must be unique across all dbt Cloud accounts, so pick a slug that uniquely identifies your company. diff --git a/website/docs/docs/cloud/manage-access/set-up-sso-okta.md b/website/docs/docs/cloud/manage-access/set-up-sso-okta.md index 4079cc488c4..53986513ce2 100644 --- a/website/docs/docs/cloud/manage-access/set-up-sso-okta.md +++ b/website/docs/docs/cloud/manage-access/set-up-sso-okta.md @@ -61,7 +61,7 @@ Click **Next** to continue. ### Configure SAML Settings -The SAML Settings page configures how Okta and dbt Cloud communicate. You will want to use an [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +The SAML Settings page configures how Okta and dbt Cloud communicate. You will want to use an [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. To complete this section, you will need a _login slug_. This slug controls the URL where users on your account can log into your application via Okta. Login @@ -172,7 +172,7 @@ configured in the steps above. | **Identity Provider SSO Url** | Paste the **Identity Provider Single Sign-On URL** shown in the Okta setup instructions | | **Identity Provider Issuer** | Paste the **Identity Provider Issuer** shown in the Okta setup instructions | | **X.509 Certificate** | Paste the **X.509 Certificate** shown in the Okta setup instructions;
**Note:** When the certificate expires, an Okta admin will have to generate a new one to be pasted into dbt Cloud for uninterrupted application access. | -| **Slug** | Enter your desired login slug. Users will be able to log into dbt Cloud by navigating to `https://YOUR_ACCESS_URL/enterprise-login/LOGIN-SLUG`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. Login slugs must be unique across all dbt Cloud accounts, so pick a slug that uniquely identifies your company. | +| **Slug** | Enter your desired login slug. Users will be able to log into dbt Cloud by navigating to `https://YOUR_ACCESS_URL/enterprise-login/LOGIN-SLUG`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. Login slugs must be unique across all dbt Cloud accounts, so pick a slug that uniquely identifies your company. | " }` * `VARIABLES` with a dictionary of your GraphQL query variables, such as a job ID or a filter. diff --git a/website/docs/docs/dbt-cloud-apis/migrating-to-v2.md b/website/docs/docs/dbt-cloud-apis/migrating-to-v2.md index 3e6ac2c3577..72616f4b19c 100644 --- a/website/docs/docs/dbt-cloud-apis/migrating-to-v2.md +++ b/website/docs/docs/dbt-cloud-apis/migrating-to-v2.md @@ -10,7 +10,7 @@ In an attempt to provide an improved dbt Cloud Administrative API experience, th ## Key differences -When using the [List runs](/dbt-cloud/api-v2-legacy#tag/Runs) endpoint, you can include triggered runs and sort by ID. You can use the following request in v2 to get a similar response as v4, replacing the `{accountId}` with your own and `{YOUR_ACCESS_URL}` with the appropriate [Access URL](https://docs.getdbt.com/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: +When using the [List runs](/dbt-cloud/api-v2-legacy#tag/Runs) endpoint, you can include triggered runs and sort by ID. You can use the following request in v2 to get a similar response as v4, replacing the `{accountId}` with your own and `{YOUR_ACCESS_URL}` with the appropriate [Access URL](https://docs.getdbt.com/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: ```shell GET https://{YOUR_ACCESS_URL}/api/v2/accounts/{accountId}/runs/?include_related=[%22trigger%22]&order_by=-id diff --git a/website/docs/docs/dbt-cloud-apis/sl-jdbc.md b/website/docs/docs/dbt-cloud-apis/sl-jdbc.md index aba309566f8..9f61f488c4a 100644 --- a/website/docs/docs/dbt-cloud-apis/sl-jdbc.md +++ b/website/docs/docs/dbt-cloud-apis/sl-jdbc.md @@ -50,7 +50,7 @@ jdbc:arrow-flight-sql://semantic-layer.cloud.getdbt.com:443?&environmentId=20233 | JDBC parameter | Description | Example | | -------------- | ----------- | ------- | | `jdbc:arrow-flight-sql://` | The protocol for the JDBC driver. | `jdbc:arrow-flight-sql://` | -| `semantic-layer.cloud.getdbt.com` | The [access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your account's dbt Cloud region. You must always add the `semantic-layer` prefix before the access URL. | For dbt Cloud deployment hosted in North America, use `semantic-layer.cloud.getdbt.com` | +| `semantic-layer.cloud.getdbt.com` | The [access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your account's dbt Cloud region. You must always add the `semantic-layer` prefix before the access URL. | For dbt Cloud deployment hosted in North America, use `semantic-layer.cloud.getdbt.com` | | `environmentId` | The unique identifier for the dbt production environment, you can retrieve this from the dbt Cloud URL
when you navigate to **Environments** under **Deploy**. | If your URL ends with `.../environments/222222`, your `environmentId` is `222222`

| | `SERVICE_TOKEN` | dbt Cloud [service token](/docs/dbt-cloud-apis/service-tokens) with “Semantic Layer Only” and "Metadata Only" permissions. Create a new service token on the **Account Settings** page. | `token=SERVICE_TOKEN` | diff --git a/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/api-v2v3-limit.md b/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/api-v2v3-limit.md index 9768886d5fb..fb27e8e1727 100644 --- a/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/api-v2v3-limit.md +++ b/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/api-v2v3-limit.md @@ -10,6 +10,6 @@ tags: [Oct-2023, API] Beginning December 1, 2023, the [Administrative API](/docs/dbt-cloud-apis/admin-cloud-api) v2 and v3 will expect you to limit all "list" or `GET` API methods to 100 results per API request. This limit enhances the efficiency and stability of our services. If you need to handle more than 100 results, then use the `limit` and `offset` query parameters to paginate those results; otherwise, you will receive an error. -This maximum limit applies to [multi-tenant instances](/docs/cloud/about-cloud/regions-ip-addresses) only, and _does not_ apply to single tenant instances. +This maximum limit applies to [multi-tenant instances](/docs/cloud/about-cloud/access-regions-ip-addresses) only, and _does not_ apply to single tenant instances. Refer to the [API v3 Pagination](https://docs.getdbt.com/dbt-cloud/api-v3#/) or [API v2 Pagination](https://docs.getdbt.com/dbt-cloud/api-v2#/) sections for more information on how to paginate your API responses. diff --git a/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/sl-ga.md b/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/sl-ga.md index a81abec5d42..1cae19c69c4 100644 --- a/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/sl-ga.md +++ b/website/docs/docs/dbt-versions/release-notes/03-Oct-2023/sl-ga.md @@ -17,7 +17,7 @@ It aims to bring the best of modeling and semantics to downstream applications b - Brand new [integrations](/docs/use-dbt-semantic-layer/avail-sl-integrations) such as Tableau, Google Sheets, Hex, Mode, and Lightdash. - New [Semantic Layer APIs](/docs/dbt-cloud-apis/sl-api-overview) using GraphQL and JDBC to query metrics and build integrations. -- dbt Cloud [multi-tenant regional](/docs/cloud/about-cloud/regions-ip-addresses) support for North America, EMEA, and APAC. Single-tenant support coming soon. +- dbt Cloud [multi-tenant regional](/docs/cloud/about-cloud/access-regions-ip-addresses) support for North America, EMEA, and APAC. Single-tenant support coming soon. - Use the APIs to call an export (a way to build tables in your data platform), then access them in your preferred BI tool. Starting from dbt v1.7 or higher, you will be able to schedule exports as part of your dbt job. diff --git a/website/docs/docs/dbt-versions/release-notes/05-Aug-2023/sl-revamp-beta.md b/website/docs/docs/dbt-versions/release-notes/05-Aug-2023/sl-revamp-beta.md index f44fd57aa4a..77ba9030038 100644 --- a/website/docs/docs/dbt-versions/release-notes/05-Aug-2023/sl-revamp-beta.md +++ b/website/docs/docs/dbt-versions/release-notes/05-Aug-2023/sl-revamp-beta.md @@ -44,7 +44,7 @@ By bringing these enhancements to the dbt Semantic Layer, we enable organization The dbt Semantic Layer is currently available as a public beta, which means: -- **Who** — To experience the new dbt Semantic Layer, you must be on a dbt Cloud [Team and Enterprise](https://www.getdbt.com/pricing/) multi-tenant dbt Cloud plan, [hosted](/docs/cloud/about-cloud/regions-ip-addresses) in North America and on dbt v1.6 and higher. Look out for announcements on removing the location requirement soon. +- **Who** — To experience the new dbt Semantic Layer, you must be on a dbt Cloud [Team and Enterprise](https://www.getdbt.com/pricing/) multi-tenant dbt Cloud plan, [hosted](/docs/cloud/about-cloud/access-regions-ip-addresses) in North America and on dbt v1.6 and higher. Look out for announcements on removing the location requirement soon. - Developer plans or dbt Core users can use MetricFlow to define and test metrics using the dbt MetricFlow CLI only. diff --git a/website/docs/docs/dbt-versions/release-notes/07-June-2023/admin-api-rn.md b/website/docs/docs/dbt-versions/release-notes/07-June-2023/admin-api-rn.md index 2008331ebe6..b486c90b881 100644 --- a/website/docs/docs/dbt-versions/release-notes/07-June-2023/admin-api-rn.md +++ b/website/docs/docs/dbt-versions/release-notes/07-June-2023/admin-api-rn.md @@ -11,5 +11,5 @@ dbt Labs updated the docs for the [dbt Cloud Administrative API](/docs/dbt-cloud - Now using Spotlight for improved UI and UX. - All endpoints are now documented for v2 and v3. Added automation to the docs so they remain up to date. - Documented many of the request and response bodies. -- You can now test endpoints directly from within the API docs. And, you can choose which [regional server](/docs/cloud/about-cloud/regions-ip-addresses) to use (North America, APAC, or EMEA). +- You can now test endpoints directly from within the API docs. And, you can choose which [regional server](/docs/cloud/about-cloud/access-regions-ip-addresses) to use (North America, APAC, or EMEA). - With the new UI, you can more easily generate code for any endpoint. diff --git a/website/docs/docs/dbt-versions/release-notes/09-April-2023/api-endpoint-restriction.md b/website/docs/docs/dbt-versions/release-notes/09-April-2023/api-endpoint-restriction.md index 8507fe3dbbb..04b669f75ba 100644 --- a/website/docs/docs/dbt-versions/release-notes/09-April-2023/api-endpoint-restriction.md +++ b/website/docs/docs/dbt-versions/release-notes/09-April-2023/api-endpoint-restriction.md @@ -16,7 +16,7 @@ We recommend that you change your API requests to https:///api/ :::info Access URLs -dbt Cloud is hosted in multiple regions around the world, and each region has a different access URL. Users on Enterprise plans can choose to have their account hosted in any one of these regions. For a complete list of available dbt Cloud access URLs, refer to [Regions & IP addresses](/docs/cloud/about-cloud/regions-ip-addresses). +dbt Cloud is hosted in multiple regions around the world, and each region has a different access URL. Users on Enterprise plans can choose to have their account hosted in any one of these regions. For a complete list of available dbt Cloud access URLs, refer to [Regions & IP addresses](/docs/cloud/about-cloud/access-regions-ip-addresses). ::: diff --git a/website/docs/docs/dbt-versions/release-notes/10-Mar-2023/apiv2-limit.md b/website/docs/docs/dbt-versions/release-notes/10-Mar-2023/apiv2-limit.md index 85c4af48b54..12509bf77f7 100644 --- a/website/docs/docs/dbt-versions/release-notes/10-Mar-2023/apiv2-limit.md +++ b/website/docs/docs/dbt-versions/release-notes/10-Mar-2023/apiv2-limit.md @@ -9,6 +9,6 @@ tags: [Mar-2023, API] To make the API more scalable and reliable, we've implemented a maximum limit of `100` for all API requests to our `list` endpoints. If API requests exceed the maximum limit parameter of `100`, a user will receive an API error message. -This maximum limit applies to [multi-tenant instances](/docs/cloud/about-cloud/regions-ip-addresses) only, and _does not_ apply to single tenant instances. +This maximum limit applies to [multi-tenant instances](/docs/cloud/about-cloud/access-regions-ip-addresses) only, and _does not_ apply to single tenant instances. Refer to the [Pagination](https://docs.getdbt.com/dbt-cloud/api-v2-legacy#section/Pagination) section for more information on this change. diff --git a/website/docs/docs/dbt-versions/release-notes/11-Feb-2023/feb-ide-updates.md b/website/docs/docs/dbt-versions/release-notes/11-Feb-2023/feb-ide-updates.md index 64fa2026d04..7020868197a 100644 --- a/website/docs/docs/dbt-versions/release-notes/11-Feb-2023/feb-ide-updates.md +++ b/website/docs/docs/dbt-versions/release-notes/11-Feb-2023/feb-ide-updates.md @@ -19,7 +19,7 @@ Learn more about the [February changes](https://getdbt.slack.com/archives/C03SAH - Rename files by double-clicking on files in the file tree and the editor tabs - Right-clicking on file tabs has new options and will now open at your cursor instead of in the middle of the tab - The git branch name above **Version Control** links to the repo for specific git providers - * Currently available for all [multi-tenant](/docs/cloud/about-cloud/regions-ip-addresses) instances using GitHub or GitLab providers + * Currently available for all [multi-tenant](/docs/cloud/about-cloud/access-regions-ip-addresses) instances using GitHub or GitLab providers ## Product refinements diff --git a/website/docs/docs/dbt-versions/release-notes/26-Sept-2022/liststeps-endpoint-deprecation.md b/website/docs/docs/dbt-versions/release-notes/26-Sept-2022/liststeps-endpoint-deprecation.md index 545847efd90..9cae773ea3e 100644 --- a/website/docs/docs/dbt-versions/release-notes/26-Sept-2022/liststeps-endpoint-deprecation.md +++ b/website/docs/docs/dbt-versions/release-notes/26-Sept-2022/liststeps-endpoint-deprecation.md @@ -10,6 +10,6 @@ On October 14th, 2022 dbt Labs is deprecating the [List Steps](https://docs.getd dbt Labs will continue to maintain the [Get Run](https://docs.getdbt.com/dbt-cloud/api-v2-legacy#tag/Runs/operation/getRunById) endpoint, which is a viable alternative depending on the use case. -You can fetch run steps for an individual run with a GET request to the following URL, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: +You can fetch run steps for an individual run with a GET request to the following URL, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/api/v2/accounts/{accountId}/runs/{runId}/?include_related=["run_steps"]` diff --git a/website/docs/docs/deploy/dashboard-status-tiles.md b/website/docs/docs/deploy/dashboard-status-tiles.md index 67aa1a93c33..d3944fc5877 100644 --- a/website/docs/docs/deploy/dashboard-status-tiles.md +++ b/website/docs/docs/deploy/dashboard-status-tiles.md @@ -36,7 +36,7 @@ You can insert these three fields into the following iFrame, and then embed it * :::tip Replace `YOUR_ACCESS_URL` with your region and plan's Access URL -dbt Cloud is hosted in multiple regions in the world and each region has a different access URL. Replace `YOUR_ACCESS_URL` with the appropriate [Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. For example, if your account is hosted in the EMEA region, you would use the following iFrame code: +dbt Cloud is hosted in multiple regions in the world and each region has a different access URL. Replace `YOUR_ACCESS_URL` with the appropriate [Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. For example, if your account is hosted in the EMEA region, you would use the following iFrame code: ``` @@ -71,7 +71,7 @@ https://metadata.YOUR_ACCESS_URL/exposure-tile?name=&jobId=&jobId=&token= @@ -91,7 +91,7 @@ https://metadata.YOUR_ACCESS_URL/exposure-tile?name=&jobId=&jobId=&token= diff --git a/website/docs/docs/deploy/run-visibility.md b/website/docs/docs/deploy/run-visibility.md index ff9abfa5b0b..0ace26eb5ed 100644 --- a/website/docs/docs/deploy/run-visibility.md +++ b/website/docs/docs/deploy/run-visibility.md @@ -26,7 +26,7 @@ You can view or download in-progress and historical logs for your dbt runs. This ## Model timing -> Available on [multi-tenant](/docs/cloud/about-cloud/regions-ip-addresses) dbt Cloud accounts on the [Team or Enterprise plans](https://www.getdbt.com/pricing/). +> Available on [multi-tenant](/docs/cloud/about-cloud/access-regions-ip-addresses) dbt Cloud accounts on the [Team or Enterprise plans](https://www.getdbt.com/pricing/). The model timing dashboard on dbt Cloud displays the composition, order, and time taken by each model in a job run. The visualization appears for successful jobs and highlights the top 1% of model durations. This helps you identify bottlenecks in your runs, so you can investigate them and potentially make changes to improve their performance. diff --git a/website/docs/docs/deploy/webhooks.md b/website/docs/docs/deploy/webhooks.md index f6c766ab201..e036444c304 100644 --- a/website/docs/docs/deploy/webhooks.md +++ b/website/docs/docs/deploy/webhooks.md @@ -35,7 +35,7 @@ You can also check out the free [dbt Fundamentals course](https://courses.getdbt ## Create a webhook subscription {#create-a-webhook-subscription} -From your **Account Settings** in dbt Cloud (using the gear menu in the top right corner), click **Create New Webhook** in the **Webhooks** section. You can find the appropriate dbt Cloud access URL for your region and plan with [Regions & IP addresses](/docs/cloud/about-cloud/regions-ip-addresses). +From your **Account Settings** in dbt Cloud (using the gear menu in the top right corner), click **Create New Webhook** in the **Webhooks** section. You can find the appropriate dbt Cloud access URL for your region and plan with [Regions & IP addresses](/docs/cloud/about-cloud/access-regions-ip-addresses). To configure your new webhook: @@ -167,7 +167,7 @@ An example of a webhook payload for an errored run: You can use the dbt Cloud API to create new webhooks that you want to subscribe to, get detailed information about your webhooks, and to manage the webhooks that are associated with your account. The following sections describe the API endpoints you can use for this. :::info Access URLs -dbt Cloud is hosted in multiple regions in the world and each region has a different access URL. People on Enterprise plans can choose to have their account hosted in any one of these regions. For a complete list of available dbt Cloud access URLs, refer to [Regions & IP addresses](/docs/cloud/about-cloud/regions-ip-addresses). +dbt Cloud is hosted in multiple regions in the world and each region has a different access URL. People on Enterprise plans can choose to have their account hosted in any one of these regions. For a complete list of available dbt Cloud access URLs, refer to [Regions & IP addresses](/docs/cloud/about-cloud/access-regions-ip-addresses). ::: ### List all webhook subscriptions diff --git a/website/docs/docs/running-a-dbt-project/using-the-dbt-ide.md b/website/docs/docs/running-a-dbt-project/using-the-dbt-ide.md index f41bceab12d..c772ae89fab 100644 --- a/website/docs/docs/running-a-dbt-project/using-the-dbt-ide.md +++ b/website/docs/docs/running-a-dbt-project/using-the-dbt-ide.md @@ -32,7 +32,7 @@ New dbt Cloud accounts should have developer credentials created automatically a New users on existing accounts *might not* have their development credentials already configured. To manage your development credentials: -1. Navigate to your **Credentials** under **Your Profile** settings, which you can access at `https://YOUR_ACCESS_URL/settings/profile#credentials`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +1. Navigate to your **Credentials** under **Your Profile** settings, which you can access at `https://YOUR_ACCESS_URL/settings/profile#credentials`, replacing `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. 2. Select the relevant project in the list. After entering your developer credentials, you'll be able to access the dbt IDE. diff --git a/website/docs/docs/use-dbt-semantic-layer/tableau.md b/website/docs/docs/use-dbt-semantic-layer/tableau.md index a5c1b6edd04..0f202cd4a2c 100644 --- a/website/docs/docs/use-dbt-semantic-layer/tableau.md +++ b/website/docs/docs/use-dbt-semantic-layer/tableau.md @@ -21,7 +21,7 @@ This integration provides a live connection to the dbt Semantic Layer through Ta - Note that Tableau Online does not currently support custom connectors natively. If you use Tableau Online, you will only be able to access the connector in Tableau Desktop. - Log in to Tableau Desktop (with Online or Server credentials) or a license to Tableau Server - You need your dbt Cloud host, [Environment ID](/docs/use-dbt-semantic-layer/setup-sl#set-up-dbt-semantic-layer) and [service token](/docs/dbt-cloud-apis/service-tokens) to log in. This account should be set up with the dbt Semantic Layer. -- You must have a dbt Cloud Team or Enterprise [account](https://www.getdbt.com/pricing) and multi-tenant [deployment](/docs/cloud/about-cloud/regions-ip-addresses). (Single-Tenant coming soon) +- You must have a dbt Cloud Team or Enterprise [account](https://www.getdbt.com/pricing) and multi-tenant [deployment](/docs/cloud/about-cloud/access-regions-ip-addresses). (Single-Tenant coming soon) ## Installing the Connector diff --git a/website/docs/faqs/API/rotate-token.md b/website/docs/faqs/API/rotate-token.md index 144c834ea8a..edddc77c2d9 100644 --- a/website/docs/faqs/API/rotate-token.md +++ b/website/docs/faqs/API/rotate-token.md @@ -34,7 +34,7 @@ curl --location --request POST 'https://YOUR_ACCESS_URL/api/v2/users/YOUR_USER_I * Find your `YOUR_USER_ID` by reading [How to find your user ID](/faqs/Accounts/find-user-id). * Find your `YOUR_CURRENT_TOKEN` by going to **Profile Settings** -> **API Access** and copying the API key. -* Find [`YOUR_ACCESS_URL`](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +* Find [`YOUR_ACCESS_URL`](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. :::info Example @@ -53,7 +53,7 @@ curl --location --request POST 'https://cloud.getdbt.com/api/v2/users/123/apikey ### dbt Cloud deployments -If your [dbt Cloud deployment](/docs/cloud/about-cloud/regions-ip-addresses) uses a different access URL, replace `cloud.getdbt.com` with the URL of your instance. +If your [dbt Cloud deployment](/docs/cloud/about-cloud/access-regions-ip-addresses) uses a different access URL, replace `cloud.getdbt.com` with the URL of your instance. For example, if your deployment is Virtual Private dbt: diff --git a/website/docs/faqs/Accounts/transfer-account.md b/website/docs/faqs/Accounts/transfer-account.md index d82dfbf505a..56b87155444 100644 --- a/website/docs/faqs/Accounts/transfer-account.md +++ b/website/docs/faqs/Accounts/transfer-account.md @@ -10,10 +10,10 @@ You can transfer your dbt Cloud [access control](/docs/cloud/manage-access/about | Account plan| Steps | | ------ | ---------- | -| **Developer** | You can transfer ownership by changing the email directly on your dbt Cloud profile page, which you can access using this URL when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile` | +| **Developer** | You can transfer ownership by changing the email directly on your dbt Cloud profile page, which you can access using this URL when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile` | | **Team** | Existing account admins with account access can add users to, or remove users from the owner group. | | **Enterprise** | Account admins can add users to, or remove users from a group with Account Admin permissions. | -| **If all account owners left the company** | If the account owner has left your organization, you will need to work with _your_ IT department to have incoming emails forwarded to the new account owner. Once your IT department has redirected the emails, you can request to reset the user password. Once you log in, you can change the email on the Profile page when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile`. | +| **If all account owners left the company** | If the account owner has left your organization, you will need to work with _your_ IT department to have incoming emails forwarded to the new account owner. Once your IT department has redirected the emails, you can request to reset the user password. Once you log in, you can change the email on the Profile page when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile`. | When you make any account owner and email changes: diff --git a/website/docs/guides/how-to-use-databricks-workflows-to-run-dbt-cloud-jobs.md b/website/docs/guides/how-to-use-databricks-workflows-to-run-dbt-cloud-jobs.md index 30221332355..f6e59c7b1a8 100644 --- a/website/docs/guides/how-to-use-databricks-workflows-to-run-dbt-cloud-jobs.md +++ b/website/docs/guides/how-to-use-databricks-workflows-to-run-dbt-cloud-jobs.md @@ -134,7 +134,7 @@ if __name__ == '__main__': 3. Replace **``** and **``** with the values you used [previously](#set-up-a-databricks-secret-scope) -4. Replace **``** and **``** with the correct values of your environment and [Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan. +4. Replace **``** and **``** with the correct values of your environment and [Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan. :::tip To find these values, navigate to **dbt Cloud**, select **Deploy -> Jobs**. Select the Job you want to run and copy the URL. For example: `https://cloud.getdbt.com/deploy/000000/projects/111111/jobs/222222` diff --git a/website/docs/guides/starburst-galaxy-qs.md b/website/docs/guides/starburst-galaxy-qs.md index 1822c83fa90..c928d37ae1a 100644 --- a/website/docs/guides/starburst-galaxy-qs.md +++ b/website/docs/guides/starburst-galaxy-qs.md @@ -28,7 +28,7 @@ You can also watch the [Build Better Data Pipelines with dbt and Starburst](http ### Prerequisites -- You have a [multi-tenant](/docs/cloud/about-cloud/regions-ip-addresses) deployment in [dbt Cloud](https://www.getdbt.com/signup/). For more information, refer to [Tenancy](/docs/cloud/about-cloud/tenancy). +- You have a [multi-tenant](/docs/cloud/about-cloud/access-regions-ip-addresses) deployment in [dbt Cloud](https://www.getdbt.com/signup/). For more information, refer to [Tenancy](/docs/cloud/about-cloud/tenancy). - You have a [Starburst Galaxy account](https://www.starburst.io/platform/starburst-galaxy/). If you don't, you can start a free trial. Refer to the [getting started guide](https://docs.starburst.io/starburst-galaxy/get-started.html) in the Starburst Galaxy docs for further setup details. - You have an AWS account with permissions to upload data to an S3 bucket. - For Amazon S3 authentication, you will need either an AWS access key and AWS secret key with access to the bucket, or you will need a cross account IAM role with access to the bucket. For details, refer to these Starburst Galaxy docs: diff --git a/website/snippets/_new-sl-setup.md b/website/snippets/_new-sl-setup.md index 3cb6e09eb4c..66cbeb1ef86 100644 --- a/website/snippets/_new-sl-setup.md +++ b/website/snippets/_new-sl-setup.md @@ -1,6 +1,6 @@ You can set up the dbt Semantic Layer in dbt Cloud at the environment and project level. Before you begin: -- You must have a dbt Cloud Team or Enterprise [multi-tenant](/docs/cloud/about-cloud/regions-ip-addresses) deployment. Single-tenant coming soon. +- You must have a dbt Cloud Team or Enterprise [multi-tenant](/docs/cloud/about-cloud/access-regions-ip-addresses) deployment. Single-tenant coming soon. - You must be part of the Owner group, and have the correct [license](/docs/cloud/manage-access/seats-and-users) and [permissions](/docs/cloud/manage-access/self-service-permissions) to configure the Semantic Layer: * Enterprise plan — Developer license with Account Admin permissions. Or Owner with a Developer license, assigned Project Creator, Database Admin, or Admin permissions. * Team plan — Owner with a Developer license. diff --git a/website/snippets/_sl-connect-and-query-api.md b/website/snippets/_sl-connect-and-query-api.md index 429f41c3bf6..180561a978e 100644 --- a/website/snippets/_sl-connect-and-query-api.md +++ b/website/snippets/_sl-connect-and-query-api.md @@ -1,6 +1,6 @@ You can query your metrics in a JDBC-enabled tool or use existing first-class integrations with the dbt Semantic Layer. -You must have a dbt Cloud Team or Enterprise [multi-tenant](/docs/cloud/about-cloud/regions-ip-addresses) deployment. Single-tenant coming soon. +You must have a dbt Cloud Team or Enterprise [multi-tenant](/docs/cloud/about-cloud/access-regions-ip-addresses) deployment. Single-tenant coming soon. - To learn how to use the JDBC or GraphQL API and what tools you can query it with, refer to [dbt Semantic Layer APIs](/docs/dbt-cloud-apis/sl-api-overview). diff --git a/website/snippets/_sl-plan-info.md b/website/snippets/_sl-plan-info.md index 083ab2209bc..0e982b1bf0d 100644 --- a/website/snippets/_sl-plan-info.md +++ b/website/snippets/_sl-plan-info.md @@ -1,2 +1,2 @@ -To define and query metrics with the {props.product}, you must be on a {props.plan} multi-tenant plan .


+To define and query metrics with the {props.product}, you must be on a {props.plan} multi-tenant plan .


diff --git a/website/snippets/_v2-sl-prerequisites.md b/website/snippets/_v2-sl-prerequisites.md index c80db4d1c8f..d3f7887a6bd 100644 --- a/website/snippets/_v2-sl-prerequisites.md +++ b/website/snippets/_v2-sl-prerequisites.md @@ -1,7 +1,7 @@ -- Have a dbt Cloud Team or Enterprise [multi-tenant](/docs/cloud/about-cloud/regions-ip-addresses) deployment. Single-tenant coming soon. +- Have a dbt Cloud Team or Enterprise [multi-tenant](/docs/cloud/about-cloud/access-regions-ip-addresses) deployment. Single-tenant coming soon. - Have both your production and development environments running dbt version 1.6 or higher. Refer to [upgrade in dbt Cloud](/docs/dbt-versions/upgrade-core-in-cloud) for more info. - Use Snowflake, BigQuery, Databricks, or Redshift. - Create a successful run in the environment where you configure the Semantic Layer. @@ -16,7 +16,7 @@ -- Have a multi-tenant dbt Cloud instance, hosted in North America
+- Have a multi-tenant dbt Cloud instance, hosted in North America
- Have both your production and development environments running dbt version 1.3 or higher
- Use Snowflake data platform
- Install the dbt metrics package version >=1.3.0, <1.4.0 in your dbt project
@@ -28,7 +28,7 @@ -- Have a multi-tenant dbt Cloud instance, hosted in North America
+- Have a multi-tenant dbt Cloud instance, hosted in North America
- Have both your production and development environments running dbt version 1.2
- Use Snowflake data platform
- Install the dbt metrics package version >=0.3.0, <0.4.0 in your dbt project
diff --git a/website/snippets/login_url_note.md b/website/snippets/login_url_note.md index a46648ea9c6..65c1b6c16ca 100644 --- a/website/snippets/login_url_note.md +++ b/website/snippets/login_url_note.md @@ -1,5 +1,5 @@ :::success Logging in -Users can now log into the dbt Cloud by navigating to the following URL, replacing `LOGIN-SLUG` with the value used in the previous steps and `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/regions-ip-addresses) for your region and plan: +Users can now log into the dbt Cloud by navigating to the following URL, replacing `LOGIN-SLUG` with the value used in the previous steps and `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/enterprise-login/LOGIN-SLUG` ::: diff --git a/website/snippets/sl-public-preview-banner.md b/website/snippets/sl-public-preview-banner.md index e97527d356d..41a724c22be 100644 --- a/website/snippets/sl-public-preview-banner.md +++ b/website/snippets/sl-public-preview-banner.md @@ -1,6 +1,6 @@ :::info 📌 -The dbt Semantic Layer is currently available in Public Preview for multi-tenant dbt Cloud accounts hosted in North America. If you log in via https://cloud.getdbt.com/, you can access the Semantic Layer. If you log in with [another URL](/docs/cloud/about-cloud/regions-ip-addresses), the dbt Semantic Layer will be available in the future. +The dbt Semantic Layer is currently available in Public Preview for multi-tenant dbt Cloud accounts hosted in North America. If you log in via https://cloud.getdbt.com/, you can access the Semantic Layer. If you log in with [another URL](/docs/cloud/about-cloud/access-regions-ip-addresses), the dbt Semantic Layer will be available in the future. For more info, review the [Prerequisites](/docs/use-dbt-semantic-layer/dbt-semantic-layer#prerequisites), [Public Preview](/docs/use-dbt-semantic-layer/quickstart-semantic-layer#public-preview), and [Product architecture](/docs/use-dbt-semantic-layer/dbt-semantic-layer#product-architecture) sections. diff --git a/website/vercel.json b/website/vercel.json index 3377b49278d..2877da61da9 100644 --- a/website/vercel.json +++ b/website/vercel.json @@ -1279,7 +1279,7 @@ }, { "source": "/docs/deploy/regions-ip-addresses", - "destination": "/docs/cloud/about-cloud/regions-ip-addresses", + "destination": "/docs/cloud/about-cloud/access-regions-ip-addresses", "permanent": true }, { From b242461a8720492b98f52833491d4af002e302bd Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:34:21 -0500 Subject: [PATCH 03/84] Adding reference page for unit tests --- .../resource-properties/unit-tests.md | 51 +++++++++++++++++++ website/sidebars.js | 1 + 2 files changed, 52 insertions(+) create mode 100644 website/docs/reference/resource-properties/unit-tests.md diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md new file mode 100644 index 00000000000..02753803964 --- /dev/null +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -0,0 +1,51 @@ +--- +title: "About unit tests property" +sidebar_label: "unit tests" +resource_types: [models] +datatype: test +--- + + + +```yml +unit-tests: + - name: # this is the unique name of the test + model: + config: + meta: {dictionary} + tags: | [] + given: + - input: # optional for seeds + format: dict | csv + # if format csv, either define dictionary of rows or name of fixture + rows: + - {dictionary} + fixture: + - input: ... # declare additional inputs + expect: + format: dict | csv + # if format csv, either define dictionary of rows or name of fixture + rows: + - {dictionary} + fixture: + overrides: # optional: configuration for the dbt execution environment + macros: + is_incremental: true | false + dbt_utils.current_timestamp: str + # ... any other jinja function from https://docs.getdbt.com/reference/dbt-jinja-functions + # ... any other context property + vars: {dictionary} + env_vars: {dictionary} + - name: ... # declare additional unit tests + + ``` + + + + +## Definition + +Unit tests validate your modeling logic on a small set of static inputs before you materialize your full model in production. Unit tests enable test-driven development, with benefits for developer efficiency and code reliability. + +To run just your unit tests: +`dbt test —-select test_type:unit` \ No newline at end of file diff --git a/website/sidebars.js b/website/sidebars.js index 598fffc7f0d..11795e62704 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -744,6 +744,7 @@ const sidebarSettings = { "reference/resource-properties/include-exclude", "reference/resource-properties/quote", "reference/resource-properties/tests", + "reference/resource-properties/unit-tests", "reference/resource-properties/versions", ], }, From 840eed465aa011cb22c9e8fd191c38086670f1a4 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:49:05 -0500 Subject: [PATCH 04/84] Unit tests --- website/dbt-versions.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/dbt-versions.js b/website/dbt-versions.js index be55c893041..86580584fed 100644 --- a/website/dbt-versions.js +++ b/website/dbt-versions.js @@ -26,6 +26,10 @@ exports.versions = [ ] exports.versionedPages = [ + { + "page": "reference/resource-properties/unit-tests", + "firstVersion": "1.7", + }, { "page": "reference/resource-configs/store_failures_as", "firstVersion": "1.7", From 6ce45ff065db68007f9a0c2f0add1a4626954ae7 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:42:06 -0500 Subject: [PATCH 05/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 02753803964..a8b7512cd07 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -8,7 +8,7 @@ datatype: test ```yml -unit-tests: +unit_tests: - name: # this is the unique name of the test model: config: From 214eb6f9db0f3f3759ae0418fb44e64cc0cf3b83 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:14:40 -0500 Subject: [PATCH 06/84] Update website/dbt-versions.js --- website/dbt-versions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/dbt-versions.js b/website/dbt-versions.js index 86580584fed..c5b5245cebe 100644 --- a/website/dbt-versions.js +++ b/website/dbt-versions.js @@ -28,7 +28,7 @@ exports.versions = [ exports.versionedPages = [ { "page": "reference/resource-properties/unit-tests", - "firstVersion": "1.7", + "firstVersion": "1.8", }, { "page": "reference/resource-configs/store_failures_as", From 12fbe42149c97616a3ee08ddc757abbbc6ca0c10 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:29:44 -0500 Subject: [PATCH 07/84] Fixing spacing changes --- website/dbt-versions.js | 4 --- .../resource-properties/unit-tests.md | 25 ++++++++++--------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/website/dbt-versions.js b/website/dbt-versions.js index c5b5245cebe..be55c893041 100644 --- a/website/dbt-versions.js +++ b/website/dbt-versions.js @@ -26,10 +26,6 @@ exports.versions = [ ] exports.versionedPages = [ - { - "page": "reference/resource-properties/unit-tests", - "firstVersion": "1.8", - }, { "page": "reference/resource-configs/store_failures_as", "firstVersion": "1.7", diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index a8b7512cd07..7d4b1c44c17 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -8,34 +8,35 @@ datatype: test ```yml + unit_tests: - name: # this is the unique name of the test model: config: - meta: {dictionary} - tags: | [] - given: + meta: {dictionary} + tags: | [] + given: - input: # optional for seeds - format: dict | csv + format: dict | csv # if format csv, either define dictionary of rows or name of fixture rows: - {dictionary} fixture: - - input: ... # declare additional inputs + - input: ... # declare additional inputs expect: - format: dict | csv + format: dict | csv # if format csv, either define dictionary of rows or name of fixture - rows: - - {dictionary} + rows: + - {dictionary} fixture: overrides: # optional: configuration for the dbt execution environment macros: is_incremental: true | false dbt_utils.current_timestamp: str - # ... any other jinja function from https://docs.getdbt.com/reference/dbt-jinja-functions - # ... any other context property - vars: {dictionary} - env_vars: {dictionary} + # ... any other jinja function from https://docs.getdbt.com/reference/dbt-jinja-functions + # ... any other context property + vars: {dictionary} + env_vars: {dictionary} - name: ... # declare additional unit tests ``` From 8eee9342fc7186403277d39d341b643d02811ba4 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:20:10 -0500 Subject: [PATCH 08/84] Update website/docs/reference/resource-properties/unit-tests.md --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 7d4b1c44c17..973ec6b56dc 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -48,5 +48,5 @@ unit_tests: Unit tests validate your modeling logic on a small set of static inputs before you materialize your full model in production. Unit tests enable test-driven development, with benefits for developer efficiency and code reliability. -To run just your unit tests: +To run only your unit tests, use the command: `dbt test —-select test_type:unit` \ No newline at end of file From a79096259b7bbd984a97ffefdbbf31e66a0494c4 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:21:37 -0500 Subject: [PATCH 09/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: mirnawong1 <89008547+mirnawong1@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 973ec6b56dc..aa49d2d25c2 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -49,4 +49,4 @@ unit_tests: Unit tests validate your modeling logic on a small set of static inputs before you materialize your full model in production. Unit tests enable test-driven development, with benefits for developer efficiency and code reliability. To run only your unit tests, use the command: -`dbt test —-select test_type:unit` \ No newline at end of file +`dbt test --select test_type:unit` \ No newline at end of file From b6d8ed62f4012e74f54af61c4fc3fd12d389740c Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 7 Feb 2024 14:27:11 -0500 Subject: [PATCH 10/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Mirna Wong <89008547+mirnawong1@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index aa49d2d25c2..c8832e7fbab 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -46,7 +46,7 @@ unit_tests: ## Definition -Unit tests validate your modeling logic on a small set of static inputs before you materialize your full model in production. Unit tests enable test-driven development, with benefits for developer efficiency and code reliability. +Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and code reliability. To run only your unit tests, use the command: `dbt test --select test_type:unit` \ No newline at end of file From 9772609638f4b59b488e0dd6f7bac0e200a37abe Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:34:26 -0500 Subject: [PATCH 11/84] Adding /docs page for unit tests --- website/docs/docs/build/unit-tests.md | 138 ++++++++++++++++++++++++++ website/sidebars.js | 1 + 2 files changed, 139 insertions(+) create mode 100644 website/docs/docs/build/unit-tests.md diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md new file mode 100644 index 00000000000..e8cbc257852 --- /dev/null +++ b/website/docs/docs/build/unit-tests.md @@ -0,0 +1,138 @@ +--- +title: "Unit tests" +sidebar_label: "Unit tests" +description: "Read this tutorial to learn how to use unit tests on your SQL models." +search_weight: "heavy" +id: "unit-tests" +keywords: + - unit test, unit tests, unit testing, dag +--- +:::note closed beta + +Unit testing is currently in closed beta for dbt Cloud accounts that have updated to a [versionless environment](/docs/dbt-versions/upgrade-core-in-cloud). + +It is available now as an alpha feature for dbt Core v1.8 users. + +::: + +Historically, the test coverage capabilities of dbt were limited to “data” tests ‐ testing the quality of input data or the shape of the resulting datasets — that could only be executed *after* a model had been built. + +Now, we are introducing a new type of test to dbt - unit tests. In software programming, unit tests validate small portions of your functional code, and they work much the same way here. Unit tests allow you to validate your SQL modeling logic on a small set of static inputs _before_ you materialize your full model in production. Unit tests enable test-driven development, benefiting developer efficiency and code reliability. + +Let’s say you’re creating a new `dim_customers` model with a field `is_valid_email_address`, that calculates whether or not the customer’s email is valid: + +```sql +with customers as ( + + select * from {{ ref('stg_customers') }} + +), + +accepted_email_domains as ( + + select * from {{ ref('top_level_email_domains') }} + +), + +check_valid_emails as ( + + select + customers.customer_id, + customers.first_name, + customers.last_name, + coalesce (regexp_like( + customers.email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$' + ) + = true + and accepted_email_domains.tld is not null, + false) as is_valid_email_address + from customers + left join accepted_email_domains + on customers.email_top_level_domain = lower(accepted_email_domains.tld) + +) + +select * from check_valid_emails +``` + +This type of logic can be challenging to validate. Let’s add a unit test to this model to ensure our `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. + +```yaml +unit_tests: + - name: test_is_valid_email_address # this is the unique name of the test + description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. + model: dim_customers # name of the model you're unit testing + given: # the mock data for your inputs + - input: ref('stg_customers') + rows: + - {customer_id: 1, email: cool@example.com, email_top_level_domain: example.com} + - {customer_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} + - {customer_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} + - {customer_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} + - input: ref('top_level_email_domains') + rows: + - {tld: example.com} + - {tld: gmail.com} + expect: # the expected output given the inputs above + rows: + - {customer_id: 1, is_valid_email_address: true} + - {customer_id: 2, is_valid_email_address: false} + - {customer_id: 3, is_valid_email_address: false} + - {customer_id: 4, is_valid_email_address: false} +``` + +The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. + +You’ll notice that we _only_ had to define the mock data for the columns we care about. This enables you to write succinct and _specific_ unit tests. + +:::note + +The direct parents of the model that you’re unit testing (in this example `stg_customers` and `top_level_email_domains`) need to exist in the warehouse before you’re able to execute the unit test. + +Use the `—-empty` flag to build an empty version of those models to save warehouse spend. + +```bash + +`dbt run —-select "stg_customers top_level_email_domains" --empty`. + +``` + +Alternatively, use `dbt build` to, in lineage order: + +- Run the unit tests on your model. +- Materialize your model in the warehouse. +- Run the data tests on your model. + +::: + +Now we’re ready to run this unit test! We have a couple of options for commands depending on how specific we want to be: + +- `dbt test —-select dim_customers` runs _all_ of the tests on `dim_customers`. +- `dbt test —-select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. +- `dbt test —-select test_is_valid_email_address` runs the test named `test_is_valid_email_address`. + +[add screenshot] + +It looks like our clever regex statement wasn’t as clever as we thought as our model is incorrectly flagging `missingdot@gmailcom` as a valid email address. + +Updating our regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those darn escape characters!) and running the unit test again does the trick: + +[to add screenshot of example logs] + +Your model is now ready for production! Adding this unit test helped us catch an issue with the SQL logic _before_ you materialized `dim_customers` in your warehouse and will better ensure the reliability of this model in the future. + +### Best practices for “when to add a unit test to your model”: + +- when your SQL contains complex logic: + - Regex + - Date math + - Window functions + - `case when` statements when many `when`s + - Truncation + - Recursion +- Add a unit test for anything that feels like writing a function. For example, it involves your own logic processing the input. + - You wouldn't need to prioritize unit testing just calling `min()`, for example. That's already tested extensively by the warehouse and if something unexpected happens it's going to be a result of issues in the underlying data, so your fixture data in the unit test isn't going to help you. +- Logic for which you had bugs reported before. +- Edge cases not yet seen in your actual data that you want to handle. +- Prior to refactoring the transformation logic (especially if the refactor is significant). +- Models with high “criticality” (public, contracted models or models directly upstream of an exposure). \ No newline at end of file diff --git a/website/sidebars.js b/website/sidebars.js index 00b464a0277..79f8911aaa6 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -278,6 +278,7 @@ const sidebarSettings = { "docs/build/snapshots", "docs/build/seeds", "docs/build/tests", + "docs/build/unit-tests", "docs/build/jinja-macros", "docs/build/sources", "docs/build/exposures", From 19fd46385c5fffa0e878cc377d7581e8d4883b9c Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:04:38 -0500 Subject: [PATCH 12/84] fixing spacing on YML --- website/docs/docs/build/unit-tests.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index e8cbc257852..4a09d24eccc 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -60,7 +60,7 @@ This type of logic can be challenging to validate. Let’s add a unit test to th ```yaml unit_tests: - name: test_is_valid_email_address # this is the unique name of the test - description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. + description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. model: dim_customers # name of the model you're unit testing given: # the mock data for your inputs - input: ref('stg_customers') @@ -73,12 +73,12 @@ unit_tests: rows: - {tld: example.com} - {tld: gmail.com} - expect: # the expected output given the inputs above - rows: - - {customer_id: 1, is_valid_email_address: true} - - {customer_id: 2, is_valid_email_address: false} - - {customer_id: 3, is_valid_email_address: false} - - {customer_id: 4, is_valid_email_address: false} + expect: # the expected output given the inputs above + rows: + - {customer_id: 1, is_valid_email_address: true} + - {customer_id: 2, is_valid_email_address: false} + - {customer_id: 3, is_valid_email_address: false} + - {customer_id: 4, is_valid_email_address: false} ``` The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. From f044ff17c2df7ad50b30a94ba2e5abe6b4b19d65 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:11:14 -0500 Subject: [PATCH 13/84] Update unit-tests.md Fixing yml spacing --- website/docs/docs/build/unit-tests.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 4a09d24eccc..09c28dbbfe7 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -60,7 +60,7 @@ This type of logic can be challenging to validate. Let’s add a unit test to th ```yaml unit_tests: - name: test_is_valid_email_address # this is the unique name of the test - description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. + description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. model: dim_customers # name of the model you're unit testing given: # the mock data for your inputs - input: ref('stg_customers') @@ -73,12 +73,12 @@ unit_tests: rows: - {tld: example.com} - {tld: gmail.com} - expect: # the expected output given the inputs above - rows: - - {customer_id: 1, is_valid_email_address: true} - - {customer_id: 2, is_valid_email_address: false} - - {customer_id: 3, is_valid_email_address: false} - - {customer_id: 4, is_valid_email_address: false} + - expect: # the expected output given the inputs above + rows: + - {customer_id: 1, is_valid_email_address: true} + - {customer_id: 2, is_valid_email_address: false} + - {customer_id: 3, is_valid_email_address: false} + - {customer_id: 4, is_valid_email_address: false} ``` The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. @@ -135,4 +135,4 @@ Your model is now ready for production! Adding this unit test helped us catch an - Logic for which you had bugs reported before. - Edge cases not yet seen in your actual data that you want to handle. - Prior to refactoring the transformation logic (especially if the refactor is significant). -- Models with high “criticality” (public, contracted models or models directly upstream of an exposure). \ No newline at end of file +- Models with high “criticality” (public, contracted models or models directly upstream of an exposure). From 56db5cafc6af98d32923bff9927595742e8c0586 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:16:04 -0500 Subject: [PATCH 14/84] Update unit-tests.md FIXING SPACING AGAIN --- website/docs/docs/build/unit-tests.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 09c28dbbfe7..442803f5b42 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -61,7 +61,7 @@ This type of logic can be challenging to validate. Let’s add a unit test to th unit_tests: - name: test_is_valid_email_address # this is the unique name of the test description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. - model: dim_customers # name of the model you're unit testing + model: dim_customers # name of the model I'm unit testing given: # the mock data for your inputs - input: ref('stg_customers') rows: @@ -73,12 +73,12 @@ unit_tests: rows: - {tld: example.com} - {tld: gmail.com} - - expect: # the expected output given the inputs above - rows: - - {customer_id: 1, is_valid_email_address: true} - - {customer_id: 2, is_valid_email_address: false} - - {customer_id: 3, is_valid_email_address: false} - - {customer_id: 4, is_valid_email_address: false} + expect: # the expected output given the inputs above + rows: + - {customer_id: 1, is_valid_email_address: true} + - {customer_id: 2, is_valid_email_address: false} + - {customer_id: 3, is_valid_email_address: false} + - {customer_id: 4, is_valid_email_address: false} ``` The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. From 6112e01753b0369e4b6ba8e9c3225f7de46cf6a5 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:20:45 -0500 Subject: [PATCH 15/84] Update unit-tests.md --- website/docs/docs/build/unit-tests.md | 31 ++++++++++++++------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 442803f5b42..322dedf747d 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -59,26 +59,27 @@ This type of logic can be challenging to validate. Let’s add a unit test to th ```yaml unit_tests: - - name: test_is_valid_email_address # this is the unique name of the test - description: Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains. - model: dim_customers # name of the model I'm unit testing - given: # the mock data for your inputs + - name: test_is_valid_email_address + description: "Check my is_valid_email_address logic captures all known edge cases - emails without ., emails without @, and emails from invalid domains." + model: dim_customers + given: - input: ref('stg_customers') rows: - - {customer_id: 1, email: cool@example.com, email_top_level_domain: example.com} - - {customer_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} - - {customer_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} - - {customer_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} + - {customer_id: 1, email: cool@example.com, email_top_level_domain: example.com} + - {customer_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} + - {customer_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} + - {customer_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} - input: ref('top_level_email_domains') rows: - - {tld: example.com} - - {tld: gmail.com} - expect: # the expected output given the inputs above + - {tld: example.com} + - {tld: gmail.com} + expect: rows: - - {customer_id: 1, is_valid_email_address: true} - - {customer_id: 2, is_valid_email_address: false} - - {customer_id: 3, is_valid_email_address: false} - - {customer_id: 4, is_valid_email_address: false} + - {customer_id: 1, is_valid_email_address: true} + - {customer_id: 2, is_valid_email_address: false} + - {customer_id: 3, is_valid_email_address: false} + - {customer_id: 4, is_valid_email_address: false} + ``` The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. From 1687dd365aff4b4a59d087e452ce87aee432de86 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:17:49 -0500 Subject: [PATCH 16/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 322dedf747d..e8e2b2092f3 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -94,7 +94,7 @@ Use the `—-empty` flag to build an empty version of those models to save wareh ```bash -`dbt run —-select "stg_customers top_level_email_domains" --empty`. +dbt run —-select "stg_customers top_level_email_domains" --empty ``` From a18b387265fc5c1c01dc5ac581bf1f167d01cf9c Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:45:25 -0500 Subject: [PATCH 17/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index e8e2b2092f3..f959171b9ad 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -114,7 +114,7 @@ Now we’re ready to run this unit test! We have a couple of options for command [add screenshot] -It looks like our clever regex statement wasn’t as clever as we thought as our model is incorrectly flagging `missingdot@gmailcom` as a valid email address. +It looks like our clever regex statement wasn’t as clever as we thought as our model is incorrectly flagging `cool@example.com` as an invalid email address. Updating our regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those darn escape characters!) and running the unit test again does the trick: From 5ffa00b68f458c63786be4fd2ae595ecd208421f Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:46:57 -0500 Subject: [PATCH 18/84] Updates --- website/docs/docs/build/tests.md | 2 +- website/docs/docs/build/unit-tests.md | 56 +++++++ website/docs/reference/commands/test.md | 45 ++++++ .../resource-properties/unit-tests.md | 150 +++++++++++++++++- website/sidebars.js | 19 ++- 5 files changed, 267 insertions(+), 5 deletions(-) diff --git a/website/docs/docs/build/tests.md b/website/docs/docs/build/tests.md index 3d86dc6a81b..678468ca504 100644 --- a/website/docs/docs/build/tests.md +++ b/website/docs/docs/build/tests.md @@ -1,6 +1,6 @@ --- title: "Add tests to your DAG" -sidebar_label: "Tests" +sidebar_label: "Data tests" description: "Read this tutorial to learn how to use tests when building in dbt." search_weight: "heavy" id: "tests" diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 322dedf747d..11697a1150b 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -19,6 +19,15 @@ Historically, the test coverage capabilities of dbt were limited to “data” t Now, we are introducing a new type of test to dbt - unit tests. In software programming, unit tests validate small portions of your functional code, and they work much the same way here. Unit tests allow you to validate your SQL modeling logic on a small set of static inputs _before_ you materialize your full model in production. Unit tests enable test-driven development, benefiting developer efficiency and code reliability. +:::note Before you begin + +- We currently only support unit testing SQL models. +- We currently only support adding unit tests to models in your _current_ project. +- If your model has multiple versions, be default the unit test will run on *all* versions of your model. Read [unit testing versioned models for more information](#unit-testing-versioned-models). + +Read the [refernce doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. +::: + Let’s say you’re creating a new `dim_customers` model with a field `is_valid_email_address`, that calculates whether or not the customer’s email is valid: ```sql @@ -122,6 +131,53 @@ Updating our regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` Your model is now ready for production! Adding this unit test helped us catch an issue with the SQL logic _before_ you materialized `dim_customers` in your warehouse and will better ensure the reliability of this model in the future. +### Unit testing versioned models + +When a unit test is added to a model, with no supplied version, the unit test will run on all versions of the model. +Using the example on this page, if you have version 1, 2, and 3 of `my_model`, `my test_is_valid_email_address` unit test will run on all 3 versions. + +To to only unit test a specific version (or versions) of a model, you can include the desired version(s) in the model config: + +```yml + +unit-tests: + - name: test_is_valid_email_address # this is the unique name of the test + model: my_model # name of the model I'm unit testing + versions: + include: + - 2 + given: # optional: list of inputs to provide as fixtures + +``` + +In this scenario, if you have version 1, 2, and 3 of `my_model`, `my test_is_valid_email_address` unit test will run on _only_ version 2. + +To to unit test all versions except a specific version (or versions) of a model, you can exclude the relevant version(s) in the model config: + +```yml + +unit-tests: + - name: test_is_valid_email_address # this is the unique name of the test + model: my_model # name of the model I'm unit testing + versions: + exclude: + - 1 + given: # optional: list of inputs to provide as fixtures + +``` +So if you have version 1, 2, and 3 of `my_model`, your `test_is_valid_email_address` unit test will run on _only_ version 2 and 3. + +If you want to unit test a model that references a pinned version of model, you should specify that in the ref of your input: + +```yml + +unit-tests: + - name: test_is_valid_email_address # this is the unique name of the test + model: my_model # name of the model I'm unit testing + given: # optional: list of inputs to provide as fixtures + +``` + ### Best practices for “when to add a unit test to your model”: - when your SQL contains complex logic: diff --git a/website/docs/reference/commands/test.md b/website/docs/reference/commands/test.md index c050d82a0ab..0b60cc87941 100644 --- a/website/docs/reference/commands/test.md +++ b/website/docs/reference/commands/test.md @@ -3,6 +3,7 @@ title: "About dbt test command" sidebar_label: "test" id: "test" --- + `dbt test` runs tests defined on models, sources, snapshots, and seeds. It expects that you have already created those resources through the appropriate commands. @@ -29,3 +30,47 @@ dbt test --select "one_specific_model,test_type:generic" ``` For more information on writing tests, see the [Testing Documentation](/docs/build/tests). + + + + + +`dbt test` runs data tests and unit tests defined on models, sources, snapshots, and seeds. It expects that you have already created those resources through the appropriate commands. + +The tests to run can be selected using the `--select` flag discussed [here](/reference/node-selection/syntax). + +```bash +# run data and unit tests +dbt test + +# run only data tests +dbt test --select test_type:data + +# run only unit tests +dbt test --select test_type:unit + +# run tests for one_specific_model +dbt test --select "one_specific_model" + +# run tests for all models in package +dbt test --select "some_package.*" + +# run only tests defined singularly +dbt test --select "test_type:singular" + +# run only tests defined generically +dbt test --select "test_type:generic" + +# run singular tests limited to one_specific_model +dbt test --select "one_specific_model,test_type:singular" + +# run generic tests limited to one_specific_model +dbt test --select "one_specific_model,test_type:generic" +``` + +For more information on writing tests, read the [data testing](/docs/build/tests) and [unit testing](/docs/build/unit-tests) documentation. + + + + + diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index c8832e7fbab..c0e4eead166 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -1,6 +1,6 @@ --- title: "About unit tests property" -sidebar_label: "unit tests" +sidebar_label: "Unit tests" resource_types: [models] datatype: test --- @@ -12,6 +12,9 @@ datatype: test unit_tests: - name: # this is the unique name of the test model: + versions: #optional + include: #optional + exclude: #optional config: meta: {dictionary} tags: | [] @@ -49,4 +52,147 @@ unit_tests: Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and code reliability. To run only your unit tests, use the command: -`dbt test --select test_type:unit` \ No newline at end of file +`dbt test --select test_type:unit` + +### About writing unit tests + +Unit tests are currently limited to testing SQL models and only models in your current project. When writing your unit tests, keep the following in mind: +- If your model has multiple versions, be default the unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, `include` or `exclude` the desired versions in your model versions config: + + ```yaml +# my test_is_valid_email_address unit test will run on all 3 versions +unit-tests: + - name: test_is_valid_email_address + model: my_model +... + +# my test_is_valid_email_address unit test will run on ONLY version 2 +unit-tests: + - name: test_is_valid_email_address + model: my_model + versions: + include: + - 2 +... + +# my test_is_valid_email_address unit test will run on ONLY version 2 and 3 +unit-tests: + - name: test_is_valid_email_address + model: my_model + versions: + exclude: + - 1 +... + +``` + +-When using `format: dict` you must supply an in-line dictionary for `rows:` (this is the default, if you don’t specify a `format`) + +```yml + +unit_tests: + - name: test_my_model + model: my_model + given: + - input: ref('my_model_a') + format: dict + rows: + - {id: 1, name: gerda} + - {id: 2, b: michelle} + +``` + +- When `format: csv`, can either supply: + - An inline csv string for `rows:` + + ```yaml + unit_tests: + - name: test_my_model + model: my_model + given: + - input: ref('my_model_a') + format: csv + rows: | + id,name + 1,gerda + 2,michelle + + ... + ``` + + - The name of a csv file in the `tests/fixtures` directory in your project (or the directory configured for [test-paths](https://docs.getdbt.com/reference/project-configs/test-paths)) for `fixture`: + + ```yaml + unit_tests: + - name: test_my_model + model: my_model + given: + - input: ref('my_model_a') + format: csv + fixture: my_model_a_fixture + ... + ``` + + ```yaml + # tests/fixtures/my_model_a_fixture.csv + 1,gerda + 2,michelle + ``` + +- `input:` string that represents a `ref` or `source` call: + - `ref('my_model')` or `ref('my_model', v='2')` or `ref('dougs_project', 'users')` + - `source('source_schema', 'source_name')` +- `input:` is optional for seeds: + - If you don’t supply an input for a seed, we will use the seed *as* the input. + - If you do supply an input for a seed, we will use that input instead. +- You can also have “empty” inputs, by setting rows to an empty list `rows: []`: + +Examples: +```yml + +unit_tests: + - name: test_is_valid_email_address # this is the unique name of the test + model: my_model # name of the model I'm unit testing + given: # the mock data for your inputs + - input: ref('users') + rows: + - {user_id: 1, email: cool@example.com, email_top_level_domain: example.com} + - {user_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} + - {user_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} + - {user_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} + - input: ref('top_level_domains') + rows: + - {tld: example.com} + - {tld: gmail.com} + expect: # the expected output given the inputs above + rows: + - {user_id: 1, is_valid_email_address: true} + - {user_id: 2, is_valid_email_address: false} + - {user_id: 3, is_valid_email_address: false} + - {user_id: 4, is_valid_email_address: false} + +``` + +```yml + +unit_tests: + - name: test_is_valid_email_address # this is the unique name of the test + model: my_model # name of the model I'm unit testing + given: # the mock data for your inputs + - input: ref('users') + rows: + - {user_id: 1, email: cool@example.com, email_top_level_domain: example.com} + - {user_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} + - {user_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} + - {user_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} + - input: ref('top_level_domains') + format: csv + rows: | + tld + example.com + gmail.com + expect: # the expected output given the inputs above + format: csv + fixture: my_model_fixture + +``` \ No newline at end of file diff --git a/website/sidebars.js b/website/sidebars.js index 79f8911aaa6..ce1fa2d513b 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -275,6 +275,15 @@ const sidebarSettings = { "docs/build/python-models", ], }, + { + type: "category", + label: "Tests", + link: { type: "doc", id: "docs/build/models" }, + items: [ + "docs/build/tests", + "docs/build/unit-tests", + ], + }, "docs/build/snapshots", "docs/build/seeds", "docs/build/tests", @@ -745,7 +754,6 @@ const sidebarSettings = { "reference/resource-properties/include-exclude", "reference/resource-properties/quote", "reference/resource-properties/tests", - "reference/resource-properties/unit-tests", "reference/resource-properties/versions", ], }, @@ -809,7 +817,7 @@ const sidebarSettings = { }, { type: "category", - label: "For tests", + label: "For data tests", items: [ "reference/test-configs", "reference/resource-configs/fail_calc", @@ -820,6 +828,13 @@ const sidebarSettings = { "reference/resource-configs/where", ], }, + { + type: "category", + label: "For unit tests", + items: [ + "reference/resource-properties/unit-tests", + ], + }, { type: "category", label: "For sources", From 2329f3fbb108310b44eb5bbd6a034cbb659d00ac Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:47:02 -0500 Subject: [PATCH 19/84] Updates from feedback --- website/docs/docs/build/unit-tests.md | 62 ++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 11697a1150b..b2433c2511e 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -64,7 +64,7 @@ check_valid_emails as ( select * from check_valid_emails ``` -This type of logic can be challenging to validate. Let’s add a unit test to this model to ensure our `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. +This type of logic can be challenging to validate. You can add a unit test to this model to ensure your `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. ```yaml unit_tests: @@ -93,7 +93,7 @@ unit_tests: The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. -You’ll notice that we _only_ had to define the mock data for the columns we care about. This enables you to write succinct and _specific_ unit tests. +You’ll notice that you only_had to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. :::note @@ -121,13 +121,63 @@ Now we’re ready to run this unit test! We have a couple of options for command - `dbt test —-select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. - `dbt test —-select test_is_valid_email_address` runs the test named `test_is_valid_email_address`. -[add screenshot] +```bash + +dbt test --select test_is_valid_email_address +16:03:49 Running with dbt=1.8.0-a1 +16:03:49 Registered adapter: postgres=1.8.0-a1 +16:03:50 Found 6 models, 5 seeds, 4 data tests, 0 sources, 0 exposures, 0 metrics, 410 macros, 0 groups, 0 semantic models, 1 unit test +16:03:50 +16:03:50 Concurrency: 5 threads (target='postgres') +16:03:50 +16:03:50 1 of 1 START unit_test dim_customers::test_is_valid_email_address ................... [RUN] +16:03:51 1 of 1 FAIL 1 dim_customers::test_is_valid_email_address ............................ [FAIL 1 in 0.26s] +16:03:51 +16:03:51 Finished running 1 unit_test in 0 hours 0 minutes and 0.67 seconds (0.67s). +16:03:51 +16:03:51 Completed with 1 error and 0 warnings: +16:03:51 +16:03:51 Failure in unit_test test_is_valid_email_address (models/marts/unit_tests.yml) +16:03:51 + +actual differs from expected: + +@@ ,customer_id,is_valid_email_address +→ ,1 ,True→False + ,2 ,False +...,... ,... + + +16:03:51 +16:03:51 compiled Code at models/marts/unit_tests.yml +16:03:51 +16:03:51 Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1 + +``` -It looks like our clever regex statement wasn’t as clever as we thought as our model is incorrectly flagging `missingdot@gmailcom` as a valid email address. +It looks like the clever regex statement wasn’t as clever as we thought as the model is incorrectly flagging `missingdot@gmailcom` as a valid email address. -Updating our regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those darn escape characters!) and running the unit test again does the trick: +Updating the regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those darn escape characters!) and running the unit test again solves the problem: -[to add screenshot of example logs] +```bash + +dbt test --select test_is_valid_email_address +16:09:11 Running with dbt=1.8.0-a1 +16:09:12 Registered adapter: postgres=1.8.0-a1 +16:09:12 Found 6 models, 5 seeds, 4 data tests, 0 sources, 0 exposures, 0 metrics, 410 macros, 0 groups, 0 semantic models, 1 unit test +16:09:12 +16:09:13 Concurrency: 5 threads (target='postgres') +16:09:13 +16:09:13 1 of 1 START unit_test dim_wizards::test_is_valid_email_address ................... [RUN] +16:09:13 1 of 1 PASS dim_wizards::test_is_valid_email_address .............................. [PASS in 0.26s] +16:09:13 +16:09:13 Finished running 1 unit_test in 0 hours 0 minutes and 0.75 seconds (0.75s). +16:09:13 +16:09:13 Completed successfully +16:09:13 +16:09:13 Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1 + +``` Your model is now ready for production! Adding this unit test helped us catch an issue with the SQL logic _before_ you materialized `dim_customers` in your warehouse and will better ensure the reliability of this model in the future. From 829c40ce5ea6d6a95c0131c004bbab59495caaf0 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:10:25 -0500 Subject: [PATCH 20/84] Reverting changes --- website/docs/faqs/Accounts/transfer-account.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/website/docs/faqs/Accounts/transfer-account.md b/website/docs/faqs/Accounts/transfer-account.md index 3d602ba11d1..f12a6ab209a 100644 --- a/website/docs/faqs/Accounts/transfer-account.md +++ b/website/docs/faqs/Accounts/transfer-account.md @@ -3,22 +3,20 @@ title: How do I transfer account ownership to another user? description: "Instructions on how to transfer your dbt Cloud user account to another user" sidebar_label: 'How to transfer dbt Cloud account?' id: transfer-account - --- You can transfer your dbt Cloud [access control](/docs/cloud/manage-access/about-user-access) to another user by following the steps below, depending on your dbt Cloud account plan: | Account plan| Steps | | ------ | ---------- | -| **Developer** | You can transfer ownership by changing the email directly on your dbt Cloud profile page, which you can access using this URL when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile` | +| **Developer** | You can transfer ownership by changing the email directly on your dbt Cloud profile page, which you can access using this URL when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile`. Before doing this, please ensure that you unlink your GitHub profile. | | **Team** | Existing account admins with account access can add users to, or remove users from the owner group. | | **Enterprise** | Account admins can add users to, or remove users from a group with Account Admin permissions. | | **If all account owners left the company** | If the account owner has left your organization, you will need to work with _your_ IT department to have incoming emails forwarded to the new account owner. Once your IT department has redirected the emails, you can request to reset the user password. Once you log in, you can change the email on the Profile page when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile`. | -| **If all account owners left the company** | If the account owner has left your organization, you will need to work with _your_ IT department to have incoming emails forwarded to the new account owner. Once your IT department has redirected the emails, you can request to reset the user password. Once you log in, you can change the email on the Profile page when you replace `YOUR_ACCESS_URL` with the [appropriate Access URL](/docs/cloud/about-cloud/access-regions-ip-addresses) for your region and plan: `https://YOUR_ACCESS_URL/settings/profile`. | When you make any account owner and email changes: - The new email address _must_ be verified through our email verification process. - You can update any billing email address or [Notifications Settings](/docs/deploy/job-notifications) to reflect the new account owner changes, if applicable. - When transferring account ownership, please ensure you [unlink](/faqs/Accounts/git-account-in-use) your GitHub account in dbt Cloud. This is because you can only have your Git account linked to one dbt Cloud user account. - + \ No newline at end of file From 7547ecb44c92087231c5dd76f512a5eb8ff51143 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:12:28 -0500 Subject: [PATCH 21/84] fixing edits --- .../docs/docs/dbt-versions/release-notes/76-Oct-2023/sl-ga.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/dbt-versions/release-notes/76-Oct-2023/sl-ga.md b/website/docs/docs/dbt-versions/release-notes/76-Oct-2023/sl-ga.md index 35ef60bb125..06818042539 100644 --- a/website/docs/docs/dbt-versions/release-notes/76-Oct-2023/sl-ga.md +++ b/website/docs/docs/dbt-versions/release-notes/76-Oct-2023/sl-ga.md @@ -18,7 +18,7 @@ It aims to bring the best of modeling and semantics to downstream applications b - Brand new [integrations](/docs/use-dbt-semantic-layer/avail-sl-integrations) such as Tableau, Google Sheets, Hex, Mode, and Lightdash. - New [Semantic Layer APIs](/docs/dbt-cloud-apis/sl-api-overview) using GraphQL and JDBC to query metrics and build integrations. - dbt Cloud [multi-tenant regional](/docs/cloud/about-cloud/access-regions-ip-addresses) support for North America, EMEA, and APAC. Single-tenant support coming soon. -- Use the APIs to call an export (a way to build tables in your data platform), then access them in your preferred BI tool. Starting from dbt v1.7 or higher, you will be able to schedule exports as part of your dbt job. +- Coming soon — Schedule exports (a way to build tables in your data platform) as part of your dbt Cloud job. Use the APIs to call an export, then access them in your preferred BI tool. From ada59190f1c6599ebfab3609e2e6223cf43bf7b1 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:14:17 -0500 Subject: [PATCH 22/84] fixing --- website/snippets/_v2-sl-prerequisites.md | 29 +----------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/website/snippets/_v2-sl-prerequisites.md b/website/snippets/_v2-sl-prerequisites.md index 432480e9a21..18f228ad3fe 100644 --- a/website/snippets/_v2-sl-prerequisites.md +++ b/website/snippets/_v2-sl-prerequisites.md @@ -7,31 +7,4 @@ - Set up the [Semantic Layer API](/docs/dbt-cloud-apis/sl-api-overview) in the integrated tool to import metric definitions. - dbt Core or Developer accounts can define metrics but won't be able to dynamically query them.
- Understand [MetricFlow's](/docs/build/about-metricflow) key concepts, which powers the latest dbt Semantic Layer. -- Note that SSH tunneling for [Postgres and Redshift](/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb) connections, [PrivateLink](/docs/cloud/secure/about-privatelink), and [Single sign-on (SSO)](/docs/cloud/manage-access/sso-overview) doesn't supported the dbt Semantic Layer yet. - -
- - - - -- Have a multi-tenant dbt Cloud instance, hosted in North America
-- Have both your production and development environments running dbt version 1.3 or higher
-- Use Snowflake data platform
-- Install the dbt metrics package version >=1.3.0, <1.4.0 in your dbt project
- * **Note** — After installing the dbt metrics package and updating the `packages.yml` file, make sure you run at least one model. -- Set up the Discovery API in the integrated tool to import metric definitions - * Developer accounts will be able to query the Proxy Server using SQL, but will not be able to browse pre-populated dbt metrics in external tools, which requires access to the Discovery API
- -
- - - -- Have a multi-tenant dbt Cloud instance, hosted in North America
-- Have both your production and development environments running dbt version 1.2
-- Use Snowflake data platform
-- Install the dbt metrics package version >=0.3.0, <0.4.0 in your dbt project
- * **Note** — After installing the dbt metrics package and updating the `packages.yml` file, make sure you run at least one model. -- Set up the Discovery API in the integrated tool to import metric definitions - * Developer accounts will be able to query the Proxy Server using SQL, but will not be able to browse pre-populated dbt metrics in external tools, which requires access to the Discovery API
- -
+- Note that SSH tunneling for [Postgres and Redshift](/docs/cloud/connect-data-platform/connect-redshift-postgresql-alloydb) connections, [PrivateLink](/docs/cloud/secure/about-privatelink), and [Single sign-on (SSO)](/docs/cloud/manage-access/sso-overview) doesn't support the dbt Semantic Layer yet. From 59cbb84b40cb1606c00683cfa6ac7da81524da7a Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:15:24 -0500 Subject: [PATCH 23/84] fixing --- website/docs/faqs/Accounts/transfer-account.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/faqs/Accounts/transfer-account.md b/website/docs/faqs/Accounts/transfer-account.md index f12a6ab209a..693061c55c6 100644 --- a/website/docs/faqs/Accounts/transfer-account.md +++ b/website/docs/faqs/Accounts/transfer-account.md @@ -3,6 +3,7 @@ title: How do I transfer account ownership to another user? description: "Instructions on how to transfer your dbt Cloud user account to another user" sidebar_label: 'How to transfer dbt Cloud account?' id: transfer-account + --- You can transfer your dbt Cloud [access control](/docs/cloud/manage-access/about-user-access) to another user by following the steps below, depending on your dbt Cloud account plan: @@ -19,4 +20,4 @@ When you make any account owner and email changes: - The new email address _must_ be verified through our email verification process. - You can update any billing email address or [Notifications Settings](/docs/deploy/job-notifications) to reflect the new account owner changes, if applicable. - When transferring account ownership, please ensure you [unlink](/faqs/Accounts/git-account-in-use) your GitHub account in dbt Cloud. This is because you can only have your Git account linked to one dbt Cloud user account. - \ No newline at end of file + From 4fb38a29b5d5716067dbd3d6c253a3d619b219a1 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:16:57 -0500 Subject: [PATCH 24/84] Updating sidebar folders --- website/sidebars.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/website/sidebars.js b/website/sidebars.js index d6913088963..2220de7b331 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -282,14 +282,12 @@ const sidebarSettings = { label: "Tests", link: { type: "doc", id: "docs/build/models" }, items: [ - "docs/build/tests", + "docs/build/data-tests", "docs/build/unit-tests", ], }, "docs/build/snapshots", "docs/build/seeds", - "docs/build/data-tests", - "docs/build/unit-tests", "docs/build/jinja-macros", "docs/build/sources", "docs/build/exposures", From 6fe72ffebe743e288bee66b598dbf910e931caae Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:18:22 -0500 Subject: [PATCH 25/84] Fixing errors --- .../docs/cloud/about-cloud/regions-ip-addresses.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md b/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md index 844714b7fbf..72ab367d6de 100644 --- a/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md +++ b/website/docs/docs/cloud/about-cloud/regions-ip-addresses.md @@ -23,17 +23,17 @@ dbt Cloud is [hosted](/docs/cloud/about-cloud/architecture) in multiple regions ## Accessing your account -To login to dbt Cloud, use the URL that applies to your environment. Your access URL used will depend on a few factors including location and tenancy: -- **US multi-tenant:** Use your unique URL that starts with your account prefix, followed by `us1.dbt.com`. For example, `abc123.us1.dbt.com`. - - If you are unsure of your access URL, navigate to `us1.dbt.com` and enter your credentials. If you are a member of a single account, you will be logged in and your URL will be displayed in the browser. If you are a member of muliple accounts, you will be presented with a list of options, along with the appropriate login URLs for each +To log into dbt Cloud, use the URL that applies to your environment. Your access URL used will depend on a few factors, including location and tenancy: +- **US multi-tenant:** Use your unique URL that starts with your account prefix, followed by `us1.dbt.com`. For example, `abc123.us1.dbt.com`. You can also use `cloud.getdbt.com`, but this URL will be removed in the future. + - If you are unsure of your access URL, navigate to `us1.dbt.com` and enter your dbt Cloud credentials. If you are a member of a single account, you will be logged in, and your URL will be displayed in the browser. If you are a member of multiple accounts, you will be presented with a list of options, along with the appropriate login URLs for each. -- **EMEA multi-tenant:** Use the URL `emea.dbt.com`. -- **APAC multi-tenant:** Use the URL `au.dbt.com`. +- **EMEA multi-tenant:** Use `emea.dbt.com`. +- **APAC multi-tenant:** Use `au.dbt.com`. - **Worldwide single-tenant and VPC:** Use the vanity URL provided during your onboarding. -### Locating your dbt Cloud IP addresses +## Locating your dbt Cloud IP addresses There are two ways to view your dbt Cloud IP addresses: - If no projects exist in the account, create a new project, and the IP addresses will be displayed during the **Configure your environment** steps. From d621b2b2622d3c583c02a2adeee9504152846cfa Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:23:41 -0500 Subject: [PATCH 26/84] Update unit-tests.md Fixing spacing --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 385aa6a4ba6..72f6bd372aa 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -49,7 +49,7 @@ check_valid_emails as ( customers.customer_id, customers.first_name, customers.last_name, - coalesce (regexp_like( + coalesce (regexp_like( customers.email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$' ) = true From b6376c164812a496b656899082f92fd87d4d2ed6 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:26:37 -0500 Subject: [PATCH 27/84] fixing yet another merge error --- website/vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/vercel.json b/website/vercel.json index 158d43cdc0b..9da721dc112 100644 --- a/website/vercel.json +++ b/website/vercel.json @@ -1324,7 +1324,7 @@ }, { "source": "/docs/deploy/regions-ip-addresses", - "destination": "/docs/cloud/about-cloud/access-regions-ip-addresses", + "destination": "/docs/cloud/about-cloud/regions-ip-addresses", "permanent": true }, { From 688aeded52a44e100dd02f6991b3914491641931 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:33:24 -0500 Subject: [PATCH 28/84] Update unit-tests.md Fixing code spacing --- .../docs/reference/resource-properties/unit-tests.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index c0e4eead166..20e21d5602f 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -165,11 +165,11 @@ unit_tests: - {tld: example.com} - {tld: gmail.com} expect: # the expected output given the inputs above - rows: - - {user_id: 1, is_valid_email_address: true} - - {user_id: 2, is_valid_email_address: false} - - {user_id: 3, is_valid_email_address: false} - - {user_id: 4, is_valid_email_address: false} + rows: + - {user_id: 1, is_valid_email_address: true} + - {user_id: 2, is_valid_email_address: false} + - {user_id: 3, is_valid_email_address: false} + - {user_id: 4, is_valid_email_address: false} ``` @@ -195,4 +195,4 @@ unit_tests: format: csv fixture: my_model_fixture -``` \ No newline at end of file +``` From 80ec818f9746ad49169be56565dd0fa793914798 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:35:29 -0500 Subject: [PATCH 29/84] Update unit-tests.md Fixing spacing --- website/docs/reference/resource-properties/unit-tests.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 20e21d5602f..4232c1cae9a 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -13,8 +13,8 @@ unit_tests: - name: # this is the unique name of the test model: versions: #optional - include: #optional - exclude: #optional + include: #optional + exclude: #optional config: meta: {dictionary} tags: | [] From ed9e312ed63bcca57a99ad02fa3cf9c35269621e Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:38:22 -0500 Subject: [PATCH 30/84] Updating based on feedback --- website/docs/docs/build/unit-tests.md | 2 ++ .../reference/resource-properties/unit-tests.md | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 72f6bd372aa..8bc5a0f246f 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -30,6 +30,8 @@ Read the [refernce doc](/reference/resource-properties/unit-tests) for more deta Let’s say you’re creating a new `dim_customers` model with a field `is_valid_email_address`, that calculates whether or not the customer’s email is valid: + + ```sql with customers as ( diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index c0e4eead166..3a5b8334ff4 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -5,6 +5,13 @@ resource_types: [models] datatype: test --- +## Definition + +Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and code reliability. + +To run only your unit tests, use the command: +`dbt test --select test_type:unit` + ```yml @@ -47,13 +54,6 @@ unit_tests: -## Definition - -Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and code reliability. - -To run only your unit tests, use the command: -`dbt test --select test_type:unit` - ### About writing unit tests Unit tests are currently limited to testing SQL models and only models in your current project. When writing your unit tests, keep the following in mind: From 420e2f1fd3a8cac90fef505cfd04fe74c10b2041 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:39:49 -0500 Subject: [PATCH 31/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 8bc5a0f246f..22f9196aeb0 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -101,7 +101,7 @@ You’ll notice that you only_had to define the mock data for the columns you ca The direct parents of the model that you’re unit testing (in this example `stg_customers` and `top_level_email_domains`) need to exist in the warehouse before you’re able to execute the unit test. -Use the `—-empty` flag to build an empty version of those models to save warehouse spend. +Use the `--empty` flag to build an empty version of those models to save warehouse spend. ```bash From 75ca6f57c685e998d5115511f8957e6454f00a78 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:40:58 -0500 Subject: [PATCH 32/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 22f9196aeb0..9af51e6559f 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -30,7 +30,7 @@ Read the [refernce doc](/reference/resource-properties/unit-tests) for more deta Let’s say you’re creating a new `dim_customers` model with a field `is_valid_email_address`, that calculates whether or not the customer’s email is valid: - + ```sql with customers as ( From 4281976bedb8acd0f4a239c70e00bbe0d291a535 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:41:55 -0500 Subject: [PATCH 33/84] Update unit-tests.md Adding filename --- website/docs/docs/build/unit-tests.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 9af51e6559f..f145e681e4b 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -68,6 +68,8 @@ select * from check_valid_emails This type of logic can be challenging to validate. You can add a unit test to this model to ensure your `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. + + ```yaml unit_tests: - name: test_is_valid_email_address From 9dbb79a1a34ee0134ab95b0eec4fd81752707f69 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:46:46 -0500 Subject: [PATCH 34/84] Update unit-tests.md Fixing spacing errors --- website/docs/reference/resource-properties/unit-tests.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index dbd7c867ad9..265edbe61e9 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -186,13 +186,13 @@ unit_tests: - {user_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} - {user_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} - input: ref('top_level_domains') - format: csv - rows: | - tld + format: csv + rows: | + tld example.com gmail.com expect: # the expected output given the inputs above - format: csv + format: csv fixture: my_model_fixture ``` From 0de14e732535024a306f048a96ac96b1f9b4e235 Mon Sep 17 00:00:00 2001 From: Doug Beatty <44704949+dbeatty10@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:31:07 -0700 Subject: [PATCH 35/84] Apply suggestions from code review --- website/docs/docs/build/unit-tests.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index f145e681e4b..247a0154a22 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -23,14 +23,14 @@ Now, we are introducing a new type of test to dbt - unit tests. In software prog - We currently only support unit testing SQL models. - We currently only support adding unit tests to models in your _current_ project. -- If your model has multiple versions, be default the unit test will run on *all* versions of your model. Read [unit testing versioned models for more information](#unit-testing-versioned-models). +- If your model has multiple versions, by default the unit test will run on *all* versions of your model. Read [unit testing versioned models for more information](#unit-testing-versioned-models). -Read the [refernce doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. +Read the [reference doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. ::: Let’s say you’re creating a new `dim_customers` model with a field `is_valid_email_address`, that calculates whether or not the customer’s email is valid: - + ```sql with customers as ( From b94fb0aeb54f842aab8eea6635b4f6b1af89d3d7 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 19:34:11 -0500 Subject: [PATCH 36/84] Apply suggestions from code review --- website/docs/docs/build/unit-tests.md | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 247a0154a22..107f9ddd436 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -97,13 +97,13 @@ unit_tests: The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. -You’ll notice that you only_had to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. +Notice that you only have to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. :::note -The direct parents of the model that you’re unit testing (in this example `stg_customers` and `top_level_email_domains`) need to exist in the warehouse before you’re able to execute the unit test. +The direct parents of the model that you’re unit testing (in this example, `stg_customers` and `top_level_email_domains`) need to exist in the warehouse before you can execute the unit test. -Use the `--empty` flag to build an empty version of those models to save warehouse spend. +Use the `--empty` flag to build an empty version of the models to save warehouse spend. ```bash @@ -117,9 +117,8 @@ Alternatively, use `dbt build` to, in lineage order: - Materialize your model in the warehouse. - Run the data tests on your model. -::: -Now we’re ready to run this unit test! We have a couple of options for commands depending on how specific we want to be: +Now you’re ready to run this unit test. You have a couple of options for commands depending on how specific you want to be: - `dbt test —-select dim_customers` runs _all_ of the tests on `dim_customers`. - `dbt test —-select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. @@ -159,9 +158,9 @@ actual differs from expected: ``` -It looks like the clever regex statement wasn’t as clever as we thought as the model is incorrectly flagging `missingdot@gmailcom` as a valid email address. +The clever regex statement wasn’t as clever as initially thought, as the model incorrectly flagged `missingdot@gmailcom` as a valid email address. -Updating the regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those darn escape characters!) and running the unit test again solves the problem: +Updating the regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those pesky escape characters) and rerunning the unit test solves the problem: ```bash @@ -183,14 +182,14 @@ dbt test --select test_is_valid_email_address ``` -Your model is now ready for production! Adding this unit test helped us catch an issue with the SQL logic _before_ you materialized `dim_customers` in your warehouse and will better ensure the reliability of this model in the future. +Your model is now ready for production! Adding this unit test helped catch an issue with the SQL logic _before_ you materialized `dim_customers` in your warehouse and will better ensure the reliability of this model in the future. ### Unit testing versioned models -When a unit test is added to a model, with no supplied version, the unit test will run on all versions of the model. -Using the example on this page, if you have version 1, 2, and 3 of `my_model`, `my test_is_valid_email_address` unit test will run on all 3 versions. +When a unit test is added to a model, it will run on all versions of the model by default. +Using the example in this article, if you have versions 1, 2, and 3 of `my_model`, the `my test_is_valid_email_address` unit test will run on all 3 versions. -To to only unit test a specific version (or versions) of a model, you can include the desired version(s) in the model config: +To only unit test a specific version (or versions) of a model, include the desired version(s) in the model config: ```yml @@ -206,7 +205,7 @@ unit-tests: In this scenario, if you have version 1, 2, and 3 of `my_model`, `my test_is_valid_email_address` unit test will run on _only_ version 2. -To to unit test all versions except a specific version (or versions) of a model, you can exclude the relevant version(s) in the model config: +To unit test all versions except a specific version (or versions) of a model, you can exclude the relevant version(s) in the model config: ```yml @@ -219,9 +218,9 @@ unit-tests: given: # optional: list of inputs to provide as fixtures ``` -So if you have version 1, 2, and 3 of `my_model`, your `test_is_valid_email_address` unit test will run on _only_ version 2 and 3. +So, if you have versions 1, 2, and 3 of `my_model`, your `test_is_valid_email_address` unit test will run on _only_ versions 2 and 3. -If you want to unit test a model that references a pinned version of model, you should specify that in the ref of your input: +If you want to unit test a model that references the pinned version of the model, you should specify that in the `ref` of your input: ```yml @@ -232,9 +231,9 @@ unit-tests: ``` -### Best practices for “when to add a unit test to your model”: - -- when your SQL contains complex logic: +### When to add a unit test to your model +There are a number of scenarios where unit testing a mode is appropriate, including: +- When your SQL contains complex logic: - Regex - Date math - Window functions @@ -242,7 +241,7 @@ unit-tests: - Truncation - Recursion - Add a unit test for anything that feels like writing a function. For example, it involves your own logic processing the input. - - You wouldn't need to prioritize unit testing just calling `min()`, for example. That's already tested extensively by the warehouse and if something unexpected happens it's going to be a result of issues in the underlying data, so your fixture data in the unit test isn't going to help you. + - For example, you wouldn't need to prioritize unit testing just calling `min()`. That's already been tested extensively by the warehouse. If something unexpected happens, it's going to be a result of issues in the underlying data, so your fixture data in the unit test isn't going to help you. - Logic for which you had bugs reported before. - Edge cases not yet seen in your actual data that you want to handle. - Prior to refactoring the transformation logic (especially if the refactor is significant). From 353c4f34267d19da2c9038ecb267b20fb7027c6c Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 19:43:28 -0500 Subject: [PATCH 37/84] Update unit-tests.md Spacing --- website/docs/docs/build/unit-tests.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 107f9ddd436..f8f99b50791 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -237,7 +237,7 @@ There are a number of scenarios where unit testing a mode is appropriate, includ - Regex - Date math - Window functions - - `case when` statements when many `when`s + - `case when` statements when there are many `when`s - Truncation - Recursion - Add a unit test for anything that feels like writing a function. For example, it involves your own logic processing the input. @@ -246,3 +246,4 @@ There are a number of scenarios where unit testing a mode is appropriate, includ - Edge cases not yet seen in your actual data that you want to handle. - Prior to refactoring the transformation logic (especially if the refactor is significant). - Models with high “criticality” (public, contracted models or models directly upstream of an exposure). + From 5bfff10e7c3652bd92408163c8a28ad3563d6bf6 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:03:18 -0500 Subject: [PATCH 38/84] updating spacing --- website/docs/docs/build/unit-tests.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index f8f99b50791..ad778642451 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -232,6 +232,7 @@ unit-tests: ``` ### When to add a unit test to your model + There are a number of scenarios where unit testing a mode is appropriate, including: - When your SQL contains complex logic: - Regex From 37df470f7c01a3db586cbc021e6c5fdcdcc1e8eb Mon Sep 17 00:00:00 2001 From: "Leona B. Campbell" <3880403+runleonarun@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:05:02 -0800 Subject: [PATCH 39/84] Update website/docs/reference/resource-properties/unit-tests.md --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 265edbe61e9..c5c765c21eb 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -20,7 +20,7 @@ unit_tests: - name: # this is the unique name of the test model: versions: #optional - include: #optional + include: #optional exclude: #optional config: meta: {dictionary} From 39b83aaca973d9678570029d60f4168c24a7f81e Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:05:31 -0500 Subject: [PATCH 40/84] Update website/docs/reference/commands/test.md --- website/docs/reference/commands/test.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/commands/test.md b/website/docs/reference/commands/test.md index 0b60cc87941..1bcbd315eb2 100644 --- a/website/docs/reference/commands/test.md +++ b/website/docs/reference/commands/test.md @@ -35,7 +35,7 @@ For more information on writing tests, see the [Testing Documentation](/docs/bui -`dbt test` runs data tests and unit tests defined on models, sources, snapshots, and seeds. It expects that you have already created those resources through the appropriate commands. +`dbt test` runs data tests defined on models, sources, snapshots, and seeds and unit tests defined on SQL models. It expects that you have already created those resources through the appropriate commands. The tests to run can be selected using the `--select` flag discussed [here](/reference/node-selection/syntax). From 90526f6dcfe746d5e2f19929d2a7b79fed84be3a Mon Sep 17 00:00:00 2001 From: "Leona B. Campbell" <3880403+runleonarun@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:05:52 -0800 Subject: [PATCH 41/84] Update website/docs/reference/resource-properties/unit-tests.md --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index c5c765c21eb..d1be1d8baad 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -21,7 +21,7 @@ unit_tests: model: versions: #optional include: #optional - exclude: #optional + exclude: #optional config: meta: {dictionary} tags: | [] From ab28f995fc2e8976c985be2a97bd8bcf19e6c2cd Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:10:05 -0500 Subject: [PATCH 42/84] Apply suggestions from code review Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/reference/commands/test.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/reference/commands/test.md b/website/docs/reference/commands/test.md index 1bcbd315eb2..c62e0071484 100644 --- a/website/docs/reference/commands/test.md +++ b/website/docs/reference/commands/test.md @@ -55,16 +55,16 @@ dbt test --select "one_specific_model" # run tests for all models in package dbt test --select "some_package.*" -# run only tests defined singularly +# run only data tests defined singularly dbt test --select "test_type:singular" -# run only tests defined generically +# run only data tests defined generically dbt test --select "test_type:generic" -# run singular tests limited to one_specific_model +# run singular data tests limited to one_specific_model dbt test --select "one_specific_model,test_type:singular" -# run generic tests limited to one_specific_model +# run generic data tests limited to one_specific_model dbt test --select "one_specific_model,test_type:generic" ``` From f5753a70581ed31283339b970f715eb3b524410a Mon Sep 17 00:00:00 2001 From: "Leona B. Campbell" <3880403+runleonarun@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:14:42 -0800 Subject: [PATCH 43/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index ad778642451..1430b4fd8d7 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -246,5 +246,5 @@ There are a number of scenarios where unit testing a mode is appropriate, includ - Logic for which you had bugs reported before. - Edge cases not yet seen in your actual data that you want to handle. - Prior to refactoring the transformation logic (especially if the refactor is significant). -- Models with high “criticality” (public, contracted models or models directly upstream of an exposure). +- Models with high "criticality" (public, contracted models or models directly upstream of an exposure). From 3872aaab5c0699be9418135d52fc613a5617e95a Mon Sep 17 00:00:00 2001 From: "Leona B. Campbell" <3880403+runleonarun@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:28:34 -0800 Subject: [PATCH 44/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 1430b4fd8d7..c3e15bb98ed 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -226,7 +226,7 @@ If you want to unit test a model that references the pinned version of the model unit-tests: - name: test_is_valid_email_address # this is the unique name of the test - model: my_model # name of the model I'm unit testing + model: my_model # name of the model I am unit testing given: # optional: list of inputs to provide as fixtures ``` From 567ef1590faac92f15af7a3249de93a2eefdeac3 Mon Sep 17 00:00:00 2001 From: "Leona B. Campbell" <3880403+runleonarun@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:30:37 -0800 Subject: [PATCH 45/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index c3e15bb98ed..c6aa58e850c 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -104,7 +104,7 @@ Notice that you only have to define the mock data for the columns you care about The direct parents of the model that you’re unit testing (in this example, `stg_customers` and `top_level_email_domains`) need to exist in the warehouse before you can execute the unit test. Use the `--empty` flag to build an empty version of the models to save warehouse spend. - +::: ```bash dbt run —-select "stg_customers top_level_email_domains" --empty From 57cbfe11c720c4aafacfd521e366a810b232baa5 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:33:08 -0500 Subject: [PATCH 46/84] Update unit-tests.md --- website/docs/docs/build/unit-tests.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index c6aa58e850c..673e217e33a 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -104,7 +104,7 @@ Notice that you only have to define the mock data for the columns you care about The direct parents of the model that you’re unit testing (in this example, `stg_customers` and `top_level_email_domains`) need to exist in the warehouse before you can execute the unit test. Use the `--empty` flag to build an empty version of the models to save warehouse spend. -::: + ```bash dbt run —-select "stg_customers top_level_email_domains" --empty @@ -117,6 +117,7 @@ Alternatively, use `dbt build` to, in lineage order: - Materialize your model in the warehouse. - Run the data tests on your model. +::: Now you’re ready to run this unit test. You have a couple of options for commands depending on how specific you want to be: From 1a7d70d564355446b8e9ddc668345a28dea2333a Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:45:08 -0500 Subject: [PATCH 47/84] Apply suggestions from code review Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index d1be1d8baad..3cf0858e4b4 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -60,13 +60,13 @@ Unit tests are currently limited to testing SQL models and only models in your c - If your model has multiple versions, be default the unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, `include` or `exclude` the desired versions in your model versions config: ```yaml -# my test_is_valid_email_address unit test will run on all 3 versions +# my test_is_valid_email_address unit test will run on all versions of my_model unit-tests: - name: test_is_valid_email_address model: my_model ... -# my test_is_valid_email_address unit test will run on ONLY version 2 +# my test_is_valid_email_address unit test will run on ONLY version 2 of my_model unit-tests: - name: test_is_valid_email_address model: my_model @@ -75,7 +75,7 @@ unit-tests: - 2 ... -# my test_is_valid_email_address unit test will run on ONLY version 2 and 3 +# my test_is_valid_email_address unit test will run on all versions EXCEPT 1 of my_model unit-tests: - name: test_is_valid_email_address model: my_model From 0d6b78a5b3f587757dffb58fccd2b1782420c1e0 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:45:48 -0500 Subject: [PATCH 48/84] Update unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 673e217e33a..2ac12d4763d 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -65,6 +65,7 @@ check_valid_emails as ( select * from check_valid_emails ``` + This type of logic can be challenging to validate. You can add a unit test to this model to ensure your `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. @@ -94,6 +95,7 @@ unit_tests: - {customer_id: 4, is_valid_email_address: false} ``` + The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. From 5c50489b4391e66746fadda8cd47d5bc32175cf1 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:39:27 -0500 Subject: [PATCH 49/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 2ac12d4763d..31495c2b023 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -15,7 +15,7 @@ It is available now as an alpha feature for dbt Core v1.8 users. ::: -Historically, the test coverage capabilities of dbt were limited to “data” tests ‐ testing the quality of input data or the shape of the resulting datasets — that could only be executed *after* a model had been built. +Historically, the test coverage capabilities of dbt were limited to [“data” tests](/docs/build/data-tests) ‐ testing the quality of input data or the shape of the resulting datasets — that could only be executed _after_ a model had been built. Now, we are introducing a new type of test to dbt - unit tests. In software programming, unit tests validate small portions of your functional code, and they work much the same way here. Unit tests allow you to validate your SQL modeling logic on a small set of static inputs _before_ you materialize your full model in production. Unit tests enable test-driven development, benefiting developer efficiency and code reliability. From 92b55c0626b2f97aa115f0118a61f6c172dadedb Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:47:11 -0500 Subject: [PATCH 50/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 3cf0858e4b4..34b9b17f58b 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -133,7 +133,7 @@ unit_tests: ... ``` - ```yaml + ```csv # tests/fixtures/my_model_a_fixture.csv 1,gerda 2,michelle From 810180dd44315674ddf87e51b96a7045aaed4a56 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:50:11 -0500 Subject: [PATCH 51/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 31495c2b023..b981930bf1d 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -97,7 +97,7 @@ unit_tests: ``` -The above example defines the mock data using the inline `dict` format, but there are a handful of different options for how you format your mock data. +The above example defines the mock data using the inline `dict` format, but you can also use `csv` either inline or in a separate fixture file. Notice that you only have to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. From 225f48f03108027bbd875d4227fd8f573e011380 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:51:46 -0500 Subject: [PATCH 52/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 34b9b17f58b..852af27e219 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -145,7 +145,7 @@ unit_tests: - `input:` is optional for seeds: - If you don’t supply an input for a seed, we will use the seed *as* the input. - If you do supply an input for a seed, we will use that input instead. -- You can also have “empty” inputs, by setting rows to an empty list `rows: []`: +- You can also have “empty” inputs, by setting rows to an empty list `rows: []` Examples: ```yml From ea79e05b09ada8dffb613880bfa1c77d8fe514b2 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:52:55 -0500 Subject: [PATCH 53/84] Update unit-tests.md Fixing spacing --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 852af27e219..b404f7f1e01 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -96,7 +96,7 @@ unit_tests: given: - input: ref('my_model_a') format: dict - rows: + rows: - {id: 1, name: gerda} - {id: 2, b: michelle} From fc0ba3a22337fc84b0de764c98aeabdbdbd386e2 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:54:00 -0500 Subject: [PATCH 54/84] Update unit-tests.md Fixing spacing --- website/docs/reference/resource-properties/unit-tests.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index b404f7f1e01..00e74254eee 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -119,6 +119,7 @@ unit_tests: ... ``` + - The name of a csv file in the `tests/fixtures` directory in your project (or the directory configured for [test-paths](https://docs.getdbt.com/reference/project-configs/test-paths)) for `fixture`: From fb455284ab80f90d7fd12445d3666af1172553cf Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:55:07 -0500 Subject: [PATCH 55/84] Update unit-tests.md Spacing --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 00e74254eee..b24506e6ce6 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -112,7 +112,7 @@ unit_tests: given: - input: ref('my_model_a') format: csv - rows: | + rows: | id,name 1,gerda 2,michelle From 2edec426fc3683941362f59ed7af720a11cdbaef Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:13:27 -0500 Subject: [PATCH 56/84] Update website/sidebars.js --- website/sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/sidebars.js b/website/sidebars.js index a453afe62a5..9c67619bf90 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -280,7 +280,7 @@ const sidebarSettings = { { type: "category", label: "Tests", - link: { type: "doc", id: "docs/build/models" }, + link: { type: "doc", id: "docs/build/data-tests" }, items: [ "docs/build/data-tests", "docs/build/unit-tests", From 158ea89c6bd036f320ddf7df812fa446902c2604 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:38:16 -0500 Subject: [PATCH 57/84] Update unit-tests.md --- website/docs/reference/resource-properties/unit-tests.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index b24506e6ce6..aa65fc1f8ac 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -60,6 +60,7 @@ Unit tests are currently limited to testing SQL models and only models in your c - If your model has multiple versions, be default the unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, `include` or `exclude` the desired versions in your model versions config: ```yaml + # my test_is_valid_email_address unit test will run on all versions of my_model unit-tests: - name: test_is_valid_email_address From 8b4b31b498f0528d66816b8cd3946b84c1be3686 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:50:14 -0500 Subject: [PATCH 58/84] Update unit-tests.md Spacing fix --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index aa65fc1f8ac..3aa5295e8dd 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -59,7 +59,7 @@ unit_tests: Unit tests are currently limited to testing SQL models and only models in your current project. When writing your unit tests, keep the following in mind: - If your model has multiple versions, be default the unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, `include` or `exclude` the desired versions in your model versions config: - ```yaml +```yaml # my test_is_valid_email_address unit test will run on all versions of my_model unit-tests: From 27ecde39c6b841eb1e064cc94e3e58980a3d1517 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:21:01 -0500 Subject: [PATCH 59/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index b981930bf1d..01ec387476e 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -28,7 +28,7 @@ Now, we are introducing a new type of test to dbt - unit tests. In software prog Read the [reference doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. ::: -Let’s say you’re creating a new `dim_customers` model with a field `is_valid_email_address`, that calculates whether or not the customer’s email is valid: +This example creates a new `dim_customers` model with a field `is_valid_email_address` that calculates whether or not the customer’s email is valid: From fba19031f6e8aeb11313d517ac09a093aa7ada3c Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:21:19 -0500 Subject: [PATCH 60/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 01ec387476e..73e3fa43f76 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -97,7 +97,7 @@ unit_tests: ``` -The above example defines the mock data using the inline `dict` format, but you can also use `csv` either inline or in a separate fixture file. +The previous example defines the mock data using the inline `dict` format, but you can also use `csv` either inline or in a separate fixture file. Notice that you only have to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. From bdfc000111bfaa7bc59b9942f63e4bcb0061756b Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:21:31 -0500 Subject: [PATCH 61/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 73e3fa43f76..086fc9c1f77 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -99,7 +99,7 @@ unit_tests: The previous example defines the mock data using the inline `dict` format, but you can also use `csv` either inline or in a separate fixture file. -Notice that you only have to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. +You only have to define the mock data for the columns you care about. This enables you to write succinct and _specific_ unit tests. :::note From 58c41a69011081414945834f66ade0965fd0fa36 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:26:28 -0500 Subject: [PATCH 62/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 086fc9c1f77..349c4389ebc 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -244,7 +244,7 @@ There are a number of scenarios where unit testing a mode is appropriate, includ - `case when` statements when there are many `when`s - Truncation - Recursion -- Add a unit test for anything that feels like writing a function. For example, it involves your own logic processing the input. +- When you're writing custom logic to process input data, similar to creating a function. - For example, you wouldn't need to prioritize unit testing just calling `min()`. That's already been tested extensively by the warehouse. If something unexpected happens, it's going to be a result of issues in the underlying data, so your fixture data in the unit test isn't going to help you. - Logic for which you had bugs reported before. - Edge cases not yet seen in your actual data that you want to handle. From f67b7795c0e1811eec7ef4fca6d2eab05656b4bf Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:31:26 -0500 Subject: [PATCH 63/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 349c4389ebc..244304cd3ea 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -26,7 +26,6 @@ Now, we are introducing a new type of test to dbt - unit tests. In software prog - If your model has multiple versions, by default the unit test will run on *all* versions of your model. Read [unit testing versioned models for more information](#unit-testing-versioned-models). Read the [reference doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. -::: This example creates a new `dim_customers` model with a field `is_valid_email_address` that calculates whether or not the customer’s email is valid: From db435da4be41f5cd80c0b18fb54174d76e2f41c9 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:31:34 -0500 Subject: [PATCH 64/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 244304cd3ea..8caaed77bb2 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -23,7 +23,7 @@ Now, we are introducing a new type of test to dbt - unit tests. In software prog - We currently only support unit testing SQL models. - We currently only support adding unit tests to models in your _current_ project. -- If your model has multiple versions, by default the unit test will run on *all* versions of your model. Read [unit testing versioned models for more information](#unit-testing-versioned-models). +- If your model has multiple versions, by default the unit test will run on *all* versions of your model. Read [unit testing versioned models](#unit-testing-versioned-models) for more information. Read the [reference doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. From 97f7e7ab4895d63631c12f2aa5a1cb41f16fd873 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:31:46 -0500 Subject: [PATCH 65/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 8caaed77bb2..aab848163e4 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -19,7 +19,7 @@ Historically, the test coverage capabilities of dbt were limited to [“data” Now, we are introducing a new type of test to dbt - unit tests. In software programming, unit tests validate small portions of your functional code, and they work much the same way here. Unit tests allow you to validate your SQL modeling logic on a small set of static inputs _before_ you materialize your full model in production. Unit tests enable test-driven development, benefiting developer efficiency and code reliability. -:::note Before you begin +## Before you begin - We currently only support unit testing SQL models. - We currently only support adding unit tests to models in your _current_ project. From 62ce8c61721423aea650e7d2948404b735b6e9e0 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:31:51 -0500 Subject: [PATCH 66/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index aab848163e4..0a949429025 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -15,7 +15,7 @@ It is available now as an alpha feature for dbt Core v1.8 users. ::: -Historically, the test coverage capabilities of dbt were limited to [“data” tests](/docs/build/data-tests) ‐ testing the quality of input data or the shape of the resulting datasets — that could only be executed _after_ a model had been built. +Historically, dbt's test coverage was confined to [“data” tests](/docs/build/data-tests), assessing the quality of input data or resulting datasets' structure. However, these tests could only be executed _after_ a building a model. Now, we are introducing a new type of test to dbt - unit tests. In software programming, unit tests validate small portions of your functional code, and they work much the same way here. Unit tests allow you to validate your SQL modeling logic on a small set of static inputs _before_ you materialize your full model in production. Unit tests enable test-driven development, benefiting developer efficiency and code reliability. From 8bd64f7c2d8a0ce9c260a52206761d40e768a2d3 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:33:47 -0500 Subject: [PATCH 67/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 0a949429025..4cdd7fce48d 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -186,7 +186,7 @@ dbt test --select test_is_valid_email_address Your model is now ready for production! Adding this unit test helped catch an issue with the SQL logic _before_ you materialized `dim_customers` in your warehouse and will better ensure the reliability of this model in the future. -### Unit testing versioned models +## Unit testing versioned models When a unit test is added to a model, it will run on all versions of the model by default. Using the example in this article, if you have versions 1, 2, and 3 of `my_model`, the `my test_is_valid_email_address` unit test will run on all 3 versions. From 72b84f28ff1d98635fa7173c8b91449d62863e37 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:34:08 -0500 Subject: [PATCH 68/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 4cdd7fce48d..cc8bb29b2bc 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -235,7 +235,7 @@ unit-tests: ### When to add a unit test to your model -There are a number of scenarios where unit testing a mode is appropriate, including: +You should unit test a model: - When your SQL contains complex logic: - Regex - Date math From dbd0aa446465f21ea02acac91c19dbb5c0211871 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:34:14 -0500 Subject: [PATCH 69/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index cc8bb29b2bc..c902bcd4fac 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -244,7 +244,7 @@ You should unit test a model: - Truncation - Recursion - When you're writing custom logic to process input data, similar to creating a function. - - For example, you wouldn't need to prioritize unit testing just calling `min()`. That's already been tested extensively by the warehouse. If something unexpected happens, it's going to be a result of issues in the underlying data, so your fixture data in the unit test isn't going to help you. +- We don't recommend conducting unit testing for functions like `min()` since these functions are tested extensively by the warehouse. If an unexpected issue arises, it's more likely a result of issues in the underlying data rather than the function itself. Therefore, fixture data in the unit test won't provide valuable information. - Logic for which you had bugs reported before. - Edge cases not yet seen in your actual data that you want to handle. - Prior to refactoring the transformation logic (especially if the refactor is significant). From 12f92a87b519614417442ae61d92e7664b1935a7 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:34:59 -0500 Subject: [PATCH 70/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index c902bcd4fac..cba0e27ca6e 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -66,7 +66,7 @@ select * from check_valid_emails ``` -This type of logic can be challenging to validate. You can add a unit test to this model to ensure your `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. +The logic posed in this example can be challenging to validate. You can add a unit test to this model to ensure the `is_valid_email_address` logic captures all known edge cases: emails without `.`, emails without `@`, and emails from invalid domains. From dd87c90d0db7757d4ca74c974d51d3b9e2f1e7b9 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:35:08 -0500 Subject: [PATCH 71/84] Update website/docs/docs/build/unit-tests.md --- website/docs/docs/build/unit-tests.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index cba0e27ca6e..b4c296dc424 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -27,6 +27,8 @@ Now, we are introducing a new type of test to dbt - unit tests. In software prog Read the [reference doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. +## Unit testing a model + This example creates a new `dim_customers` model with a field `is_valid_email_address` that calculates whether or not the customer’s email is valid: From 694037a9d49c0ad3effdd46542aea3872cc89190 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:36:17 -0500 Subject: [PATCH 72/84] Update unit-tests.md moving section based on feedback --- website/docs/docs/build/unit-tests.md | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index b4c296dc424..7448df5d674 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -27,6 +27,23 @@ Now, we are introducing a new type of test to dbt - unit tests. In software prog Read the [reference doc](/reference/resource-properties/unit-tests) for more details about formatting your unit tests. +### When to add a unit test to your model + +You should unit test a model: +- When your SQL contains complex logic: + - Regex + - Date math + - Window functions + - `case when` statements when there are many `when`s + - Truncation + - Recursion +- When you're writing custom logic to process input data, similar to creating a function. +- We don't recommend conducting unit testing for functions like `min()` since these functions are tested extensively by the warehouse. If an unexpected issue arises, it's more likely a result of issues in the underlying data rather than the function itself. Therefore, fixture data in the unit test won't provide valuable information. +- Logic for which you had bugs reported before. +- Edge cases not yet seen in your actual data that you want to handle. +- Prior to refactoring the transformation logic (especially if the refactor is significant). +- Models with high "criticality" (public, contracted models or models directly upstream of an exposure). + ## Unit testing a model This example creates a new `dim_customers` model with a field `is_valid_email_address` that calculates whether or not the customer’s email is valid: @@ -235,20 +252,5 @@ unit-tests: ``` -### When to add a unit test to your model -You should unit test a model: -- When your SQL contains complex logic: - - Regex - - Date math - - Window functions - - `case when` statements when there are many `when`s - - Truncation - - Recursion -- When you're writing custom logic to process input data, similar to creating a function. -- We don't recommend conducting unit testing for functions like `min()` since these functions are tested extensively by the warehouse. If an unexpected issue arises, it's more likely a result of issues in the underlying data rather than the function itself. Therefore, fixture data in the unit test won't provide valuable information. -- Logic for which you had bugs reported before. -- Edge cases not yet seen in your actual data that you want to handle. -- Prior to refactoring the transformation logic (especially if the refactor is significant). -- Models with high "criticality" (public, contracted models or models directly upstream of an exposure). From 528e6533a90c218b82fff9a181fc54e85f5b65c4 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:36:52 -0500 Subject: [PATCH 73/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 7448df5d674..de7c560a924 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -1,7 +1,7 @@ --- title: "Unit tests" sidebar_label: "Unit tests" -description: "Read this tutorial to learn how to use unit tests on your SQL models." +description: "Learn how to use unit tests on your SQL models." search_weight: "heavy" id: "unit-tests" keywords: From 5870f968b86d19f7f0de1137f004e3b776a81c31 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:13:53 -0500 Subject: [PATCH 74/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 3aa5295e8dd..758567ce5db 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -86,7 +86,9 @@ unit-tests: ... ``` - + +### Format + -When using `format: dict` you must supply an in-line dictionary for `rows:` (this is the default, if you don’t specify a `format`) ```yml From c10ea4910e9085c3439571287ba330bf655b603b Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:14:18 -0500 Subject: [PATCH 75/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 758567ce5db..43bfd753f19 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -5,7 +5,6 @@ resource_types: [models] datatype: test --- -## Definition Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and code reliability. From 95cd74b8ca366c761bbdbcf5caac9522c1cc89df Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:14:57 -0500 Subject: [PATCH 76/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 43bfd753f19..f838f29e3eb 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -6,7 +6,7 @@ datatype: test --- -Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and code reliability. +Unit tests validate your SQL modeling logic on a small set of static inputs before you materialize your full model in production. They support a test-driven development approach, improving both the efficiency of developers and reliability of code. To run only your unit tests, use the command: `dbt test --select test_type:unit` From 7b3f23b2fb945d0760fbc229ae9f33ea8c25cf27 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:15:18 -0500 Subject: [PATCH 77/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index f838f29e3eb..7b0a030689e 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -56,7 +56,7 @@ unit_tests: ### About writing unit tests Unit tests are currently limited to testing SQL models and only models in your current project. When writing your unit tests, keep the following in mind: -- If your model has multiple versions, be default the unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, `include` or `exclude` the desired versions in your model versions config: +- If your model has multiple versions, the default unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, use `include` or `exclude` for the desired versions in your model versions config: ```yaml From ef9ceeeafb8e2fe27494cd547414cad130325c24 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:15:40 -0500 Subject: [PATCH 78/84] Update website/docs/reference/resource-properties/unit-tests.md Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 7b0a030689e..36f282b76b1 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -53,7 +53,7 @@ unit_tests: -### About writing unit tests +## About writing unit tests Unit tests are currently limited to testing SQL models and only models in your current project. When writing your unit tests, keep the following in mind: - If your model has multiple versions, the default unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, use `include` or `exclude` for the desired versions in your model versions config: From d6b4fa14f7aac41415fa2844e10a2767475df53b Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:16:35 -0500 Subject: [PATCH 79/84] Apply suggestions from code review Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- website/docs/reference/resource-properties/unit-tests.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 36f282b76b1..575f6f35345 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -88,7 +88,7 @@ unit-tests: ### Format --When using `format: dict` you must supply an in-line dictionary for `rows:` (this is the default, if you don’t specify a `format`) +When using `format: dict` you must supply an in-line dictionary for `rows:` (this is the default, if you don’t specify a `format`) ```yml @@ -104,7 +104,7 @@ unit_tests: ``` -- When `format: csv`, can either supply: +When `format: csv`, can either supply: - An inline csv string for `rows:` ```yaml @@ -142,6 +142,8 @@ unit_tests: 2,michelle ``` +### Input + - `input:` string that represents a `ref` or `source` call: - `ref('my_model')` or `ref('my_model', v='2')` or `ref('dougs_project', 'users')` - `source('source_schema', 'source_name')` @@ -150,7 +152,7 @@ unit_tests: - If you do supply an input for a seed, we will use that input instead. - You can also have “empty” inputs, by setting rows to an empty list `rows: []` -Examples: +### Examples ```yml unit_tests: From 8503acd764b68376fa06559fe8f97b4938706e69 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:26:37 -0500 Subject: [PATCH 80/84] Apply suggestions from code review Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index de7c560a924..3acaa14a018 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -141,8 +141,8 @@ Alternatively, use `dbt build` to, in lineage order: Now you’re ready to run this unit test. You have a couple of options for commands depending on how specific you want to be: -- `dbt test —-select dim_customers` runs _all_ of the tests on `dim_customers`. -- `dbt test —-select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. +- `dbt test --select dim_customers` runs _all_ of the tests on `dim_customers`. +- `dbt test --select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. - `dbt test —-select test_is_valid_email_address` runs the test named `test_is_valid_email_address`. ```bash From a1b361449913408f4ffc4c724ca26b6d7d545ad3 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:27:54 -0500 Subject: [PATCH 81/84] Update website/docs/docs/build/unit-tests.md Co-authored-by: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> --- website/docs/docs/build/unit-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 3acaa14a018..50adebcc885 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -179,7 +179,7 @@ actual differs from expected: ``` -The clever regex statement wasn’t as clever as initially thought, as the model incorrectly flagged `missingdot@gmailcom` as a valid email address. +The clever regex statement wasn’t as clever as initially thought, as the model incorrectly flagged `cool@example.com` (customer 1's email) as an invalid email address. Updating the regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those pesky escape characters) and rerunning the unit test solves the problem: From ba74fe5632dfdf6350bfe0cc92d2bce7b443fc92 Mon Sep 17 00:00:00 2001 From: Grace Goheen <53586774+graciegoheen@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:08:47 -0700 Subject: [PATCH 82/84] Apply suggestions from code review --- website/docs/docs/build/unit-tests.md | 40 ++++++------ website/docs/reference/commands/test.md | 8 +-- .../resource-properties/unit-tests.md | 61 ++++++++++--------- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 50adebcc885..86efe423b25 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -127,7 +127,7 @@ Use the `--empty` flag to build an empty version of the models to save warehouse ```bash -dbt run —-select "stg_customers top_level_email_domains" --empty +dbt run --select "stg_customers top_level_email_domains" --empty ``` @@ -143,7 +143,7 @@ Now you’re ready to run this unit test. You have a couple of options for comma - `dbt test --select dim_customers` runs _all_ of the tests on `dim_customers`. - `dbt test --select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. -- `dbt test —-select test_is_valid_email_address` runs the test named `test_is_valid_email_address`. +- `dbt test --select test_is_valid_email_address` runs the test named `test_is_valid_email_address`. ```bash @@ -192,8 +192,8 @@ dbt test --select test_is_valid_email_address 16:09:12 16:09:13 Concurrency: 5 threads (target='postgres') 16:09:13 -16:09:13 1 of 1 START unit_test dim_wizards::test_is_valid_email_address ................... [RUN] -16:09:13 1 of 1 PASS dim_wizards::test_is_valid_email_address .............................. [PASS in 0.26s] +16:09:13 1 of 1 START unit_test dim_customers::test_is_valid_email_address ................... [RUN] +16:09:13 1 of 1 PASS dim_customers::test_is_valid_email_address .............................. [PASS in 0.26s] 16:09:13 16:09:13 Finished running 1 unit_test in 0 hours 0 minutes and 0.75 seconds (0.75s). 16:09:13 @@ -208,47 +208,49 @@ Your model is now ready for production! Adding this unit test helped catch an is ## Unit testing versioned models When a unit test is added to a model, it will run on all versions of the model by default. -Using the example in this article, if you have versions 1, 2, and 3 of `my_model`, the `my test_is_valid_email_address` unit test will run on all 3 versions. +Using the example in this article, if you have versions 1, 2, and 3 of `dim_customers`, the `test_is_valid_email_address` unit test will run on all 3 versions. To only unit test a specific version (or versions) of a model, include the desired version(s) in the model config: ```yml -unit-tests: - - name: test_is_valid_email_address # this is the unique name of the test - model: my_model # name of the model I'm unit testing +unit_tests:: + - name: test_is_valid_email_address + model: dim_customers versions: include: - 2 - given: # optional: list of inputs to provide as fixtures + ... ``` -In this scenario, if you have version 1, 2, and 3 of `my_model`, `my test_is_valid_email_address` unit test will run on _only_ version 2. +In this scenario, if you have version 1, 2, and 3 of `dim_customers `, my `test_is_valid_email_address` unit test will run on _only_ version 2. To unit test all versions except a specific version (or versions) of a model, you can exclude the relevant version(s) in the model config: ```yml -unit-tests: - - name: test_is_valid_email_address # this is the unique name of the test - model: my_model # name of the model I'm unit testing +unit_tests: + - name: test_is_valid_email_address + model: dim_customers versions: exclude: - 1 - given: # optional: list of inputs to provide as fixtures + ... ``` -So, if you have versions 1, 2, and 3 of `my_model`, your `test_is_valid_email_address` unit test will run on _only_ versions 2 and 3. +So, if you have versions 1, 2, and 3 of `dim_customers`, your `test_is_valid_email_address` unit test will run on _only_ versions 2 and 3. If you want to unit test a model that references the pinned version of the model, you should specify that in the `ref` of your input: ```yml -unit-tests: - - name: test_is_valid_email_address # this is the unique name of the test - model: my_model # name of the model I am unit testing - given: # optional: list of inputs to provide as fixtures +unit_tests: + - name: test_is_valid_email_address + model: dim_customers + given: + - input: ref('stg_customers', v=1) + ... ``` diff --git a/website/docs/reference/commands/test.md b/website/docs/reference/commands/test.md index c62e0071484..2203cc09faa 100644 --- a/website/docs/reference/commands/test.md +++ b/website/docs/reference/commands/test.md @@ -61,11 +61,11 @@ dbt test --select "test_type:singular" # run only data tests defined generically dbt test --select "test_type:generic" -# run singular data tests limited to one_specific_model -dbt test --select "one_specific_model,test_type:singular" +# run data tests limited to one_specific_model +dbt test --select "one_specific_model,test_type:data" -# run generic data tests limited to one_specific_model -dbt test --select "one_specific_model,test_type:generic" +# run unit tests limited to one_specific_model +dbt test --select "one_specific_model,test_type:unit" ``` For more information on writing tests, read the [data testing](/docs/build/tests) and [unit testing](/docs/build/unit-tests) documentation. diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 575f6f35345..64744b98918 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -55,34 +55,36 @@ unit_tests: ## About writing unit tests -Unit tests are currently limited to testing SQL models and only models in your current project. When writing your unit tests, keep the following in mind: -- If your model has multiple versions, the default unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, use `include` or `exclude` for the desired versions in your model versions config: +Unit tests are currently limited to testing SQL models and only models in your current project. + +### Versions +If your model has multiple versions, the default unit test will run on *all* versions of your model. To specify version(s) of your model to unit test, use `include` or `exclude` for the desired versions in your model versions config: ```yaml # my test_is_valid_email_address unit test will run on all versions of my_model -unit-tests: +unit_tests: - name: test_is_valid_email_address model: my_model -... + ... # my test_is_valid_email_address unit test will run on ONLY version 2 of my_model -unit-tests: +unit_tests: - name: test_is_valid_email_address model: my_model versions: include: - 2 -... + ... # my test_is_valid_email_address unit test will run on all versions EXCEPT 1 of my_model -unit-tests: +unit_tests: - name: test_is_valid_email_address model: my_model versions: exclude: - 1 -... + ... ``` @@ -101,7 +103,7 @@ unit_tests: rows: - {id: 1, name: gerda} - {id: 2, b: michelle} - + ... ``` When `format: csv`, can either supply: @@ -118,7 +120,6 @@ When `format: csv`, can either supply: id,name 1,gerda 2,michelle - ... ``` @@ -152,29 +153,29 @@ When `format: csv`, can either supply: - If you do supply an input for a seed, we will use that input instead. - You can also have “empty” inputs, by setting rows to an empty list `rows: []` -### Examples +## Examples ```yml unit_tests: - name: test_is_valid_email_address # this is the unique name of the test - model: my_model # name of the model I'm unit testing + model: dim_customers # name of the model I'm unit testing given: # the mock data for your inputs - - input: ref('users') + - input: ref('stg_customers') rows: - - {user_id: 1, email: cool@example.com, email_top_level_domain: example.com} - - {user_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} - - {user_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} - - {user_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} - - input: ref('top_level_domains') + - {customer_id: 1, email: cool@example.com, email_top_level_domain: example.com} + - {customer_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} + - {customer_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} + - {customer_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} + - input: ref('top_level_email_domains') rows: - {tld: example.com} - {tld: gmail.com} expect: # the expected output given the inputs above rows: - - {user_id: 1, is_valid_email_address: true} - - {user_id: 2, is_valid_email_address: false} - - {user_id: 3, is_valid_email_address: false} - - {user_id: 4, is_valid_email_address: false} + - {customer_id: 1, is_valid_email_address: true} + - {customer_id: 2, is_valid_email_address: false} + - {customer_id: 3, is_valid_email_address: false} + - {customer_id: 4, is_valid_email_address: false} ``` @@ -182,15 +183,15 @@ unit_tests: unit_tests: - name: test_is_valid_email_address # this is the unique name of the test - model: my_model # name of the model I'm unit testing + model: dim_customers # name of the model I'm unit testing given: # the mock data for your inputs - - input: ref('users') + - input: ref('stg_customers') rows: - - {user_id: 1, email: cool@example.com, email_top_level_domain: example.com} - - {user_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} - - {user_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} - - {user_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} - - input: ref('top_level_domains') + - {customer_id: 1, email: cool@example.com, email_top_level_domain: example.com} + - {customer_id: 2, email: cool@unknown.com, email_top_level_domain: unknown.com} + - {customer_id: 3, email: badgmail.com, email_top_level_domain: gmail.com} + - {customer_id: 4, email: missingdot@gmailcom, email_top_level_domain: gmail.com} + - input: ref('top_level_email_domains') format: csv rows: | tld @@ -198,6 +199,6 @@ unit_tests: gmail.com expect: # the expected output given the inputs above format: csv - fixture: my_model_fixture + fixture: valid_email_address_fixture_output ``` From 9c626b9447deee9be3465a9cfb7632debe7df066 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:56:39 -0500 Subject: [PATCH 83/84] Fixing format and spacing --- website/docs/docs/build/unit-tests.md | 4 ++-- website/docs/reference/resource-properties/unit-tests.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/docs/build/unit-tests.md b/website/docs/docs/build/unit-tests.md index 86efe423b25..71c464cbd40 100644 --- a/website/docs/docs/build/unit-tests.md +++ b/website/docs/docs/build/unit-tests.md @@ -145,7 +145,7 @@ Now you’re ready to run this unit test. You have a couple of options for comma - `dbt test --select "dim_customers,test_type:unit"` runs all of the _unit_ tests on `dim_customers`. - `dbt test --select test_is_valid_email_address` runs the test named `test_is_valid_email_address`. -```bash +```shell dbt test --select test_is_valid_email_address 16:03:49 Running with dbt=1.8.0-a1 @@ -183,7 +183,7 @@ The clever regex statement wasn’t as clever as initially thought, as the model Updating the regex logic to `'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'` (those pesky escape characters) and rerunning the unit test solves the problem: -```bash +```shell dbt test --select test_is_valid_email_address 16:09:11 Running with dbt=1.8.0-a1 diff --git a/website/docs/reference/resource-properties/unit-tests.md b/website/docs/reference/resource-properties/unit-tests.md index 64744b98918..40c3414e373 100644 --- a/website/docs/reference/resource-properties/unit-tests.md +++ b/website/docs/reference/resource-properties/unit-tests.md @@ -124,7 +124,7 @@ When `format: csv`, can either supply: ``` - - The name of a csv file in the `tests/fixtures` directory in your project (or the directory configured for [test-paths](https://docs.getdbt.com/reference/project-configs/test-paths)) for `fixture`: + - The name of a csv file in the `tests/fixtures` directory in your project (or the directory configured for [test-paths](https://docs.getdbt.com/reference/project-configs/test-paths)) for `fixture`: ```yaml unit_tests: From 6b8e0348393f1e8f29616cbe68c0bbc0fe79de07 Mon Sep 17 00:00:00 2001 From: Matt Shaver <60105315+matthewshaver@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:59:42 -0500 Subject: [PATCH 84/84] fixing links --- website/docs/reference/commands/test.md | 4 ++-- website/docs/reference/resource-configs/store_failures_as.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/reference/commands/test.md b/website/docs/reference/commands/test.md index 2203cc09faa..cad61a05ac5 100644 --- a/website/docs/reference/commands/test.md +++ b/website/docs/reference/commands/test.md @@ -29,7 +29,7 @@ dbt test --select "one_specific_model,test_type:singular" dbt test --select "one_specific_model,test_type:generic" ``` -For more information on writing tests, see the [Testing Documentation](/docs/build/tests). +For more information on writing tests, see the [Testing Documentation](/docs/build/data-tests).
@@ -68,7 +68,7 @@ dbt test --select "one_specific_model,test_type:data" dbt test --select "one_specific_model,test_type:unit" ``` -For more information on writing tests, read the [data testing](/docs/build/tests) and [unit testing](/docs/build/unit-tests) documentation. +For more information on writing tests, read the [data testing](/docs/build/data-tests) and [unit testing](/docs/build/unit-tests) documentation.
diff --git a/website/docs/reference/resource-configs/store_failures_as.md b/website/docs/reference/resource-configs/store_failures_as.md index dd61030afb8..005193a5381 100644 --- a/website/docs/reference/resource-configs/store_failures_as.md +++ b/website/docs/reference/resource-configs/store_failures_as.md @@ -17,7 +17,7 @@ You can configure it in all the same places as `store_failures`, including singu #### Singular test -[Singular test](https://docs.getdbt.com/docs/build/tests#singular-data-tests) in `tests/singular/check_something.sql` file +[Singular test](https://docs.getdbt.com/docs/build/data-tests#singular-data-tests) in `tests/singular/check_something.sql` file ```sql {{ config(store_failures_as="table") }} @@ -29,7 +29,7 @@ where 1=0 #### Generic test -[Generic tests](https://docs.getdbt.com/docs/build/tests#generic-data-tests) in `models/_models.yml` file +[Generic tests](https://docs.getdbt.com/docs/build/data-tests#generic-data-tests) in `models/_models.yml` file ```yaml models: