UiPath Documentation
test-manager
latest
false
Wichtig :
Es kann 1–2 Wochen dauern, bis die Lokalisierung neu veröffentlichter Inhalte verfügbar ist.

Test Manager-Benutzerhandbuch

Letzte Aktualisierung 21. Mai 2026

TMH file format specification

A .tmh file is the project backup/migration format used by UiPath Test Manager. This document describes its structure, content, and encoding requirements in detail.

Archive structure

<package-name>.tmh               ← ZIP archive
├── manifest.json                ← Package metadata and object counts
└── objects/
    ├── requirements/
    │   └── requirements-{n}.json
    ├── testcases/
    │   └── testcases-{n}.json
    ├── teststeps/
    │   └── teststeps-{n}.json
    ├── testsets/
    │   └── testsets-{n}.json
    ├── testsettestcaseassignments/
    │   └── testsettestcaseassignments-{n}.json
    ├── requirementtestcaseassignments/
    │   └── requirementtestcaseassignments-{n}.json
    ├── objectlabels/
    │   ├── objectlabels-testcase-{n}.json
    │   ├── objectlabels-testset-{n}.json
    │   ├── objectlabels-requirement-{n}.json
    │   ├── objectlabels-testexecution-{n}.json
    │   └── objectlabels-testcaselog-{n}.json
    ├── customfieldvalues/
    │   ├── customfieldvalues-testcase-{n}.json
    │   └── customfieldvalues-requirement-{n}.json
    ├── customfieldlabels/
    │   └── customfieldlabels-{n}.json
    ├── customfielddefinitions/
    │   └── customfielddefinitions-{n}.json
    ├── attachments/
    │   ├── attachments-testexecution-{n}.json
    │   ├── attachments-requirement-{n}.json
    │   ├── attachments-testcaselog-{n}.json
    │   ├── attachments-teststeplog-{n}.json
    │   └── attachments-project-{n}.json
    ├── testexecutions/
    │   ├── testexecutions-Manual-Finished-{n}.json
    │   ├── testexecutions-Automated-Finished-{n}.json
    │   └── testexecutions-Mixed-Finished-{n}.json
    ├── testcaselogs/
    │   └── testcaselogs-{n}.json
    ├── teststeplogs/
    │   └── teststeplogs-{n}.json
    ├── testcaselog-assertions/
    │   └── testcaselogassertions-{n}.json
    ├── testcaselogresultoverrides/
    │   └── testcaselogresultoverrides-{n}.json
    ├── assertion-attachments/
    │   └── assertion-attachments-{n}.json
    ├── defects/
    │   └── defects-{n}.json
    ├── parameters/
    │   └── parameters-{n}.json
    ├── testsetpackages/
    │   └── testsetpackages-{n}.json
    ├── testsettestcaseparameters/
    │   └── testsettestcaseparameters-{n}.json
    ├── testsetschedules/
    │   └── testsetschedules-testset-{n}.json
    ├── objectfilters/
    │   └── objectfilters-testset-{n}.json
    ├── projectauthorization/
    │   └── projectauthorization-{n}.json
    ├── projectsettings/
    │   └── projectsettings.json         ← singular, no number suffix
    └── prompts/
        └── prompts-{n}.json
