-
Notifications
You must be signed in to change notification settings - Fork 254
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
doc/md: add testing functions guide (#2955)
- Loading branch information
1 parent
dd5cd17
commit a50d344
Showing
3 changed files
with
216 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
--- | ||
id: testing-functions | ||
title: Testing Database Functions | ||
slug: /guides/testing/functions | ||
--- | ||
|
||
Testing your database schema and migrations is crucial to ensure code behaves as expected, catch bugs early, | ||
and prevent regressions. Databases enforce logic, constraints, and complex relationships, | ||
so testing ensures these elements work correctly and remain intact after changes. | ||
|
||
In this guide we will learn how to use Atlas's [`schema test`](/testing/schema) command to test database functions. | ||
|
||
## Database Functions | ||
|
||
Functions are predefined operations stored in a database that can be invoked to perform calculations, manipulate data, | ||
or execute tasks. | ||
|
||
:::info [Atlas Pro Feature](/features#pro-plan) | ||
Functions are currently available only to [Atlas Pro users](/features#pro-plan). To use this feature, run: | ||
``` | ||
atlas login | ||
``` | ||
::: | ||
|
||
## Project Setup | ||
|
||
### Schema File | ||
For this example, let's assume we have the following schema, including a function: | ||
|
||
```hcl title="schema.hcl" | ||
schema "public" { | ||
} | ||
table "users" { | ||
schema = schema.public | ||
column "id" { | ||
type = int | ||
} | ||
column "name" { | ||
type = text | ||
} | ||
primary_key { | ||
columns = [ | ||
column.id | ||
] | ||
} | ||
} | ||
table "transactions" { | ||
schema = schema.public | ||
column "id" { | ||
type = int | ||
} | ||
column "user_id" { | ||
type = int | ||
} | ||
column "amount" { | ||
type = decimal | ||
} | ||
// highlight-start | ||
column "is_income" { | ||
type = boolean | ||
as { | ||
expr = "positive(amount)" | ||
} | ||
// highlight-end | ||
} | ||
primary_key { | ||
columns = [column.id] | ||
} | ||
foreign_key "user_fk" { | ||
columns = [column.user_id] | ||
ref_columns = [table.users.column.id] | ||
on_delete = CASCADE | ||
on_update = NO_ACTION | ||
} | ||
} | ||
// highlight-start | ||
function "positive" { | ||
schema = schema.public | ||
lang = SQL | ||
arg "v" { | ||
type = decimal | ||
} | ||
return = boolean | ||
as = "SELECT v > 0" | ||
} | ||
// highlight-end | ||
``` | ||
|
||
In the schema above we have a simple `users` table and a `transactions` table. In `transactions`, the `is_income` column | ||
checks if the `amount` is positive by calling the `positive` function. | ||
|
||
Note that `is_income` is a [generated column](/atlas-schema/hcl#generated-columns), meaning its value is | ||
computed using other columns or deterministic expressions (in this case, via a function). | ||
|
||
### Project File | ||
|
||
Before we begin testing, create a [project file](/atlas-schema/projects#project-files) named | ||
`atlas.hcl`. | ||
|
||
In this file we will create an environment, specify the source of our schema, | ||
and a URL for our [dev database](/concepts/dev-database). | ||
|
||
We will also create a file named `schema.test.hcl` to write our tests, and | ||
add it to the `atlas.hcl` file in the test block. | ||
|
||
```hcl title="atlas.hcl" | ||
env "dev" { | ||
src = "file://schema.hcl" | ||
dev = "docker://postgres/15/dev?search_path=public" | ||
# Test configuration for local development. | ||
test { | ||
schema { | ||
src = ["schema.test.hcl"] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Writing Tests | ||
|
||
### Simple Test | ||
|
||
Let's start off with a simple test that will check that the function correctly recognizes positive numbers. | ||
|
||
```hcl title="schema.test.hcl" | ||
test "schema" "positive_func" { | ||
parallel = true | ||
assert { | ||
sql = "SELECT positive(1)" | ||
} | ||
log { | ||
message = "First assertion passed" | ||
} | ||
assert { | ||
sql = <<SQL | ||
SELECT NOT positive(0); | ||
SELECT NOT positive(-1); | ||
SQL | ||
} | ||
log { | ||
message = "Second assertion passed" | ||
} | ||
} | ||
``` | ||
|
||
The test first checks if positive(1) returns TRUE, and then verifies in the second assertion that | ||
positive(0) and positive(-1) return false. | ||
|
||
Run the test by running: | ||
|
||
```bash | ||
atlas schema test --env dev | ||
``` | ||
|
||
The output should look similar to: | ||
```testoutput title="Test Output" | ||
-- PASS: positive_func (2ms) | ||
schema.test.hcl:74: First assertion passed | ||
schema.test.hcl:83: Second assertion passed | ||
PASS | ||
``` | ||
|
||
### Table Driven Test | ||
|
||
Another alternative is to write a [table driven test](/testing/schema#table-driven-tests). This | ||
test uses the `for_each` meta-argument, which accepts a map or a set of values and is used to generate | ||
a test case for each item in the set or map. | ||
|
||
Following similar logic to the test above, we will check the function for the integers: 0, 1, and -1. | ||
|
||
```hcl title="schema.test.hcl" | ||
test "schema" "positive_func" { | ||
parallel = true | ||
for_each = [ | ||
{input: 1, expected: "t"}, | ||
{input: 0, expected: "f"}, | ||
{input: -1, expected: "f"}, | ||
] | ||
exec { | ||
sql = "SELECT positive(${each.value.input})" | ||
output = each.value.expected | ||
} | ||
} | ||
``` | ||
|
||
Run the test by running: | ||
|
||
```bash | ||
atlas schema test --env dev | ||
``` | ||
|
||
The output should look similar to: | ||
```testoutput title="Test Output" | ||
-- PASS: positive_func/2 (5ms) | ||
-- PASS: positive_func/3 (10ms) | ||
-- PASS: positive_func/1 (10ms) | ||
PASS | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters