- 基本情報
- プロジェクト管理
- プロジェクトの運用とユーティリティ
- プロジェクトをインポート
- プロジェクトをエクスポートする
- データをエクスポート
- TMH file format specification
- 一括操作
- レポート
- Test Manager の成果物を他の提供オプションに移行する
- Test Manager の設定
- ALM ツールとの連携
- API 連携
Test Manager ガイド
はじめに
A .tmh file is UiPath Test Manager's portable data container format. While it is commonly used to back up and restore entire projects, its scope is broader than that:
- Project backup and restore — export a complete project including all test cases, test sets, requirements, executions, and configuration, then import it into a new or existing project.
- Selective object migration — export any subset of objects (e.g. only test cases, or only requirements) and import them into a different project or a different Test Manager instance.
- Cross-instance migration — move projects between Test Manager deployments, including between cloud and on-premises installations.
- Third-party tooling — external tools and scripts can generate
.tmhfiles from scratch to bulk-create Test Manager objects without using the UI or API directly. This document is intended to support those integration efforts.
A .tmh file is a standard ZIP archive with the .tmh extension. It can be opened with any ZIP tool by renaming it to .zip. The archive contains a manifest.json at the root and all exported object data under an objects/ directory tree.
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-{n}.json
├── customfieldvalues/
│ └── customfieldvalues-{n}.json
├── customfieldlabels/
│ └── customfieldlabels-{n}.json
├── customfielddefinitions/
│ └── customfielddefinitions-{n}.json
├── attachments/
│ └── attachments-{n}.json
├── testexecutions/
│ └── testexecutions-{n}.json
├── testcaselogs/
│ └── testcaselogs-{n}.json
├── teststeplogs/
│ └── teststeplogs-{n}.json
├── testcaselog-assertions/
│ └── testcaselog-assertions-{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-{n}.json
├── objectfilters/
│ └── objectfilters-{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-{n}.json
├── customfieldvalues/
│ └── customfieldvalues-{n}.json
├── customfieldlabels/
│ └── customfieldlabels-{n}.json
├── customfielddefinitions/
│ └── customfielddefinitions-{n}.json
├── attachments/
│ └── attachments-{n}.json
├── testexecutions/
│ └── testexecutions-{n}.json
├── testcaselogs/
│ └── testcaselogs-{n}.json
├── teststeplogs/
│ └── teststeplogs-{n}.json
├── testcaselog-assertions/
│ └── testcaselog-assertions-{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-{n}.json
├── objectfilters/
│ └── objectfilters-{n}.json
├── projectauthorization/
│ └── projectauthorization-{n}.json
├── projectsettings/
│ └── projectsettings.json ← singular, no number suffix
└── prompts/
└── prompts-{n}.json
Object type folders that contain no data can be omitted entirely. The importer silently skips missing folders and files.
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
When manually constructing a .tmh file you may use {n} = 1 (e.g., testcases-1.json) — the importer scans for any matching file in the folder. Both 0 and 1 based numbering work.
Large exports may be split across multiple files (testcases-0.json, testcases-1.json, etc.) — the importer reads all files in the folder in order. Splitting large datasets into chunks prevents imports from being cancelled due to excessive resource consumption and improves performance. It is recommended to keep each chunk to a maximum of 500 objects.
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.
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:
| バージョン | Notable additions |
|---|---|
1.0.0 | Initial: requirements, test cases, test steps, test sets, assignments, labels, attachments, defects, custom field values |
1.0.1 | preCondition on test cases |
1.0.2 | Test executions, test case log result overrides, assertions |
1.0.4 | Subset export (isSubsetExport, exportSubsetDetails) |
1.0.5 | Custom field labels |
1.0.7 | User-defined prompts |
1.0.9 | postCondition on test cases |
1.0.10 | パラメーター |
1.0.11 | Test set packages, folderKey/folderName on test sets, packageEntryPointUniqueId etc. on test cases |
1.0.13 | id field on attachments |
1.0.14 | studioWebFileId/studioWebProjectId on test cases; id on test-set/test-case assignments |
1.0.15 | assigneeEmail on test-set/test-case assignments |
1.0.16 | Project 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"
}
packageName, packageSize, and chunkSize fields exist in the DTO but are marked [ProjectImportSchemaIgnore] — the importer ignores them. Real exports omit these fields; do not include them 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"
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
id | GUID string | Unique per-requirement identifier |
name | string | Required; max 255 chars |
description | string | Can be empty string |
foreignRef | string | External system reference; can be empty |
connectorRequirementId | GUID string | Use "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": "",
"description": "",
"automationId": "",
"automationTestCaseName": "",
"automationProjectName": "",
"foreignRef": "",
"connectorTestCaseId": "",
"preCondition": "",
"postCondition": "",
"packageEntryPointUniqueId": "",
"packageIdentifier": "",
"packageEntryPointName": "",
"feedId": "",
"packageSourceName": "",
"studioWebFileId": "",
"studioWebProjectId": ""
}
]
}
{
"testCases": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"version": null,
"name": "Verify login with valid credentials",
"inputParams": "",
"description": "",
"automationId": "",
"automationTestCaseName": "",
"automationProjectName": "",
"foreignRef": "",
"connectorTestCaseId": "",
"preCondition": "",
"postCondition": "",
"packageEntryPointUniqueId": "",
"packageIdentifier": "",
"packageEntryPointName": "",
"feedId": "",
"packageSourceName": "",
"studioWebFileId": "",
"studioWebProjectId": ""
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
id | GUID string | Unique per test case |
version | string | null | null for manual test cases; populated for automated test cases linked to a package version |
name | string | Required; max 255 chars |
inputParams | string | JSON-encoded input parameters; empty string for manual |
description | string | Rich text description |
automationId | string | UiPath automation identifier; empty for manual |
automationTestCaseName | string | Automation display name; empty for manual |
automationProjectName | string | Automation project; empty for manual |
foreignRef | string | External system reference |
connectorTestCaseId | string | Connector system ID |
preCondition | string (v1.0.1+) | Pre-condition text; max 8000 chars |
postCondition | string (v1.0.9+) | Post-condition text; max 8000 chars |
packageEntryPointUniqueId | string (v1.0.11+) | Package entry point; empty for manual |
packageIdentifier | string (v1.0.11+) | Package ID; empty for manual |
packageEntryPointName | string (v1.0.11+) | Entry point name; empty for manual |
feedId | string (v1.0.11+) | Package feed ID; empty for manual |
packageSourceName | string (v1.0.11+) | Package source name; empty for manual |
studioWebFileId | string (v1.0.14+) | Studio Web file ID; empty for manual |
studioWebProjectId | string (v1.0.14+) | Studio Web project ID; empty for manual |
teststeps/{n}.json
{
"testSteps": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"testCaseId": "550e8400-e29b-41d4-a716-446655440001",
"orderNo": 1,
"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": 1,
"actionType": null,
"description": "Navigate to the login page",
"expectedResult": "Login page is displayed",
"clipboardData": ""
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
id | GUID string | Unique per step |
testCaseId | GUID string | Must reference an existing test case id |
orderNo | integer | 1-based display order |
actionType | string | null | null for manual steps |
description | string | Step action text |
expectedResult | string | Expected outcome |
clipboardData | string | Clipboard/screenshot data; max 8000 chars; usually empty |
testsets/{n}.json
{
"testSets": [
{
"id": "550e8400-e29b-41d4-a716-446655440020",
"version": "",
"name": "Regression Suite",
"description": "",
"source": 0,
"externalTestSetId": "",
"sourceDetails": "",
"folderKey": "",
"folderName": ""
}
]
}
{
"testSets": [
{
"id": "550e8400-e29b-41d4-a716-446655440020",
"version": "",
"name": "Regression Suite",
"description": "",
"source": 0,
"externalTestSetId": "",
"sourceDetails": "",
"folderKey": "",
"folderName": ""
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
id | GUID string | Unique per test set |
name | string | Required; max 255 chars |
source | integer | 0 = TestManager (default); 1 = external |
folderKey | string (v1.0.11+) | UiPath Orchestrator folder key; empty if not linked |
folderName | string (v1.0.11+) | Folder display name; 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
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
id | GUID string (v1.0.14+) | Assignment identifier |
testSetId | GUID string | References a test set id |
testCaseId | GUID string | References a test case id |
assigneeEmail | string | 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"
}
]
}
No id field. Unlike most other object types, requirement–test case assignments have only requirementId and testCaseId.
objectlabels/{n}.json
{
"objectLabels": [
{
"objectId": "550e8400-e29b-41d4-a716-446655440001",
"objectType": "TestCase",
"labelName": "regression",
"labelColor": "#FF5733"
}
]
}
{
"objectLabels": [
{
"objectId": "550e8400-e29b-41d4-a716-446655440001",
"objectType": "TestCase",
"labelName": "regression",
"labelColor": "#FF5733"
}
]
}
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": "User",
"signatoryLastKnownDetails": "{\"displayName\":\"John Doe\",\"email\":\"john.doe@company.com\"}"
},
{
"signatoryId": "550e8400-e29b-41d4-a716-446655440100",
"signatoryType": "UserGroup",
"signatoryLastKnownDetails": "{\"displayName\":\"Administrators\"}"
}
]
}
{
"projectTimeZone": "Europe/Vienna",
"folderKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"governanceEnabled": true,
"governedByDefault": false,
"signatories": [
{
"signatoryId": "550e8400-e29b-41d4-a716-446655440099",
"signatoryType": "User",
"signatoryLastKnownDetails": "{\"displayName\":\"John Doe\",\"email\":\"john.doe@company.com\"}"
},
{
"signatoryId": "550e8400-e29b-41d4-a716-446655440100",
"signatoryType": "UserGroup",
"signatoryLastKnownDetails": "{\"displayName\":\"Administrators\"}"
}
]
}
Unlike all other object files, projectsettings.json is a direct object (not a wrapper array). The file contains a single flat JSON object.
| フィールド | 入力 | 備考 |
|---|---|---|
projectTimeZone | string | null | IANA timezone string (e.g., "Europe/Vienna") |
folderKey | GUID | null | Linked Orchestrator folder |
governanceEnabled | boolean | null | Whether governance is enabled for the project |
governedByDefault | boolean | null | Whether new test cases are governed by default |
signatories | array | null | List of approvers/signatories |
signatories[].signatoryId | GUID | User or group ID from the identity provider |
signatories[].signatoryType | string | "User" OR "UserGroup" |
signatories[].signatoryLastKnownDetails | string (JSON) | Serialised JSON object with display details captured at export time. Used as a fallback during import if the identity cannot be resolved from the identity provider. For users: {"displayName":"…","email":"…"}; for groups: {"displayName":"…"} |
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.
customfielddefinitions/{n}.json
Introduced in schema version 1.0.16. Only present when "Export project configuration" is enabled.
{
"customFieldDefinitions": [
{
"id": "550e8400-e29b-41d4-a716-446655440050",
"name": "Severity",
"description": "Bug severity level",
"dataType": "Label",
"defaultValue": "",
"valueHints": "Low,Medium,High,Critical",
"objectType": "TestCase",
"scope": 2,
"scopeList": ["TestCase"]
}
]
}
{
"customFieldDefinitions": [
{
"id": "550e8400-e29b-41d4-a716-446655440050",
"name": "Severity",
"description": "Bug severity level",
"dataType": "Label",
"defaultValue": "",
"valueHints": "Low,Medium,High,Critical",
"objectType": "TestCase",
"scope": 2,
"scopeList": ["TestCase"]
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
id | GUID string | Unique identifier for this field definition |
name | string | Display name; max 255 chars |
description | string | null | Optional description |
dataType | string | "Text" OR "Label" |
defaultValue | string | null | Default value; max 4000 chars |
valueHints | string | null | Comma-separated list of suggested/allowed values for Label fields; max 4000 chars |
objectType | string | Object type this field applies to: "Requirement", "TestCase", "TestSet", "TestExecution" |
scope | integer | Bitmask of scopeList values (legacy field; kept for compatibility) |
scopeList | array of strings | List of applicable scopes: "Requirement" (1), "TestCase" (2), "TestSet" (4), "TestExecution" (8) |
projectauthorization/{n}.json
Introduced in schema version 1.0.16. Only present when "Export project configuration" is enabled.
{
"userPermissions": [
{
"identityProviderId": "550e8400-e29b-41d4-a716-446655440060",
"email": "jane.smith@company.com",
"displayName": "Jane Smith",
"userType": "User",
"roles": ["TestManager.View", "TestManager.Edit"]
},
{
"identityProviderId": "550e8400-e29b-41d4-a716-446655440061",
"email": "",
"displayName": "QA Team",
"userType": "DirectoryGroup",
"roles": ["TestManager.View"]
}
]
}
{
"userPermissions": [
{
"identityProviderId": "550e8400-e29b-41d4-a716-446655440060",
"email": "jane.smith@company.com",
"displayName": "Jane Smith",
"userType": "User",
"roles": ["TestManager.View", "TestManager.Edit"]
},
{
"identityProviderId": "550e8400-e29b-41d4-a716-446655440061",
"email": "",
"displayName": "QA Team",
"userType": "DirectoryGroup",
"roles": ["TestManager.View"]
}
]
}
| フィールド | 入力 | 備考 |
|---|---|---|
identityProviderId | GUID string | User or group ID from the identity provider |
email | string | Email address; empty string for groups |
displayName | string | Display name at time of export |
userType | string | "User", "LocalUser", "LocalGroup", "DirectoryUser", "DirectoryGroup", or "Robot" |
roles | array of strings | Role names assigned to this user/group on the project |
Rules and constraints
-
All IDs must be unique, valid GUIDs. Do not reuse IDs across objects of the same or different type.
-
Cross-references must resolve. A
testCaseIdin a test step or assignment must refer to a test caseidpresent in the same package. -
Wrapper objects are required. Even when the collection has one item, it must still be wrapped:
{ "testCases": [ {...} ] }, never a bare array or object. -
Empty string vs. null: Most string fields default to
""(empty string), notnull. Optional nullable fields (likeversionon test cases) should usenull. Prefernullover""for fields that are genuinely absent. -
objectCountDetailsin 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. -
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.
- はじめに
- Archive structure
- File naming conventions
- Most object types — numbered chunks
- Project settings — no number suffix
- Encoding requirements
- Schema versioning
- manifest.json
- objects/ — JSON File Schemas
- requirements/{n}.json
- testcases/{n}.json
- teststeps/{n}.json
- testsets/{n}.json
- testsettestcaseassignments/{n}.json
- requirementtestcaseassignments/{n}.json
- objectlabels/{n}.json
- customfieldvalues/{n}.json
- projectsettings/projectsettings.json
- customfielddefinitions/{n}.json
- projectauthorization/{n}.json
- Rules and constraints
- Minimal valid TMH file (hand-crafted)