<package-name>.tmh               ← ZIP archive
├── manifest.json                ← Package metadata and object counts
└── objects/
    ├── requirements/
    │   └── requirements-{n}.json
    ├── testcases/
    │   └── testcases-{n}.json
    ├── teststeps/
    │   └── teststeps-{n}.json
    ├── testsets/
    │   └── testsets-{n}.json
    ├── testsettestcaseassignments/
    │   └── testsettestcaseassignments-{n}.json
    ├── requirementtestcaseassignments/
    │   └── requirementtestcaseassignments-{n}.json
    ├── objectlabels/
    │   ├── objectlabels-testcase-{n}.json
    │   ├── objectlabels-testset-{n}.json
    │   ├── objectlabels-requirement-{n}.json
    │   ├── objectlabels-testexecution-{n}.json
    │   └── objectlabels-testcaselog-{n}.json
    ├── customfieldvalues/
    │   ├── customfieldvalues-testcase-{n}.json
    │   └── customfieldvalues-requirement-{n}.json
    ├── customfieldlabels/
    │   └── customfieldlabels-{n}.json
    ├── customfielddefinitions/
    │   └── customfielddefinitions-{n}.json
    ├── attachments/
    │   ├── attachments-testexecution-{n}.json
    │   ├── attachments-requirement-{n}.json
    │   ├── attachments-testcaselog-{n}.json
    │   ├── attachments-teststeplog-{n}.json
    │   └── attachments-project-{n}.json
    ├── testexecutions/
    │   ├── testexecutions-Manual-Finished-{n}.json
    │   ├── testexecutions-Automated-Finished-{n}.json
    │   └── testexecutions-Mixed-Finished-{n}.json
    ├── testcaselogs/
    │   └── testcaselogs-{n}.json
    ├── teststeplogs/
    │   └── teststeplogs-{n}.json
    ├── testcaselog-assertions/
    │   └── testcaselogassertions-{n}.json
    ├── testcaselogresultoverrides/
    │   └── testcaselogresultoverrides-{n}.json
    ├── assertion-attachments/
    │   └── assertion-attachments-{n}.json
    ├── defects/
    │   └── defects-{n}.json
    ├── parameters/
    │   └── parameters-{n}.json
    ├── testsetpackages/
    │   └── testsetpackages-{n}.json
    ├── testsettestcaseparameters/
    │   └── testsettestcaseparameters-{n}.json
    ├── testsetschedules/
    │   └── testsetschedules-testset-{n}.json
    ├── objectfilters/
    │   └── objectfilters-testset-{n}.json
    ├── projectauthorization/
    │   └── projectauthorization-{n}.json
    ├── projectsettings/
    │   └── projectsettings.json         ← singular, no number suffix
    └── prompts/
        └── prompts-{n}.json
Hinweis:

Only object types that were actually exported are present. Missing folders/files are silently skipped during import.

File naming conventions

Most object types — numbered chunks

Files are named <type>-{n}.json where {n} starts at 0 for real exports produced by the system. For example:

requirementtestcaseassignments-0.json
testcases-0.json
teststeps-0.json
requirementtestcaseassignments-0.json
testcases-0.json
teststeps-0.json

The importer scans all files in each folder, so both 0-based and 1-based numbering work when hand-crafting files.

Large exports may be split across multiple files (testcases-0.json, testcases-1.json, etc.) — the importer reads all files in the folder.

Type-scoped file names

Several object types scope their files by the object type they belong to. The importer reads all files in the folder regardless of the qualifier, but real exports always use these names:

ObjekttypMuster des Dateinamens
ObjectLabelsobjectlabels-testcase-{n}.json, objectlabels-testset-{n}.json, objectlabels-requirement-{n}.json, …
CustomFieldValuescustomfieldvalues-testcase-{n}.json, customfieldvalues-requirement-{n}.json
Anhänge (Attachments)attachments-testexecution-{n}.json, attachments-requirement-{n}.json, …
Testausführungentestexecutions-Manual-Finished-{n}.json, testexecutions-Automated-Finished-{n}.json, …
Object filtersobjectfilters-testset-{n}.json
Zeitpläne der Testsätzetestsetschedules-testset-{n}.json

Project settings — no number suffix

projectsettings/projectsettings.json
projectsettings/projectsettings.json

This file is always singular (no chunk number).

Encoding requirements

All JSON files must be encoded as UTF-8 without BOM.

Warnung:

PowerShell 5.1's Set-Content -Encoding utf8 writes a UTF-8 BOM (EF BB BF). This causes JSON.parse in the browser to throw SyntaxError: Unexpected token at position 0. Always use [System.IO.File]::WriteAllText($path, $content, (New-Object System.Text.UTF8Encoding($false))) when creating .tmh files from PowerShell.

