Skip to main content

Test Capabilities

1. Local Execution with DuckDB​

All tests run locally using DuckDB as an in-memory SQL engine. No cloud credentials or service accounts are required. SQL written for BigQuery, Snowflake, Databricks, or Redshift is automatically transpiled to DuckDB dialect before execution.

2. Test Types​

Starlake supports two test types:

TypeWhat it validates
Load testsIngestion of files into tables (parsing, validation, rejection)
Transform testsSQL or Python transformations (query logic, output schema)

If neither --load nor --transform is specified, both types are executed.

3. Load Test Structure​

Each load test is a directory under metadata/tests/load/{domain}/{table}/{test-name}/ containing:

FileRequiredPurpose
{domain}.{table}.csv or .jsonNoInitial data to preload into the table
_incoming.{filename}YesInput file to ingest (named per the table's file pattern)
_expected.csv or .jsonYesExpected table contents after loading
_expected_{name}.csv / .json / .sqlNoAdditional named expectations
{table}.sqlNoPre-test SQL statements
env.sl.ymlNoTest-level environment variables

4. Transform Test Structure​

Each transform test is a directory under metadata/tests/transform/{domain}/{task}/{test-name}/ containing:

FileRequiredPurpose
{domain}.{table}.csv or .jsonYesSource data for each table referenced by the SQL
_expected.csv or .jsonYesExpected transformation output
_expected.sqlNoSQL query whose result is compared to actual output
_expected_{name}.csv / .json / .sqlNoAdditional named expectations
{task}.sqlNoPre-test SQL statements
env.sl.ymlNoTest-level environment variables

5. Multiple Expectations per Test​

A single test can define multiple expected outputs, each validated independently:

test1/
├── _expected.csv # default expectation
├── _expected_by_region.csv # named expectation "by_region"
└── _expected_totals.sql # SQL-based expectation "totals"

Each generates separate pass/fail results and comparison artifacts.

6. SQL-Based Expectations​

Instead of a static CSV, an _expected.sql file defines a query executed against the DuckDB database. The query result is compared to the actual output, enabling parameterized and computed assertions.

7. Test Data Formats​

  • CSV: standard comma-separated values with header row.
  • JSON: JSONL format (one JSON object per line, no commas between objects).
order_id,customer_id,amount,seller_id,ts
12345,A009701,123.65,AQZERD,2024-02-05T21:19:15.454Z
56432,A009701,23.8,AQZERD,2024-02-05T21:19:15.454Z
{ "id": "1", "city": "Paris", "country": "France" }
{ "id": "2", "city": "Berlin", "country": "Germany" }

8. Hierarchical Environment Configuration​

Environment variables can be defined at multiple levels via env.sl.yml files. Each level overrides the one above:

  1. metadata/tests/env.sl.yml — root
  2. metadata/tests/load/{domain}/env.sl.yml — domain
  3. metadata/tests/load/{domain}/{table}/env.sl.yml — table
  4. metadata/tests/load/{domain}/{table}/{test-name}/env.sl.yml — test

Same hierarchy applies under transform/.

9. Schema Validation​

Tests compare the actual table schema against the expected data schema. Missing or unexpected columns are reported separately from data mismatches.

10. Data Comparison​

Row-by-row comparison is order-independent (set logic). Mismatches produce two artifact files:

  • missing_{name}.csv — rows in expected but not in actual.
  • not_expected_{name}.csv — rows in actual but not in expected.

11. Rejected Records​

For load tests, records that fail validation are routed to audit.rejected in the test DuckDB database — the same behavior as production ingestion.

12. Test Coverage Metrics​

The test framework tracks which domains and tables have tests, and reports:

  • Tested domains and tables.
  • Untested domains and tables.

13. CLI Commands​

# Run all tests
starlake test

# Run only load or transform tests
starlake test --load
starlake test --transform

# Filter by domain, table, or test name
starlake test --domain sales
starlake test --domain sales --table orders
starlake test --domain sales --table orders --test test1

# Generate HTML report website
starlake test --site

# Custom output directory
starlake test --outputDir /path/to/reports

14. Report Generation​

JUnit XML​

Generated by default at test-reports/junit.xml. Compatible with CI/CD systems (Jenkins, GitLab CI, GitHub Actions).

HTML Report​

Generated with --site. Produces a browsable website with:

  • Root summary (pass/fail counts, success rates).
  • Domain-level and table-level summaries.
  • Individual test pages showing schema diffs, data mismatches, executed SQL, and execution time.

DuckDB Artifacts​

Each test produces a {test-name}.db file containing:

  • sl_expected — expected data table.
  • {domain}.{table} — actual data table.
  • audit.rejected — rejected records (load tests).

15. Post-Load Expectations​

In addition to test-level assertions, data quality expectations defined in the table YAML (expectations section) are also evaluated during test execution. See the full Expectations reference for all 53 built-in macros.


Summary​

CapabilityCategory
Local DuckDB execution (no cloud credentials)Runtime
Automatic SQL transpilation (BigQuery, Snowflake, Databricks, Redshift)Runtime
Load tests (file ingestion validation)Test Types
Transform tests (SQL/Python logic validation)Test Types
Multiple named expectations per testAssertions
SQL-based expectations (_expected.sql)Assertions
Schema validation (column names and types)Assertions
Data comparison (order-independent, set logic)Assertions
Rejected record tracking (audit.rejected)Assertions
Post-load expectation macrosAssertions
Hierarchical environment configuration (env.sl.yml)Configuration
Pre-test SQL statementsConfiguration
Test coverage metrics (tested vs untested)Reporting
JUnit XML reports (CI/CD integration)Reporting
HTML report website (--site)Reporting
DuckDB artifact databasesReporting