Migration playbook

How to migrate test cases into a QA tool without a CSV import

Most QA tools define migration as: export a CSV, upload it, map your columns to their mandatory fields, queue the job if you have more than 500 rows. Your cases land as static records in a database you query through their dashboard. Assrt does it the other way. You rewrite each existing case as a few plain-English sentences, run them in a real browser, and the output is standard Playwright code in your own repo.

Direct answer · verified 2026-06-19

To move existing test cases into Assrt you do not upload a file and map fields. You rewrite each case as a #Case N: title block of 3 to 5 plain-English steps (or point assrt_plan at your live app to regenerate them), put the suite in a tests.txt, and run assrt run --plan-file tests.txt. You get a real-browser pass/fail run plus Playwright files you keep. The format and behavior are in the open-source assrt-mcp repo.

M
Matthew Diakonov
8 min read

Two definitions of “migrate a test case”

When testomat.io, QA Touch, TestRail, or qTest talk about migrating test cases, they mean moving records between test management systems. You generate a CSV, XLS, or XML export, upload it, and map your fields to theirs. The destination tools require certain columns: in QA Touch, Module name and Test case title are mandatory during mapping, and imports over 500 rows run through a background queue. The cases arrive as rows. A human still reads each one and clicks through the app to execute it, exactly as before. The migration changed where the document lives, not whether a machine can run it.

Assrt treats a migrated test case as something that should execute. The target is not a row in a database; it is a runnable scenario plus the Playwright code that scenario compiles to. That single difference changes every step of the move, so the rest of this guide walks one real case across and shows what you actually do.

Step 1 — Reshape one case, no column mapping

Take a single case out of your current tool. Here is a typical TestRail-style export on the left and the same case as an Assrt #Case block on the right. Notice what disappears: the ID, the Section column, the Priority and Type metadata, the split Steps/Expected tables. None of it is required to run the test. The data column (the coupon code) does not vanish, it becomes a {{COUPON}} variable.

One checkout case, before and after

# TestRail export (CSV row, abridged)
ID:        C2041
Section:   Checkout
Title:     Apply a valid coupon at checkout
Priority:  High
Type:      Functional
Preconditions: User has one item in cart
Steps:
  1. Open the cart
  2. Click "Have a code?"
  3. Enter coupon SAVE10
  4. Click Apply
Expected:
  1. Coupon panel expands
  2. Order total drops by 10%
  3. "SAVE10 applied" badge is shown
69% fewer lines

The #Case N: name format and the rule that each case stay self-contained in 3 to 5 steps are specified in assrt-mcp/src/mcp/server.ts; the parser that turns the heading into a named case lives in src/core/agent.ts.

Step 2 — The case lands in a file you own

This is the part the closed tools cannot offer. Whatever you migrate from, the destination is plain text on your machine. When a scenario loads, Assrt writes the plan to /tmp/assrt/scenario.md and watches it for edits (see assrt-mcp/src/core/scenario-files.ts), and a whole suite is just a tests.txt in your repo. The same case can come from a spreadsheet, Zephyr, a manual doc, or hand-written Selenium, and they all converge on the same owned format on the way to real Playwright output.

Everything converges on text you keep

TestRail / qTest
Zephyr / Xray
Spreadsheet
Selenium / Cypress
Assrt
Real-browser run
Playwright files

Step 3 — Batch the suite and run it

Stack your migrated cases in one file. There is no separate import job, no 500-row queue, no field-mapping screen. The file is the migration. Note how the data-driven cases reuse one {{COUPON}} variable instead of a row per dataset, and how a case that used to be a negative-test spreadsheet row (the expired coupon) becomes three sentences.

tests.txt
# tests.txt — one file, the whole migrated suite

#Case 1: Apply a valid coupon at checkout
Open the cart with one item. Click "Have a code?",
enter {{COUPON}}, click Apply. Verify the total drops 10%
and a "{{COUPON}} applied" badge shows.

#Case 2: Reject an expired coupon
Open the cart with one item. Enter the code EXPIRED2024
and click Apply. Verify an error reads "This code has expired"
and the order total does not change.

#Case 3: Checkout completes after a valid coupon
Apply {{COUPON}}, continue to payment, fill the test card,
and place the order. Verify the confirmation page shows an
order number and the discounted total.

Then run the whole file. The --plan-file flag reads your cases, --extension reuses your logged-in Chrome session so auth-gated cases just work, and --json gives you a CI-friendly result file.