Schema versioning

The manifest.json carries a schemaVersion field (e.g., "1.0.16"). The importer uses this version together with [IntroducedIn] attributes on each DTO property to determine which fields to read. Fields introduced in a version newer than the package's schema version are ignored during deserialization.

Current latest version: 1.0.16

Version history summary:

VersionNotable additions
1.0.0Initial: requirements, test cases, test steps, test sets, assignments, labels, attachments, defects, custom field values
1.0.1preCondition on test cases
1.0.2Test executions, test case log result overrides, assertions
1.0.4Subset export (isSubsetExport, exportSubsetDetails)
1.0.5Custom field labels
1.0.7User-defined prompts
1.0.9postCondition on test cases
1.0.10Parameter
1.0.11Test set packages, folderKey/folderName on test sets, packageEntryPointUniqueId etc. on test cases
1.0.13id field on attachments
1.0.14studioWebFileId/studioWebProjectId on test cases; id on test-set/test-case assignments
1.0.15assigneeEmail on test-set/test-case assignments
1.0.16Project configuration (settings, governance, signatories), custom field definitions, project authorizations

manifest.json

Located at the root of the archive (not inside objects/).

{
  "objectCountDetails": {
    "testCases": 5,
    "testSets": 2,
    "requirements": 3,
    "objectLabels": 0,
    "attachments": 0,
    "testExecutions": 0,
    "testCaseLogs": 0,
    "testCaseResultOverrides": 0,
    "testSteps": 12,
    "testStepLogs": 0,
    "testSetTestCaseAssignments": 6,
    "requirementTestCaseAssignments": 4,
    "defects": 0,
    "customFieldValues": 0,
    "customFieldLabels": 0,
    "assertions": 0,
    "assertionScreenshots": 0,
    "testSetLabelFilters": 0,
    "userDefinedPrompts": 0,
    "parameters": 0,
    "testSetPackages": 0,
    "testSetTestCaseParameters": 0,
    "customFieldDefinitions": 0,
    "projectAuthorizations": 0
  },
  "project": {
    "name": "My Project",
    "description": "Project description",
    "projectPrefix": "MP"
  },
  "tmPackageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "schemaVersion": "1.0.16"
}
{
  "objectCountDetails": {
    "testCases": 5,
    "testSets": 2,
    "requirements": 3,
    "objectLabels": 0,
    "attachments": 0,
    "testExecutions": 0,
    "testCaseLogs": 0,
    "testCaseResultOverrides": 0,
    "testSteps": 12,
    "testStepLogs": 0,
    "testSetTestCaseAssignments": 6,
    "requirementTestCaseAssignments": 4,
    "defects": 0,
    "customFieldValues": 0,
    "customFieldLabels": 0,
    "assertions": 0,
    "assertionScreenshots": 0,
    "testSetLabelFilters": 0,
    "userDefinedPrompts": 0,
    "parameters": 0,
    "testSetPackages": 0,
    "testSetTestCaseParameters": 0,
    "customFieldDefinitions": 0,
    "projectAuthorizations": 0
  },
  "project": {
    "name": "My Project",
    "description": "Project description",
    "projectPrefix": "MP"
  },
  "tmPackageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "schemaVersion": "1.0.16"
}
Hinweis:

Real exports also include a packageName field (the suggested download filename). The importer ignores it — omit it in hand-crafted files.

objects/ — JSON file schemas

Every object file uses a wrapper object whose single property is a JSON array. The array contains the individual object records.

requirements/{n}.json

{
  "requirements": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "User can log in",
      "description": "The login form must accept valid credentials.",
      "foreignRef": "",
      "connectorRequirementId": "00000000-0000-0000-0000-000000000000"
    }
  ]
}
{
  "requirements": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "User can log in",
      "description": "The login form must accept valid credentials.",
      "foreignRef": "",
      "connectorRequirementId": "00000000-0000-0000-0000-000000000000"
    }
  ]
}
FeldTypHinweise
idGUID stringUnique per-requirement identifier
namestringRequired; max 255 chars
descriptionstringCan be empty string
foreignRefstringExternal system reference; can be empty
connectorRequirementIdGUID stringUse "00000000-0000-0000-0000-000000000000" when not linked to a connector

testcases/{n}.json

{
  "testCases": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "version": null,
      "name": "Verify login with valid credentials",
      "inputParams": null,
      "description": "",
      "automationId": null,
      "automationTestCaseName": null,
      "automationProjectName": null,
      "foreignRef": "",
      "connectorTestCaseId": null,
      "preCondition": null,
      "postCondition": null,
      "packageEntryPointUniqueId": null,
      "packageIdentifier": null,
      "packageEntryPointName": null,
      "feedId": null,
      "packageSourceName": null,
      "studioWebFileId": null,
      "studioWebProjectId": null
    }
  ]
}
{
  "testCases": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "version": null,
      "name": "Verify login with valid credentials",
      "inputParams": null,
      "description": "",
      "automationId": null,
      "automationTestCaseName": null,
      "automationProjectName": null,
      "foreignRef": "",
      "connectorTestCaseId": null,
      "preCondition": null,
      "postCondition": null,
      "packageEntryPointUniqueId": null,
      "packageIdentifier": null,
      "packageEntryPointName": null,
      "feedId": null,
      "packageSourceName": null,
      "studioWebFileId": null,
      "studioWebProjectId": null
    }
  ]
}
FeldTypHinweise
idGUID stringUnique per test case
versionstring | nullnull for manual test cases; "1.0.0" for automated test cases linked to a package version; "" for automated test cases without a fixed version
namestringRequired; max 255 chars
inputParamsstring | nullJSON-encoded input parameters; null for manual
descriptionstringRich text description; "" when absent
automationIdstring | nullUiPath automation identifier; null for manual
automationTestCaseNamestring | nullAutomation display name; null for manual
automationProjectNamestring | nullAutomation project; null for manual
foreignRefstringExternal system reference; "" when absent
connectorTestCaseIdstring | nullConnector system ID; null when absent
preConditionstring | null (v1.0.1+)Pre-condition text; null when absent; max 8000 chars
postConditionstring | null (v1.0.9+)Post-condition text; null when absent; max 8000 chars
packageEntryPointUniqueIdstring | null (v1.0.11+)Package entry point GUID; null for manual
packageIdentifierstring | null (v1.0.11+)Package ID; null for manual
packageEntryPointNamestring | null (v1.0.11+)Entry point name; null for manual
feedIdstring | null (v1.0.11+)Package feed ID; null for manual
packageSourceNamestring | null (v1.0.11+)Package source name; null for manual
studioWebFileIdstring | null (v1.0.14+)Studio Web file ID; null for manual
studioWebProjectIdstring | null (v1.0.14+)Studio Web project ID; null for manual

teststeps/{n}.json

{
  "testSteps": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440010",
      "testCaseId": "550e8400-e29b-41d4-a716-446655440001",
      "orderNo": 0,
      "actionType": null,
      "description": "Navigate to the login page",
      "expectedResult": "Login page is displayed",
      "clipboardData": ""
    }
  ]
}
{
  "testSteps": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440010",
      "testCaseId": "550e8400-e29b-41d4-a716-446655440001",
      "orderNo": 0,
      "actionType": null,
      "description": "Navigate to the login page",
      "expectedResult": "Login page is displayed",
      "clipboardData": ""
    }
  ]
}
FeldTypHinweise
idGUID stringUnique per step
testCaseIdGUID stringMust reference an existing test case id
orderNoInteger0-based display order (first step = 0)
actionTypestring | nullnull for manual steps
descriptionstringStep action text
expectedResultstringExpected outcome; "" when absent
clipboardDatastringClipboard/screenshot data; max 8000 chars; usually ""

