Skip to content

Commit

Permalink
Add contract testing examples
Browse files Browse the repository at this point in the history
* Add source contract tests

* Fix source contract test

Improved setup instructions

* Upgrade to dbt 1.5

Upgrade dbt dependencies

* Add model contract for mart model

* Add support for Github Codespaces

* Fix Github Codespaces name

* Add initial CD pipeline definition

* Add debug connection step to the pipeline

* Inject postgres configuration via configuration variables and secrets

* Change CI config to run unit and component tests

* Run tests against test postgres database

* Add pipeline job to deploy to test environment

* Fix deploy to test job to deploy with any branch

* Add missing install dependencies step in deployment job

* Extract deployment job into a reusable workflow

* Associate specific Github environment to the deployment

* Split deployment workflow into multiple jobs
  • Loading branch information
portovep authored Oct 23, 2023
1 parent 529a662 commit ddb0182
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 63 deletions.
17 changes: 17 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "Python 3",
"dockerComposeFile": "../docker-compose.yml",
"service": "devcontainer",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"postCreateCommand": "pip3 install --user -r requirements.txt",
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh"
},
"extensions": [
"GitHub.codespaces"
]
}
}
}
35 changes: 35 additions & 0 deletions .github/workflows/cd-pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CD Pipeline

on:
push:

jobs:
test:
name: Test
runs-on: ubuntu-latest
container:
image: ghcr.io/dbt-labs/dbt-postgres:1.6.3
env:
POSTGRES_HOST: ${{ vars.POSTGRES_HOST }}
POSTGRES_USER: ${{ vars.POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_DB: ${{ vars.POSTGRES_DB }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install dependencies
run: |
dbt deps
- name: Run unit tests
run: |
dbt test --target test --select tag:unit-test
- name: Run component tests
run: |
dbt test --target test --select tag:unit-test
deploy-test:
name: Deploy to test
needs: [test]
uses: ./.github/workflows/deploy.yml
with:
environment-name: test
secrets: inherit
66 changes: 66 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Deploy

on:
workflow_call:
inputs:
environment-name:
required: true
type: string

env:
POSTGRES_HOST: ${{ vars.POSTGRES_HOST }}
POSTGRES_USER: ${{ vars.POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_DB: ${{ vars.POSTGRES_DB }}

jobs:
seed-source-tables:
name: Seed source tables
runs-on: ubuntu-latest
environment: ${{ inputs.environment-name }}
container:
image: ghcr.io/dbt-labs/dbt-postgres:1.6.3
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install dependencies
run: |
dbt deps
- name: Run seeds
run: |
dbt seed --target ${{ inputs.environment-name }}
source-contract-tests:
name: Run source contract tests
needs: [seed-source-tables]
runs-on: ubuntu-latest
environment: ${{ inputs.environment-name }}
container:
image: ghcr.io/dbt-labs/dbt-postgres:1.6.3
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install dependencies
run: |
dbt deps
- name: Run seeds
run: |
dbt seed --target ${{ inputs.environment-name }}\
- name: Run source contract tests
run: |
dbt test --target ${{ inputs.environment-name }} --select tag:contract-test-source
deploy:
name: Deploy
needs: [source-contract-tests]
runs-on: ubuntu-latest
environment: ${{ inputs.environment-name }}
container:
image: ghcr.io/dbt-labs/dbt-postgres:1.6.3
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install dependencies
run: |
dbt deps
- name: Run data transformations
run: |
dbt run --target ${{ inputs.environment-name }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ target/
dbt_packages/
logs/
dbt
profiles.yml
.env
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ Check that everything works
dbt debug
```

Seed the database

```
dbt seed
```

## Running the tests

All tests
Expand All @@ -88,6 +94,12 @@ Component tests
dbt test --select tag:component
```

Contract tests

```
dbt test --select tag:contract-test-source
```

## Running data quality tests

```
Expand Down
5 changes: 2 additions & 3 deletions dbt_project.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Name your project! Project names should contain only lowercase characters
# and underscores. A good package name should reflect your organization's
# name or the intended use of these models
name: "dbt_testing_example"
version: "1.0.0"
config-version: 2

# This setting configures which "profile" dbt uses for this project.
profile: "dbt_testing_example"

require-dbt-version: ">=1.5.0"

# These configurations specify where dbt should look for different types of files.
# The `model-paths` config, for example, states that models in this project can be
# found in the "models/" directory. You probably won't need to change these!
Expand Down
14 changes: 9 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
version: '3.1'
version: '3.8'

services:
devcontainer:
image: mcr.microsoft.com/devcontainers/python:0-3.10-bullseye
volumes:
- .:/workspaces:cached
network_mode: service:db
command: sleep infinity

db:
image: postgres
restart: always
ports:
- 5432:5432
environment:
POSTGRES_PASSWORD: example

adminer:
image: adminer
restart: always
ports:
- 8080:8080
network_mode: service:db
18 changes: 17 additions & 1 deletion models/marts/_body_mass_indexes__models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,30 @@ version: 2

models:
- name: body_mass_indexes
config:
materialized: table
contract:
enforced: true
columns:
- name: user_id
tags: ["data-quality"]
data_type: int
constraints:
- type: not_null
- type: check
expression: "user_id > 0"
tests:
- not_null
- relationships:
to: source('gym_app', 'raw_height')
field: user_id
- relationships:
to: source('gym_app', 'raw_weight')
field: user_id
- name: created_date
data_type: date
- name: weight
data_type: float
- name: height
data_type: float
- name: bmi
data_type: decimal
28 changes: 28 additions & 0 deletions models/staging/gym_app/_gym_app__raw_height_schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: 2

sources:
- name: gym_app
schema: dbt_testing_example
tables:
- name: raw_height
tags: ["data-quality", "contract-test-source"]
columns:
- name: height_unit
tests:
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: text
- accepted_values:
values: ["cm", "inches"]
- name: user_id
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: integer
- name: height
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: double precision
- dbt_utils.accepted_range:
min_value: 0
inclusive: false
28 changes: 28 additions & 0 deletions models/staging/gym_app/_gym_app__raw_weight_schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: 2

sources:
- name: gym_app
schema: dbt_testing_example
tables:
- name: raw_weight
tags: ["data-quality", "contract-test-source"]
columns:
- name: measurement_unit
tests:
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: text
- accepted_values:
values: ["kg", "pounds"]
- name: user_id
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: integer
- name: weight
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: double precision
- dbt_utils.accepted_range:
min_value: 0
inclusive: false
39 changes: 0 additions & 39 deletions models/staging/gym_app/_gym_app__sources.yml

This file was deleted.

7 changes: 5 additions & 2 deletions packages.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
packages:
- package: dbt-labs/dbt_utils
version: 1.0.0
version: 1.1.1

- package: calogica/dbt_expectations
version: 0.8.5

- git: "https://github.com/EqualExperts/dbt-unit-testing"
revision: v0.2.6
revision: v0.2.7
12 changes: 0 additions & 12 deletions profiles.example.yml

This file was deleted.

21 changes: 21 additions & 0 deletions profiles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
dbt_testing_example:
target: dev
outputs:
dev:
type: postgres
host: localhost
user: postgres
password: "{{ env_var('POSTGRES_PASSWORD') }}"
port: 5432
dbname: postgres
schema: dbt_testing_example
threads: 4
test:
type: postgres
host: "{{ env_var('POSTGRES_HOST') }}"
user: "{{ env_var('POSTGRES_USER') }}"
password: "{{ env_var('POSTGRES_PASSWORD') }}"
port: 5432
dbname: "{{ env_var('POSTGRES_DB') }}"
schema: dbt_testing_example
threads: 4
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dbt-postgres

0 comments on commit ddb0182

Please sign in to comment.