Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
87ca828
Add databricks pipelines test command
tharunbhuk-db Oct 19, 2026
ad9c4be
Test every rejected pytest option and the spaced --pytest-arg form
tharunbhuk-db Oct 27, 2026
a16bd55
Resolve pipelines test selections like the test IDs the service reports
tharunbhuk-db Oct 30, 2026
31b5ec3
Map local pipelines test paths like TranslatePaths and mark the comma…
tharunbhuk-db Oct 30, 2026
f7898c2
Link the changelog entry to its PR
tharunbhuk-db Oct 30, 2026
683cede
Reject a pipelines test -k or -m value that starts with -
tharunbhuk-db Oct 31, 2026
368ddfe
Recommend pipelines deploy only after pipelines test finds the pipeline
tharunbhuk-db Oct 31, 2026
fd40c0c
Resolve pipelines test selections as local paths or against root_path
tharunbhuk-db Oct 31, 2026
b020fc5
Cover pipelines test selections with workspace.sync_mode immutable
tharunbhuk-db Oct 31, 2026
8a916d9
Require pipelines test -k and -m values in the next --pytest-arg, as …
tharunbhuk-db Oct 31, 2026
9a96d02
Wait for and print the results of databricks pipelines test
tharunbhuk-db Oct 31, 2026
87c8ffa
Reject a pipelines test --resume update that the service reports is n…
tharunbhuk-db Oct 31, 2026
bf661a8
Say why the pipelines test event reader cannot use the SDK iterator yet
tharunbhuk-db Oct 31, 2026
b241413
Reject a pipelines test --resume value that is not an update ID
tharunbhuk-db Oct 31, 2026
f301e8e
Show pipelines test case IDs in the shortest form that selects them a…
tharunbhuk-db Oct 31, 2026
fb461c2
Explain a pipelines test run whose tests failed by its summary alone,…
tharunbhuk-db Oct 31, 2026
510740f
Test that pipelines test --resume reads results when the service does…
tharunbhuk-db Oct 31, 2026
3ecf053
Reject test options in the fake pipelines service as the service does
tharunbhuk-db Oct 31, 2026
1f8d972
Read the errored count of the pipelines test summary, as the service …
tharunbhuk-db Oct 31, 2026
8679115
Reject an empty pipelines test --resume instead of starting a new run
tharunbhuk-db Oct 31, 2026
695c4b0
Say that pipelines test succeeds when at least one test was collected
tharunbhuk-db Oct 31, 2026
6cba663
Drop the unread level and message from pipelines test events
tharunbhuk-db Oct 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nextchanges/cli/pipelines-test-results.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* `databricks pipelines test` waits for the test results, prints them, and fails when a test fails or the results are incomplete. ([#7272](https://github.com/databricks/cli/pull/7272))
1 change: 1 addition & 0 deletions .nextchanges/cli/pipelines-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Add the `databricks pipelines test` command, which runs a pipeline's tests in a test-only update. ([#7271](https://github.com/databricks/cli/pull/7271))
1 change: 1 addition & 0 deletions acceptance/pipelines/databricks-cli-help/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Main Commands
run Run a pipeline
show Preview a table's columns and sample rows
stop Stop a pipeline
test *Preview* Run the tests of a pipeline

Management Commands
apply-environment *Public Preview* Apply the latest environment to the pipeline.
Expand Down
1 change: 1 addition & 0 deletions acceptance/pipelines/test/arguments/out.test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Cloud = false
97 changes: 97 additions & 0 deletions acceptance/pipelines/test/arguments/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@

>>> [CLI] pipelines test --help
Run the tests of a pipeline in a test-only update.

PIPELINE_KEY is the unique name of the pipeline, as defined in its YAML file.
It is required when test selections are given. If there is only one pipeline
in the project and no arguments are given, it is selected automatically.
Outside a project, identify the pipeline with --pipeline-id; all positional
arguments are then test selections.

TEST_SELECTION is a test directory, file, or pytest test ID, for example
tests/test_orders.py::test_backfill. In a project, a relative path is a local
path, relative to the working directory, and is converted to its deployed
workspace path. With --pipeline-id, a relative path is relative to the
pipeline's root_path. Paths that start with / are workspace paths. Without a
selection, all of the pipeline's tests run.

Each --pytest-arg passes one argument to pytest, in the order given. Only -k
and -m are supported, each followed by its value in the next --pytest-arg, for
example:

databricks pipelines test my_pipeline --pytest-arg=-k --pytest-arg='orders and not slow'

The command waits for the results and succeeds only if at least one test was
collected and none failed or errored. --no-wait returns after the update starts.
--timeout and Ctrl+C stop waiting but not the update; pass its ID to --resume
to read the results later. To stop the update, run 'pipelines stop'.

Usage:
databricks pipelines test [PIPELINE_KEY] [TEST_SELECTION...] [flags] [--pytest-arg=ARG ...]

Pipeline Test Flags:
--no-wait Return after the test update starts, without waiting for results.
--pipeline-id string ID of the pipeline to test, instead of a PIPELINE_KEY.
--pytest-arg stringArray Argument to pass to pytest (repeatable). Only -k and -m are supported.
--resume string Read the results of an existing test update instead of starting one.
--timeout duration Stop waiting for results after this duration, for example 30m. The update keeps running.

Flags:
-h, --help help for test

Global Flags:
--debug enable debug logging
-o, --output type output type: text or json (default text)
-p, --profile string ~/.databrickscfg profile
-t, --target string bundle target to use (if applicable)
--var strings set values for variables defined in project config. Example: --var="foo=bar"

=== pytest arguments must be passed with --pytest-arg
>>> musterr [CLI] pipelines test --pipeline-id 1234 -k orders
Error: -k is a pytest argument: pass pytest arguments with --pytest-arg, for example --pytest-arg=-k --pytest-arg='orders and not slow'

>>> musterr [CLI] pipelines test --pipeline-id 1234 -msmoke
Error: -m is a pytest argument: pass pytest arguments with --pytest-arg, for example --pytest-arg=-k --pytest-arg='orders and not slow'

>>> musterr [CLI] pipelines test --pipeline-id 1234 -- -k orders
Error: the -- separator is not supported: pass pytest arguments with --pytest-arg, for example --pytest-arg=-k --pytest-arg='orders and not slow'

=== Only -k and -m are supported
>>> musterr [CLI] pipelines test --pipeline-id 1234 --pytest-arg=-x
Error: unsupported pytest argument "-x": only -k and -m are supported

>>> musterr [CLI] pipelines test --pipeline-id 1234 --pytest-arg=-k
Error: pytest argument -k requires a value: pass it in the next --pytest-arg

>>> musterr [CLI] pipelines test --pipeline-id 1234 --pytest-arg=tests/test_orders.py
Error: unsupported pytest argument "tests/test_orders.py": pass test paths and test IDs as TEST_SELECTION arguments

=== -k and -m take their value in the next --pytest-arg
>>> musterr [CLI] pipelines test --pipeline-id 1234 --pytest-arg=-korders
Error: pytest argument "-korders" must be split: pass --pytest-arg=-k --pytest-arg=orders

>>> musterr [CLI] pipelines test --pipeline-id 1234 --pytest-arg=-k --pytest-arg=-m
Error: pytest argument -k requires a value, not "-m": pass it in the next --pytest-arg

=== Incompatible run-control flags
>>> musterr [CLI] pipelines test --pipeline-id 1234 tests --resume 5678
Error: --resume cannot be used with test selections

>>> musterr [CLI] pipelines test --pipeline-id 1234 --resume 5678 --pytest-arg=-m --pytest-arg=smoke
Error: --resume cannot be used with --pytest-arg

>>> musterr [CLI] pipelines test --pipeline-id 1234 --resume 5678 --no-wait
Error: --resume cannot be used with --no-wait

>>> musterr [CLI] pipelines test --pipeline-id 1234 --no-wait --timeout 10m
Error: --timeout cannot be used with --no-wait

>>> musterr [CLI] pipelines test --pipeline-id 1234 --resume 5678' OR '1'='1
Error: --resume "5678' OR '1'='1" is not an update ID; pass the update ID that pipelines test printed

>>> musterr [CLI] pipelines test --pipeline-id 1234 --resume
Error: --resume "" is not an update ID; pass the update ID that pipelines test printed

=== JSON output is not supported
>>> musterr [CLI] pipelines test --pipeline-id 1234 -o json
Error: --output json is not supported by pipelines test
26 changes: 26 additions & 0 deletions acceptance/pipelines/test/arguments/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
trace $CLI pipelines test --help

title "pytest arguments must be passed with --pytest-arg"
trace musterr $CLI pipelines test --pipeline-id 1234 -k orders
trace musterr $CLI pipelines test --pipeline-id 1234 -msmoke
trace musterr $CLI pipelines test --pipeline-id 1234 -- -k orders

title "Only -k and -m are supported"
trace musterr $CLI pipelines test --pipeline-id 1234 --pytest-arg=-x
trace musterr $CLI pipelines test --pipeline-id 1234 --pytest-arg=-k
trace musterr $CLI pipelines test --pipeline-id 1234 --pytest-arg=tests/test_orders.py

title "-k and -m take their value in the next --pytest-arg"
trace musterr $CLI pipelines test --pipeline-id 1234 --pytest-arg=-korders
trace musterr $CLI pipelines test --pipeline-id 1234 --pytest-arg=-k --pytest-arg=-m

title "Incompatible run-control flags"
trace musterr $CLI pipelines test --pipeline-id 1234 tests --resume 5678
trace musterr $CLI pipelines test --pipeline-id 1234 --resume 5678 --pytest-arg=-m --pytest-arg=smoke
trace musterr $CLI pipelines test --pipeline-id 1234 --resume 5678 --no-wait
trace musterr $CLI pipelines test --pipeline-id 1234 --no-wait --timeout 10m
trace musterr $CLI pipelines test --pipeline-id 1234 --resume "5678' OR '1'='1"
trace musterr $CLI pipelines test --pipeline-id 1234 --resume ""

title "JSON output is not supported"
trace musterr $CLI pipelines test --pipeline-id 1234 -o json
13 changes: 13 additions & 0 deletions acceptance/pipelines/test/immutable/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
bundle:
name: test-pipeline-test-immutable

workspace:
sync_mode: immutable

resources:
pipelines:
my_pipeline:
name: test-pipeline-test-immutable
libraries:
- file:
path: pipeline_file.py
1 change: 1 addition & 0 deletions acceptance/pipelines/test/immutable/out.test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Cloud = false
53 changes: 53 additions & 0 deletions acceptance/pipelines/test/immutable/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

>>> [CLI] pipelines deploy
Created internal_immutable_snapshots.immutable
Created pipelines.my_pipeline
Files: 0 uploaded, 0 deleted
Resources: 2 created, 0 changed, 0 deleted, 0 unchanged
View your pipeline my_pipeline here: [DATABRICKS_URL]/pipelines/[UUID]?w=[WORKSPACE_ID]

=== Local test paths are not supported with workspace.sync_mode immutable
>>> musterr [CLI] pipelines test my_pipeline tests/test_orders.py::test_backfill
Recommendation: This command runs the last deployed version of the code

If you've made local changes, run 'databricks pipelines deploy' first to ensure they are included.

Error: cannot resolve test selection "tests/test_orders.py::test_backfill": local test paths are not supported with workspace.sync_mode immutable; pass an absolute workspace path

=== Absolute workspace paths and running all tests still work
>>> [CLI] pipelines test my_pipeline /Workspace/Users/someone@example.com/tests/test_orders.py::test_backfill --no-wait
Recommendation: This command runs the last deployed version of the code

If you've made local changes, run 'databricks pipelines deploy' first to ensure they are included.

Pipeline: my_pipeline ([UUID])
Update: [UUID]

>>> [CLI] pipelines test my_pipeline --no-wait
Recommendation: This command runs the last deployed version of the code

If you've made local changes, run 'databricks pipelines deploy' first to ensure they are included.

Pipeline: my_pipeline ([UUID])
Update: [UUID]

>>> print_requests.py //updates
{
"method": "POST",
"path": "/api/2.0/pipelines/[UUID]/updates",
"body": {
"test_only": true,
"test_options": {
"test_selection": [
"/Workspace/Users/someone@example.com/tests/test_orders.py::test_backfill"
]
}
}
}
{
"method": "POST",
"path": "/api/2.0/pipelines/[UUID]/updates",
"body": {
"test_only": true
}
}
6 changes: 6 additions & 0 deletions acceptance/pipelines/test/immutable/pipeline_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from pyspark import pipelines as dp


@dp.table
def orders():
return spark.range(10)
12 changes: 12 additions & 0 deletions acceptance/pipelines/test/immutable/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
trace $CLI pipelines deploy
rm "$OUT_REQUESTS"

title "Local test paths are not supported with workspace.sync_mode immutable"
trace musterr $CLI pipelines test my_pipeline tests/test_orders.py::test_backfill

title "Absolute workspace paths and running all tests still work"
trace $CLI pipelines test my_pipeline /Workspace/Users/someone@example.com/tests/test_orders.py::test_backfill --no-wait
# Like the service, the test server rejects a new update while one is active.
$CLI pipelines stop my_pipeline &>> LOG.stop
trace $CLI pipelines test my_pipeline --no-wait
trace print_requests.py //updates
2 changes: 2 additions & 0 deletions acceptance/pipelines/test/immutable/tests/test_orders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def test_backfill():
assert True
11 changes: 11 additions & 0 deletions acceptance/pipelines/test/many-cases/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
bundle:
name: test-pipeline-test-many-cases

resources:
pipelines:
my_pipeline:
name: test-pipeline-test-many-cases
root_path: .
libraries:
- file:
path: pipeline_file.py
1 change: 1 addition & 0 deletions acceptance/pipelines/test/many-cases/out.test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Cloud = false
13 changes: 13 additions & 0 deletions acceptance/pipelines/test/many-cases/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

>>> [CLI] pipelines deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-pipeline-test-many-cases/default/files...
Created pipelines.my_pipeline
Files: 3 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
View your pipeline my_pipeline here: [DATABRICKS_URL]/pipelines/[UUID]?w=[WORKSPACE_ID]

=== Every case is counted once across pages, polls, and the final read
>>> tail -n 1 LOG.many
200 tests: 200 passed, 0 failed, 0 skipped, 0 errors
Event pages read: 8
Pages read with page_token: 4
6 changes: 6 additions & 0 deletions acceptance/pipelines/test/many-cases/pipeline_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from pyspark import pipelines as dp


@dp.table
def orders():
return spark.range(10)
9 changes: 9 additions & 0 deletions acceptance/pipelines/test/many-cases/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
trace $CLI pipelines deploy
rm "$OUT_REQUESTS"

title "Every case is counted once across pages, polls, and the final read"
$CLI pipelines test my_pipeline &> LOG.many
trace tail -n 1 LOG.many
print_requests.py --get //events --oneline > LOG.events
echo "Event pages read: $(wc -l < LOG.events | tr -d ' ')"
echo "Pages read with page_token: $(grep -c page_token LOG.events)"
Loading
Loading