testsets/{n}.json

{
  "testSets": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440020",
      "version": null,
      "name": "Regression Suite",
      "description": "",
      "source": "TestManager",
      "externalTestSetId": null,
      "sourceDetails": null,
      "folderKey": null,
      "folderName": ""
    }
  ]
}
{
  "testSets": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440020",
      "version": null,
      "name": "Regression Suite",
      "description": "",
      "source": "TestManager",
      "externalTestSetId": null,
      "sourceDetails": null,
      "folderKey": null,
      "folderName": ""
    }
  ]
}
FeldTypHinweise
idGUID stringUnique per test set
versionstring | nullnull for Test Manager–managed test sets
namestringRequired; max 255 chars
descriptionstring"" when absent
sourcestring"TestManager" (default) or "Orchestrator"this is a string, not an integer
externalTestSetIdstring | nullExternal ID when source is "Orchestrator"; null otherwise
sourceDetailsstring | nullAdditional source metadata; null when absent
folderKeystring | null (v1.0.11+)UiPath Orchestrator folder key; null if not linked
folderNamestring (v1.0.11+)Folder display name; "" if not linked; not stored in DB, informational only

testsettestcaseassignments/{n}.json

{
  "testSetTestCaseAssignments": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440030",
      "testSetId": "550e8400-e29b-41d4-a716-446655440020",
      "testCaseId": "550e8400-e29b-41d4-a716-446655440001",
      "assigneeEmail": null
    }
  ]
}
{
  "testSetTestCaseAssignments": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440030",
      "testSetId": "550e8400-e29b-41d4-a716-446655440020",
      "testCaseId": "550e8400-e29b-41d4-a716-446655440001",
      "assigneeEmail": null
    }
  ]
}
FeldTypHinweise
idGUID string (v1.0.14+)Assignment identifier
testSetIdGUID stringReferences a test set id
testCaseIdGUID stringReferences a test case id
assigneeEmailstring | null (v1.0.15+)Assignee email; null if unassigned

requirementtestcaseassignments/{n}.json

{
  "requirementTestCaseAssignments": [
    {
      "requirementId": "550e8400-e29b-41d4-a716-446655440000",
      "testCaseId": "550e8400-e29b-41d4-a716-446655440001"
    }
  ]
}
{
  "requirementTestCaseAssignments": [
    {
      "requirementId": "550e8400-e29b-41d4-a716-446655440000",
      "testCaseId": "550e8400-e29b-41d4-a716-446655440001"
    }
  ]
}
Warnung:

No id field. Unlike most other object types, requirement–test case assignments have only requirementId and testCaseId.

objectlabels/objectlabels-{objecttype}-{n}.json

Hinweis:

File naming: Real exports use a type-qualified name such as objectlabels-testcase-1.json, objectlabels-testset-1.json, objectlabels-requirement-1.json, etc. The importer reads all files in the objectlabels/ folder, so the qualifier is not strictly required when hand-crafting files, but it is recommended to follow the convention.

{
  "objectLabels": [
    {
      "objectId": "550e8400-e29b-41d4-a716-446655440001",
      "name": "regression",
      "description": "",
      "labelType": 0,
      "objectType": "TestCase"
    }
  ]
}
{
  "objectLabels": [
    {
      "objectId": "550e8400-e29b-41d4-a716-446655440001",
      "name": "regression",
      "description": "",
      "labelType": 0,
      "objectType": "TestCase"
    }
  ]
}
FeldTypHinweise
objectIdGUID stringID of the labelled object
namestringLabel text
descriptionstringLabel description; "" when absent
labelTypeInteger1 = system label (e.g. "manual", "automated"); 0 = user-defined label
objectTypestring"TestCase", "TestSet", "Requirement", "TestExecution", "TestCaseLog"

customfieldvalues/{n}.json

