- Erste Schritte
- Projektmanagement
- Dokumente
- Arbeiten mit der Analyse der Änderungsauswirkungen
- Erstellen von Testfällen
- Zuweisen von Testfällen zu Anforderungen
- Klonen von Testfällen
- Exportieren von Testfällen
- Verknüpfen von Testfällen in Studio mit dem Test Manager
- Delete test cases
- Manuelle Testfälle
- Importieren manueller Testfälle
- Dokumentieren von Testfällen mit Task Capture
- Parameter
- Aktivieren der Governance auf Projektebene
- Deaktivieren der Governance auf Projektebene
- Aktivieren der Governance auf Testfallebene
- Deaktivieren der Governance auf Testfallebene
- Verwalten von Genehmigern für strukturierte Testfälle
- Verwalten von gesteuerten Testfällen im Status In Arbeit
- Verwalten von geregelten Testfällen im Status „Wird überprüft“.
- Verwalten von gesteuerten Objekten im Status „Signiert“.
- Verwalten von Kommentaren für gesteuerte Testfälle
- Anwenden von Filtern und Ansichten
- Importieren von Orchestrator-Testsätzen
- Creating test sets
- Hinzufügen von Testfällen zu einem Testsatz
- Zuweisen von Standardbenutzern in der Testsatzausführung
- Aktivieren der Aktivitätsabdeckung
- Aktivieren von Healing Agent
- Konfigurieren von Testsätzen für bestimmte Ausführungsordner und Roboter
- Überschreiben von Parametern
- Klonen von Testsätzen
- Exportieren von Testsätzen
- Anwenden von Filtern und Ansichten
- FAQ – Funktion – Test Manager vs Orchestrator
- Ausführen von manuellen Tests
- Ausführen automatisierter Tests
- Ausführen von Testfällen ohne Testsatz
- Ausführen gemischter Tests
- Erstellen von ausstehenden Ausführungen
- Erzwingen einer Ausführungsreihenfolge
- Erneutes Ausführen von Testausführungen
- Planen von Ausführungen
- Fehlerbehebung bei automatisierten Ausführungen
- Zugänglichkeitstests für Test Cloud
- Suche mit Autopilot
- Projektvorgänge und Dienstprogramme
- Test Manager-Einstellungen
- ALM Tool-Integration
- API-Integration
- Fehlersuche und ‑behebung
Test Manager-Benutzerhandbuch
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
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:
| Objekttyp | Muster des Dateinamens |
|---|---|
| ObjectLabels | objectlabels-testcase-{n}.json, objectlabels-testset-{n}.json, objectlabels-requirement-{n}.json, … |
| CustomFieldValues | customfieldvalues-testcase-{n}.json, customfieldvalues-requirement-{n}.json |
| Anhänge (Attachments) | attachments-testexecution-{n}.json, attachments-requirement-{n}.json, … |
| Testausführungen | testexecutions-Manual-Finished-{n}.json, testexecutions-Automated-Finished-{n}.json, … |
| Object filters | objectfilters-testset-{n}.json |
| Zeitpläne der Testsätze | testsetschedules-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.
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:
| Version | 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 | Parameter |
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"
}
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"
}
]
}
| Feld | Typ | Hinweise |
|---|---|---|
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": 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
}
]
}
| Feld | Typ | Hinweise |
|---|---|---|
id | GUID string | Unique per test case |
version | string | null | null for manual test cases; "1.0.0" for automated test cases linked to a package version; "" for automated test cases without a fixed version |
name | string | Required; max 255 chars |
inputParams | string | null | JSON-encoded input parameters; null for manual |
description | string | Rich text description; "" when absent |
automationId | string | null | UiPath automation identifier; null for manual |
automationTestCaseName | string | null | Automation display name; null for manual |
automationProjectName | string | null | Automation project; null for manual |
foreignRef | string | External system reference; "" when absent |
connectorTestCaseId | string | null | Connector system ID; null when absent |
preCondition | string | null (v1.0.1+) | Pre-condition text; null when absent; max 8000 chars |
postCondition | string | null (v1.0.9+) | Post-condition text; null when absent; max 8000 chars |
packageEntryPointUniqueId | string | null (v1.0.11+) | Package entry point GUID; null for manual |
packageIdentifier | string | null (v1.0.11+) | Package ID; null for manual |
packageEntryPointName | string | null (v1.0.11+) | Entry point name; null for manual |
feedId | string | null (v1.0.11+) | Package feed ID; null for manual |
packageSourceName | string | null (v1.0.11+) | Package source name; null for manual |
studioWebFileId | string | null (v1.0.14+) | Studio Web file ID; null for manual |
studioWebProjectId | string | 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": ""
}
]
}
| Feld | Typ | Hinweise |
|---|---|---|
id | GUID string | Unique per step |
testCaseId | GUID string | Must reference an existing test case id |
orderNo | Integer | 0-based display order (first step = 0) |
actionType | string | null | null for manual steps |
description | string | Step action text |
expectedResult | string | Expected outcome; "" when absent |
clipboardData | string | Clipboard/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": ""
}
]
}
| Feld | Typ | Hinweise |
|---|---|---|
id | GUID string | Unique per test set |
version | string | null | null for Test Manager–managed test sets |
name | string | Required; max 255 chars |
description | string | "" when absent |
source | string | "TestManager" (default) or "Orchestrator" — this is a string, not an integer |
externalTestSetId | string | null | External ID when source is "Orchestrator"; null otherwise |
sourceDetails | string | null | Additional source metadata; null when absent |
folderKey | string | null (v1.0.11+) | UiPath Orchestrator folder key; null if not linked |
folderName | string (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
}
]
}
| Feld | Typ | Hinweise |
|---|---|---|
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/objectlabels-{objecttype}-{n}.json
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"
}
]
}
| Feld | Typ | Hinweise |
|---|---|---|
objectId | GUID string | ID of the labelled object |
name | string | Label text |
description | string | Label description; "" when absent |
labelType | Integer | 1 = system label (e.g. "manual", "automated"); 0 = user-defined label |
objectType | string | "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"
}
]
}
Unlike all other object files, projectsettings.json is a direct object (not a wrapper array). The file contains a single flat JSON object.
| Feld | Typ | Hinweise |
|---|---|---|
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 |
signatories[].signatoryType | Integer | 0 = User, 1 = UserGroup |
signatories[].signatoryLastKnownDetails | string | Display name or email at time of export |
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
-
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. -
nullvs""conventions: Usenullfor optional fields that are genuinely absent (e.g.automationId,inputParams,preCondition,connectorTestCaseId, allpackage*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""wherenullis expected — can cause silent import failures. -
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
- Type-scoped file names
- 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/objectlabels-{objecttype}-{n}.json
- customfieldvalues/{n}.json
- projectsettings/projectsettings.json
- Rules and constraints
- Minimal valid TMH file (hand-crafted)