Clean up Dataverse integration test data safely
Documentation-based guide draft · Reviewed against sources on 2026-09-27 · Not executed in an IFS environment. IFS references use 26R1 unless stated otherwise. Confirm available APIs, components, and permissions in your installed release.
This walkthrough removes a small, explicitly marked batch of integration test rows from a custom Dataverse table. It first lists the candidate IDs for review, then deletes exactly those rows. It does not delete IFS business records.
Before you start
Section titled “Before you start”Use a nonproduction Power Platform environment, a custom test table, and a connection allowed to read and delete its rows. Check its relationships and cascade-delete behavior before enabling deletion. Export any test evidence you still need.
The example uses Integration Test Runs with logical names demo_integrationtestrun, primary key demo_integrationtestrunid, Boolean demo_istest, and text demo_batchid. These are example columns you create or replace with your table’s actual logical names. Add three rows: two marked test with batch LAB-042, and one non-test control row.
1. Create a manual preview flow
Section titled “1. Create a manual preview flow”- In Power Automate, select the intended environment and create an Instant cloud flow using Manually trigger a flow.
- Add a text input named Batch ID. For this first exercise, use the fixed value
LAB-042in the query so unvalidated input cannot broaden it. - Add Microsoft Dataverse → List rows and rename it
List_candidates. - Select the test table and expand its advanced parameters.
- In Select columns, enter
demo_integrationtestrunid,demo_batchid,demo_istest. - In Filter rows, enter the following without a
$filter=prefix:
demo_istest eq true and demo_batchid eq 'LAB-042'Leave pagination off for this three-row exercise. Set Row count to 20, a deliberate upper bound for this small test.
2. Inspect the deletion list before adding deletion
Section titled “2. Inspect the deletion list before adding deletion”Add Compose after List rows and use this expression:
length(body('List_candidates')?['value'])Save and run the flow. Open its run history, expand List_candidates, and inspect Outputs. The two test IDs should appear; the non-test control must not. Save those IDs as your expected deletion set. If the count or keys are wrong, correct the query while the flow still contains no delete action.
For a large cleanup, use an approved bulk-delete job or explicit paging; this bounded preview is not an exhaustive inventory. A row limit or pagination threshold can truncate a larger result.
3. Add a deliberate execution gate
Section titled “3. Add a deliberate execution gate”Add a Condition after Compose: the count must equal 2 for this controlled exercise. In its false branch add Terminate with status Cancelled. Change the expected count only after reviewing a new preview.
Before using a dynamic Batch ID, validate that it is nonempty and belongs to a restricted format such as letters, digits, and hyphens. Do not concatenate arbitrary text containing quotes into an OData filter.
4. Delete by primary key
Section titled “4. Delete by primary key”In the true branch:
- Add Apply to each over the
valuearray fromList_candidates. - Keep the loop sequential for the first run.
- Add Microsoft Dataverse → Delete a row for the same table.
- Set Row ID to the current item’s
demo_integrationtestrunid, not its display name or batch value. - Save and run once. Inspect each delete action’s outcome.
A partial failure is possible: the first deletion can succeed while the second fails. Record successful and failed IDs separately; do not assume the loop is an all-or-nothing transaction.
5. Verify the result and handle errors
Section titled “5. Verify the result and handle errors”Run the preview query again. It should return zero rows. Query the non-test control by its ID and confirm it remains. Rerunning the original gated flow should now cancel because the preview count is zero.
| Failure | Correction |
|---|---|
| Invalid property in filter | Use the column’s logical name from table metadata |
| Access denied | Review the connection user’s delete privilege and record access |
| Related-record restriction | Inspect the relationship; resolve it deliberately instead of enabling broad cascades |
| Throttling | Reduce concurrency and use the connector’s bounded retry behavior |
| Unexpected extra rows | Stop deletion and tighten batch/test filters |
Turn off or remove the cleanup flow after the exercise. Delete the remaining control row manually only if it was created for this lab. Never schedule a broad recurring cleanup until its scope and retention rules have been reviewed.
Sources and scope
Section titled “Sources and scope”Older IFS Applications examples are historical context, not evidence of Cloud compatibility. No third-party code, screenshots, or downloadable workflows are reproduced.