{
  "customFieldValues": [
    {
      "objectId": "550e8400-e29b-41d4-a716-446655440001",
      "objectType": "TestCase",
      "fieldName": "Priority",
      "fieldValue": "High"
    }
  ]
}
{
  "customFieldValues": [
    {
      "objectId": "550e8400-e29b-41d4-a716-446655440001",
      "objectType": "TestCase",
      "fieldName": "Priority",
      "fieldValue": "High"
    }
  ]
}

projectsettings/projectsettings.json

Introduced in schema version 1.0.16. Only present when "Export project configuration" is enabled.

{
  "projectTimeZone": "Europe/Vienna",
  "folderKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "governanceEnabled": true,
  "governedByDefault": false,
  "signatories": [
    {
      "signatoryId": "550e8400-e29b-41d4-a716-446655440099",
      "signatoryType": 0,
      "signatoryLastKnownDetails": "john.doe@company.com"
    }
  ]
}
{
  "projectTimeZone": "Europe/Vienna",
  "folderKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "governanceEnabled": true,
  "governedByDefault": false,
  "signatories": [
    {
      "signatoryId": "550e8400-e29b-41d4-a716-446655440099",
      "signatoryType": 0,
      "signatoryLastKnownDetails": "john.doe@company.com"
    }
  ]
}
Hinweis:

Unlike all other object files, projectsettings.json is a direct object (not a wrapper array). The file contains a single flat JSON object.

FeldTypHinweise
projectTimeZonestring | nullIANA timezone string (e.g., "Europe/Vienna")
folderKeyGUID | nullLinked Orchestrator folder
governanceEnabledboolean | nullWhether governance is enabled for the project
governedByDefaultboolean | nullWhether new test cases are governed by default
signatoriesarray | nullList of approvers/signatories
signatories[].signatoryIdGUIDUser or group ID
signatories[].signatoryTypeInteger0 = User, 1 = UserGroup
signatories[].signatoryLastKnownDetailsstringDisplay name or email at time of export
Hinweis:

lastDisabledAt (the governance disable timestamp) is intentionally excluded from the export — it is an internal timestamp that is not meaningful for a re-imported project.

Rules and constraints

  1. All IDs must be unique, valid GUIDs. Do not reuse IDs across objects of the same or different type.

  2. Cross-references must resolve. A testCaseId in a test step or assignment must refer to a test case id present in the same package.

  3. Wrapper objects are required. Even when the collection has one item, it must still be wrapped: { "testCases": [ {...} ] }, never a bare array or object.

  4. null vs "" conventions: Use null for optional fields that are genuinely absent (e.g. automationId, inputParams, preCondition, connectorTestCaseId, all package* fields on manual test cases). Use "" only for fields that are always present as strings but happen to be empty (e.g. foreignRef, description, clipboardData). Mixing these up — particularly using "" where null is expected — can cause silent import failures.

  5. objectCountDetails in the manifest should match actual counts of objects present, but the importer does not strictly validate counts — mismatches only affect the pre-import summary display.

  6. UTF-8 without BOM is mandatory for all files.

Minimal valid TMH file (hand-crafted)

The smallest valid .tmh file that Test Manager will accept contains just a manifest.json:

{
  "objectCountDetails": { ... },
  "project": { "name": "Test Project", "description": "", "projectPrefix": "TP" },
  "tmPackageId": "<new-guid>",
  "schemaVersion": "1.0.16"
}
{
  "objectCountDetails": { ... },
  "project": { "name": "Test Project", "description": "", "projectPrefix": "TP" },
  "tmPackageId": "<new-guid>",
  "schemaVersion": "1.0.16"
}

All objects/ subdirectories are optional. The importer silently skips any object type not present in the archive.

War diese Seite hilfreich?

Verbinden

Benötigen Sie Hilfe? Support

Möchten Sie lernen? UiPath Academy

Haben Sie Fragen? UiPath-Forum

Auf dem neuesten Stand bleiben