Import test results from CI
Send a JUnit XML report from your pipeline and Rindo records a test run — tag each test with its case id, and let it draft the cases you have not written yet.
A CI pipeline that writes JUnit XML — pytest with --junitxml, Jest with the jest-junit reporter, Maven Surefire, gotestsum with --junitfile, and most others — can record its results in Rindo as a test run, with each result pinned to the test case it exercised. This page is the pipeline side; the cases and runs themselves are on Test cases and runs.
Tag your tests
Rindo matches a test to a case by a tag in the test’s name: the case’s key in square brackets, [TC-12], anywhere in the name. A test with two tags records against two cases. A tag that names no case — or a case in the Trash, or in another project — is reported as unmatched; a deprecated case is skipped. Draft and active cases both take results.
In Jest or Go the tag goes straight into the test’s title. In pytest a function name cannot hold brackets, so give the test an id — pytest writes it into the reported name as test_login[TC-12]:
@pytest.mark.parametrize("_", [None], ids=["TC-12"])
def test_login_with_a_valid_password(_):
...
The id is the number in the case’s key on its page. If you have not written the cases yet, let the import draft them: with Create draft cases for untagged tests on, every distinct untagged test makes one Draft case titled by its class name and test name, and the ids come back in the report — tag the tests, then turn the option off, because a later import with it on drafts the still-untagged tests again. Draft cases do not count toward coverage until someone marks them Active.
What is recorded
- A passed test is a Pass — a Surefire test that passed on a rerun included; a failure or an error is a Fail; a skipped test is a Skip. An import never records Blocked. When several tests map to one case the worst result wins; each failed, errored or skipped test adds its name, message and output to the result’s note, up to ten thousand characters.
- The import makes one run with every result already recorded, in one step — a report that fails is not half-imported, and a report in which no test maps to a case it can record is refused rather than recorded. The run’s name is the one you give, else the suite’s name from the file; a Build can be set.
- Each result pins the case’s current steps revision, as a result recorded by hand would. At most five hundred cases per import; split a larger report.
From the app
Open Tests → Runs → Import: choose the .xml, keep or change the Run name (pre-filled from the file name), tick the draft option if you want it, add a Build, and Import. The report says how many existing cases matched out of the tests in the file, the pass, fail and skip counts, the draft cases created, the unmatched tests with their reasons, and the deprecated cases skipped; View run opens the run.
From the pipeline
PROJECT="https://app.rindo.io/api/v1/projects/<project id>"
curl -sS --fail-with-body -X POST \
"$PROJECT/test-runs/import?name=CI%20main&build=1.9.0-rc1" \
-H "Authorization: Bearer rnd_…" \
--data-binary @junit.xml
- The token is a personal access token from Account settings → MCP access, held by someone with Member or above in the project, with full access or a scope that includes Record test runs and results. A read-only token is refused, and so is a runner’s or a connected app’s credential. The results are recorded as that person and, like any token write, marked via MCP.
- Add
&auto_create=trueto draft cases for untagged tests. The project id is a number the app does not show:GET /api/v1/projects?key=ACMEreturns the project with itsid. - The response is the run with its results and an
import_report: the totals, the cases created, the unmatched tests and the skipped ones. A file that is not JUnit XML (the root is<testsuites>or<testsuite>), a report in which no test maps to a case it can record — every test untagged with the draft option off, say — a blank name, more than five hundred cases or a body over 25 MiB answers an error that says which.
There is no MCP tool for this import; an agent that runs tests records them with create_test_run and record_test_result.