UiPath Documentation
test-manager
latest
false
重要 :
新发布内容的本地化可能需要 1-2 周的时间才能完成。

Test Manager 用户指南

TMH 文件格式规范

.tmh文件是 UiPath Test Manager 使用的项目备份/迁移格式。本文档详细描述其结构、内容和编码要求。

存档结构

<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
备注:

仅显示实际导出的对象类型。导入期间,系统会静默跳过缺少的文件夹/文件。

文件命名约定

大多数对象类型 — 编号块

对于系统生成的实际导出,文件名为<type>-{n}.json ,其中{n}0开始。例如:

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

导入程序将扫描每个文件夹中的所有文件,因此在手动创建文件时,基于01的编号都有效。

大型导出可以拆分为多个文件( testcases-0.jsontestcases-1.json等)— 导入程序会读取文件夹中的所有文件。

提示:

为获得最佳性能,请将每个文件最多限制为 500 个对象。

类型范围的文件名

有几种对象类型按其所属的对象类型对其文件进行范围限制。无论限定符如何,导入器都会读取文件夹中的所有文件,但实际导出始终使用以下名称:

对象类型文件名称模式
对象标签objectlabels-testcase-{n}.jsonobjectlabels-testset-{n}.jsonobjectlabels-requirement-{n}.json 、...
自定义字段值customfieldvalues-testcase-{n}.json, customfieldvalues-requirement-{n}.json
附件attachments-testexecution-{n}.jsonattachments-requirement-{n}.json 、...
测试执行testexecutions-Manual-Finished-{n}.jsontestexecutions-Automated-Finished-{n}.json 、...
对象筛选器objectfilters-testset-{n}.json
测试集计划testsetschedules-testset-{n}.json

项目设置 — 无数字后缀

projectsettings/projectsettings.json
projectsettings/projectsettings.json

此文件始终为单数(无块编号)。

编码要求

所有 JSON 文件都必须编码为UTF-8不带 BOM

警告:

PowerShell 5.1 的Set-Content -Encoding utf8写入 UTF-8 BOM ( EF BB BF )。这会导致浏览器中的JSON.parse在位置 0 处引发SyntaxError: Unexpected token从 PowerShell 创建.tmh文件时,始终使用[System.IO.File]::WriteAllText($path, $content, (New-Object System.Text.UTF8Encoding($false)))

架构版本控制

manifest.json包含schemaVersion字段(例如"1.0.16" )。导入器将此版本与每个 DTO 属性上的[IntroducedIn]属性一起使用来确定要读取的字段。反序列化期间将忽略在比包架构版本更新的版本中引入的字段。

当前最新版本: 1.0.16

版本历史记录摘要:

版本重要新增内容
1.0.0初始:需求、测试用例、测试步骤、测试集、分配、标签、附件、缺陷、自定义字段值
1.0.1preCondition 测试用例上
1.0.2测试执行、测试用例日志结果覆盖、断言
1.0.4子集导出( isSubsetExportexportSubsetDetails
1.0.5自定义字段标签
1.0.7用户定义的提示
1.0.9postCondition 测试用例上
1.0.10参数
1.0.11测试集包、测试集为folderKey / folderName 、测试用例为packageEntryPointUniqueId
1.0.13id 附件字段
1.0.14studioWebFileId/ studioWebProjectId (对测试用例);测试集/测试用例分配为id
1.0.15assigneeEmail 测试集/测试用例分配上
1.0.16项目配置(设置、监管、签署人)、自定义字段定义、项目授权

Manifest.json

位于存档的根目录(不在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字段(建议的下载文件名)。导入程序会忽略它 — 在手动创建的文件中省略它。

objects/ — JSON 文件架构

每个对象文件都使用一个包装器对象,该包装器对象的单个属性是 JSON 数组。该数组包含单个对象记录。

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"
    }
  ]
}
字段类型注意
idGUID 字符串每个需求的唯一标识符
name字符串必填项;最多 255 个字符
description字符串可以为空字符串
foreignRef字符串外部系统引用;可以为空
connectorRequirementIdGUID 字符串未链接到连接器时,请使用"00000000-0000-0000-0000-000000000000"