terminal
# Run the whole migrated suite, parameterized, with video
npx @assrt-ai/assrt run \
  --url https://staging.your-app.com \
  --plan-file tests.txt \
  --extension \
  --video \
  --json > results.json

The whole migration, in four moves

  1. 1

    Pull one case

    Copy a single test case out of TestRail, Zephyr, or your spreadsheet. Ignore IDs, sections, priority, and type columns.

  2. 2

    Rewrite as #Case

    Turn it into #Case N: title plus 3 to 5 plain steps. Data columns become {{VARIABLE}} placeholders.

  3. 3

    Batch into tests.txt

    Stack every migrated case in one file in your repo. For happy paths you already ship, let assrt_plan generate them instead of retyping.

  4. 4

    Run and keep the output

    assrt run --plan-file gives a real-browser pass/fail run, a video, and Playwright files you own and can run anywhere.

When a closed test-management migration is the right call

This approach is not free of trade-offs and it is worth being honest about them. If your organization needs an audit trail of who edited which manual case, a formal test-run sign-off workflow, or a compliance-grade vendor with a support contract, a dedicated test-management system is genuinely the better home, and you should migrate your cases there. Assrt does not replace that governance layer; it replaces the part where a human re-runs the same browser steps by hand every release.

The reason to migrate cases into Assrt instead is narrower and specific: you want the cases to execute, you want the output to be code you can read and commit, and you do not want to be locked to a closed engine to keep your own coverage running. If that is the goal, a plain-text #Case beats a mapped CSV row every time.

Migrating a real suite and want a second pair of eyes?

Walk through moving your TestRail, Zephyr, or spreadsheet cases into runnable #Case blocks and Playwright output, on your own app.

Migration questions, answered

What format do I migrate my test cases into?

A plain-text block called a #Case. Each case is `#Case N: short title` followed by 3 to 5 steps written in plain English. There is no schema to satisfy, no mandatory Module-name or Test-case-ID column, and no CSV template to download. The format is documented in assrt-mcp/src/mcp/server.ts and parsed in src/core/agent.ts. A migrated case is just a few human sentences under a heading.

Do I have to upload a CSV or map fields like in TestRail or QA Touch?

No. The classic test-management migration is: export CSV or XLS, upload it, then map your columns to the destination tool's mandatory fields (Module name and Test case title are typically required), and queue the job if you have more than 500 rows. Assrt skips all of that. You paste or write #Case blocks and run them. The cases never become rows in a database you have to query through a vendor.

Where do the migrated cases actually live?

On disk, as a markdown file. When a scenario loads, Assrt writes the plan text to /tmp/assrt/scenario.md and watches it for edits (see assrt-mcp/src/core/scenario-files.ts). You can open it, edit a case, and the change syncs back. For a whole suite you keep your own tests.txt in your repo and pass it with --plan-file. The source of truth is a text file you own, not a record in someone else's system.

What about data-driven cases that had parameter columns?

Those become {{VARIABLE}} placeholders. If your old tool stored a coupon code, an email, or a SKU in a data column, write {{COUPON}} or {{EMAIL}} in the #Case text and pass the values at run time (the variables option interpolates {{KEY}} into the plan and shows them to the agent). One #Case plus a set of variables replaces a row-per-dataset spreadsheet.

I have hundreds of manual cases. Do I really have to retype every one?

Not necessarily. For coverage you already have on the live app, run assrt_plan against the URL and it crawls the page and proposes executable #Case scenarios for you, so you start from generated cases instead of a blank file. Retyping is only worth it for the specific edge cases your manual suite captured that a crawler would not guess (an expired-coupon path, a specific error string). Migrate those by hand and let assrt_plan cover the happy paths.

What do I get out the other end, and can I leave later?

You get a real-browser run with pass or fail per case, a recorded video, and standard Playwright test files. There is no proprietary YAML and no closed engine. If you ever want to stop using Assrt, you keep the Playwright files and run them in any CI with `npx playwright test`. The migration target is your own repo, which is the whole point: leaving costs nothing because you never left your own code.

How is this different from importing TestRail cases into testRigor or another AI tool?

Tools like testRigor can also take English test cases and automate them, but the automation lives inside their cloud and stays in their format. Assrt's output is plain Playwright on your machine, the tool is open source and free, and you can self-host the whole thing. The honest trade: a closed SaaS gives you a managed dashboard and support contracts; Assrt gives you the code and zero lock-in. Pick based on whether owning the output matters to you.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.