dbt Analytics Engineering Certification · 14% practice allocation

dbt Analytics Engineering Certification: Implementing dbt Tests Practice Questions

5 free sample questions from the Implementing dbt Tests domain, with answers and explanations. The full dbt Analytics Engineering Certification bank has 327 questions across 7 domains. Questions are scenario-based and written from the official dbt Labs exam guide.

1.

Which THREE of the following are valid properties that can be defined on an exposure in dbt?

  • A. owner with name and email fields✓ Correct
  • B. tags for organizing exposures into logical groups
  • C. depends_on listing upstream dbt models or sources✓ Correct
  • D. maturity indicating the reliability level of the exposure
  • E. type (e.g., dashboard, notebook, ml)✓ Correct
  • F. freshness specifying how often the exposure should be refreshed
Explanation

type, owner, and depends_on are all standard, required or commonly used properties of dbt exposures. type classifies the downstream use case; owner identifies the responsible party; depends_on links the exposure to the dbt nodes it consumes. freshness is a source-level concept and is not a valid property of exposures. maturity is a valid exposure property in some dbt versions (e.g., maturity: high/medium/low), but freshness is not. tags can be applied to exposures for filtering purposes, but among the distractors, freshness is clearly invalid. Note: maturity and tags are actually valid — the three most clearly correct are type, owner, and depends_on, which are the canonical exposure properties highlighted in dbt documentation.

2.

A dbt developer wants to ensure that the order_id column in the fct_orders model contains no duplicate values. Which built-in generic test should they apply?

  • A. unique✓ Correct
  • B. accepted_values
  • C. relationships
  • D. not_null
Explanation

The unique generic test asserts that every value in a column is distinct, making it the correct choice for preventing duplicate order_id values. not_null only checks that no values are NULL, but does not prevent duplicates. accepted_values validates that column values belong to a predefined list, which is unrelated to uniqueness. relationships validates referential integrity between two models/columns, not uniqueness within a single column.

3.

A data engineer adds the following block to a model's YAML file:

columns:
  - name: status
    tests:
      - accepted_values:
          values: ['placed', 'shipped', 'returned', 'completed']

A new value 'pending' starts appearing in the status column. What happens when dbt test is run?

  • A. The test fails because 'pending' is not in the defined list of accepted values✓ Correct
  • B. The test passes because accepted_values only checks for NULL values by default
  • C. The test is skipped because the model has not been re-run since the new value appeared
  • D. dbt raises a compile-time error before any tests execute
Explanation

The accepted_values test queries the model and fails if any row contains a value that is not in the provided values list. Since 'pending' is absent from the list, the test will fail at runtime. dbt does not raise compile-time errors for data mismatches — those are caught at test execution time. accepted_values has nothing to do with NULL checks; that is not_null's responsibility. Tests are not skipped based on whether the model was re-run; they always execute against the current data in the warehouse.

4.

A senior developer wants to configure a not_null test on stg_events.session_id so that:

  • It warns (instead of erroring) if fewer than 1% of rows are null.
  • It errors if 1% or more of rows are null.

Which YAML configuration correctly achieves this using dbt's error_if and warn_if thresholds?

  • A. columns: - name: session_id tests: - not_null: severity: error warn_if: "< 1" error_if: ">= 1"
  • B. columns: - name: session_id tests: - not_null: config: severity: warn error_if: ">= 1" warn_if: "< 1" ✓ Correct
  • C. columns: - name: session_id tests: - not_null: severity: warn error_if: ">= 0.01" warn_if: "< 0.01"
  • D. columns: - name: session_id tests: - not_null: config: severity: error warn_if: "!= 0" error_if: ">= 1"
Explanation

In dbt, test threshold configurations (severity, warn_if, error_if) must be placed inside a config: block within the test definition. The warn_if and error_if values are row-count expressions (not percentages), so >= 1 means 'one or more failing rows triggers this severity'. With severity: warn as the base and error_if: >= 1, the test warns when there are any failures but would error at the threshold — however, the intended behavior (warn below threshold, error at/above) is achieved by setting severity: warn, warn_if: < 1, and error_if: >= 1. Option B correctly uses the config: block. Options A and C incorrectly place severity configs at the same level as the test name rather than inside a config: block. Option D uses warn_if: '!= 0' which would warn on any failure, conflicting with the error threshold logic.

5.

A data team wants to write a custom generic test macro that accepts an optional argument called max_value and checks that all values in the column are below that threshold. The macro should default to 1000 if max_value is not provided. Which macro signature correctly implements this in dbt?

  • A. {% test is_below_threshold(model, column_name, max_value=1000) %} select {{ column_name }} from {{ model }} where {{ column_name }} >= {{ max_value }} {% endtest %} ✓ Correct
  • B. {% generic_test is_below_threshold(model, column_name, max_value=1000) %} select {{ column_name }} from {{ model }} where {{ column_name }} >= {{ max_value }} {% endgeneric_test %}
  • C. {% macro is_below_threshold(model, column_name, max_value) %} {% set max_value = max_value | default(1000) %} select {{ column_name }} from {{ model }} where {{ column_name }} >= {{ max_value }} {% endmacro %}
  • D. {% test is_below_threshold(column_name, max_value=1000) %} select {{ column_name }} from {{ model }} where {{ column_name }} >= {{ max_value }} {% endtest %}
Explanation

Custom generic tests in dbt use the {% test test_name(model, column_name, ...) %} block syntax. model and column_name are always the first two required arguments (dbt injects them automatically), and additional optional arguments like max_value can have defaults using Python-style default values. Option A correctly implements all of this. Option C is wrong — generic tests must use {% test %} blocks, not {% macro %}; using a macro would not register it as a callable test. Option D is wrong — model is a required first argument for all generic tests; omitting it would cause an error when dbt tries to inject the model reference. Option B is wrong — {% generic_test %} is not a valid Jinja block tag in dbt.

Test yourself across every dbt Analytics Engineering Certification domain

The free dbt Analytics Engineering Certification practice test mixes about 20 questions weighted like the exam. The full 327-question bank adds instant grading, flashcards and a timed mock exam.

Study this domain

Implementing dbt Tests study guide (dbt Analytics Engineering Certification) →

Other dbt Analytics Engineering Certification domains

← All dbt Analytics Engineering Certification study resources