测试用例/{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
    }
  ]
}
字段类型注意
idGUID 字符串每个测试用例唯一
version字符串 |空null 针对手动测试用例; "1.0.0"适用于链接到包版本的自动化测试用例; ""适用于没有固定版本的自动化测试用例
name字符串必填项;最多 255 个字符
inputParams字符串 |空JSON 编码的输入参数; null为手动
description字符串富文本说明;不在时为""
automationId字符串 |空UiPath 自动化标识符; null为手动
automationTestCaseName字符串 |空自动化显示名称; null为手动
automationProjectName字符串 |空自动化项目; null为手动
foreignRef字符串外部系统引用;不在时为""
connectorTestCaseId字符串 |空连接器系统 ID;不在时为null
preCondition字符串 |空 (v1.0.1+)前置条件文本; null不在时);最多 8000 个字符
postCondition字符串 |空 (v1.0.9 及以上版本)后置条件文本; null不在时);最多 8000 个字符
packageEntryPointUniqueId字符串 |空 (v1.0.11+)包入口点 GUID; null为手动
packageIdentifier字符串 |空 (v1.0.11+)包 ID; null为手动
packageEntryPointName字符串 |空 (v1.0.11+)入口点名称; null为手动
feedId字符串 |空 (v1.0.11+)包订阅源 ID; null为手动
packageSourceName字符串 |空 (v1.0.11+)包来源名称; null为手动
studioWebFileId字符串 | null (v1.0.14+)Studio Web 文件 ID; null为手动
studioWebProjectId字符串 | null (v1.0.14+)Studio Web 项目 ID; null为手动

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": ""
    }
  ]
}
字段类型注意
idGUID 字符串每个步骤唯一
testCaseIdGUID 字符串必须引用现有测试用例 id
orderNo整数从 0 开始的显示顺序(第一步 = 0
actionType字符串 |空null 适用于手动步骤
description字符串步骤操作文本
expectedResult字符串预期结果;不在时为""
clipboardData字符串剪贴板/屏幕截图数据;最多 8000 个字符;通常 ""

testets/{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": ""
    }
  ]
}
字段类型注意
idGUID 字符串每个测试集唯一
version字符串 |空null 适用于 Test Manager 托管测试集
name字符串必填项;最多 255 个字符
description字符串"" 缺少时
source字符串"TestManager" (默认)或"Orchestrator"这是一个字符串,而不是整数
externalTestSetId字符串 |空source"Orchestrator"时,外部 ID;否则为null
sourceDetails字符串 |空其他源元数据;不在时为null
folderKey字符串 |空 (v1.0.11+)UiPath Orchestrator 文件夹密钥;如果未链接, null
folderName字符串 (v1.0.11+)文件夹显示名称;如果未链接,则使用"" ;未存储在数据库中,仅供参考

测试集测试用例分配/{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
    }
  ]
}
字段类型注意
idGUID 字符串 (v1.0.14+)分配标识符
testSetIdGUID 字符串引用测试集 id
testCaseIdGUID 字符串引用测试用例 id
assigneeEmail字符串 | null (v1.0.15 及以上版本)受分配人电子邮箱;如果未分配,则为null

需求测试用例分配/{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"
    }
  ]
}
警告:

id字段。与大多数其他对象类型不同,需求–测试用例分配只有requirementIdtestCaseId

对象标签/对象标签-{objecttype}-{n}.json

备注:

文件命名:真实导出使用类型限定名称,例如objectlabels-testcase-1.jsonobjectlabels-testset-1.jsonobjectlabels-requirement-1.json等。导入程序会读取objectlabels/文件夹中的所有文件,因此在手动创建文件时,限定符不是严格要求,但建议您遵循约定。

{
  "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"
    }
  ]
}
字段类型注意
objectIdGUID 字符串已标记对象的 ID
name字符串标签文本
description字符串标签说明;不在时为""
labelType整数1 = 系统标签(例如"manual""automated" ); 0 = 用户定义的标签
objectType字符串"TestCase""TestSet""Requirement""TestExecution""TestCaseLog"

自定义字段值/{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

在架构版本1.0.16中引入。仅在启用“导出项目配置”时显示。

{
  "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"
    }
  ]
}
备注:

与所有其他对象文件不同, projectsettings.json直接对象(非包装器数组)。该文件包含单个平面 JSON 对象。

字段类型注意
projectTimeZone字符串 |空IANA 时区字符串(例如"Europe/Vienna"
folderKeyGUID |空链接的 Orchestrator 文件夹
governanceEnabled布尔值 |空是否为项目启用了监管
governedByDefault布尔值 |空是否默认监管新的测试用例
signatories数组 |空审批人/签名人列表
signatories[].signatoryIdGUID用户或组 ID
signatories[].signatoryType整数0 = 用户, 1 = 用户组
signatories[].signatoryLastKnownDetails字符串导出时的显示名称或电子邮件地址
备注:

系统有意将lastDisabledAt (监管禁用时间戳)从导出中排除——它是一个内部时间戳,对于重新导入的项目没有任何意义。

规则和约束

  1. 所有 ID 都必须是唯一的有效 GUID。不要在相同或不同类型的对象之间重复使用 ID。

  2. 必须解析交叉引用。测试步骤或分配中的testCaseId必须引用同一包中存在的测试用例id

  3. 包装器对象为必需。即使集合只有一个项目,也必须将其换行: { "testCases": [ {...} ] } ,而非纯数组或对象。

  4. null""约定: null真正不存在的可选字段(例如automationIdinputParamspreConditionconnectorTestCaseId以及手动测试用例上的所有package*字段)。""仅用于始终以字符串形式呈现但正好为空的字段(例如foreignRefdescriptionclipboardData )。混合使用这两种方法 — 尤其是在需要""的情况下使用null — 可能会导致静默导入失败。

  5. 清单文件中的objectCountDetails应与存在的对象的实际计数相符,但导入程序不会严格验证计数 — 不匹配只会影响导入前摘要的显示。

  6. 所有文件都必须使用不带 BOM 的 UTF-8 编码

最小有效 TMH 文件(手动编制)

Test Manager 接受的最小有效.tmh文件仅包含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"
}

所有objects/子目录都是可选的。导入程序会静默跳过存档中未包含的任何对象类型。

此页面有帮助吗?

连接

需要帮助? 支持

想要了解详细内容? UiPath Academy

有问题? UiPath 论坛

保持更新