当我在 UI 上创建缺陷时,我不能只将其分配给测试用例,用户故事会自动分配。如果我尝试删除用户故事,测试用例也会消失。
但是通过restApi,我只能涉及到测试用例,而没有提到用户故事。
我认为这是一个错误,因为无论您如何创建缺陷,行为都应该相似。
我没有提到它,但我们总是有与用户故事相关的测试用例。
可以通过 API 和 UI 将缺陷与用户故事和测试用例相关联。但是这种情况发生在一个特殊情况下,当您首先将故事与测试用例相关联,然后将缺陷与该故事相关联,然后单击缺陷详细信息页面上的 TestCase 字段,它将在选择器中显示唯一的选项- 已经与故事相关联的测试用例。
接下来的内容令人困惑。
有两种方法可以将测试用例与 Rally UI 中的缺陷相关联:
使用详细信息页面上的“测试用例”字段
使用详细信息页面左侧的“测试用例”链接
这不仅会导致 UI 中出现不一致的做法,而且还会在用户检查 WS API 请求的结果时造成混乱。
假设使用缺陷详细信息页面上的“测试用例”字段将现有的测试用例与缺陷相关联,然后使用左侧的“测试用例”链接将新的测试用例与相同的缺陷相关联。
此时,我们有两个与同一个缺陷相关联的独立测试用例:TC7 和 TC59。
然而,当我们查询这个 Defect 及其 TestCases 集合时,它只显示一个 TestCase(在我的示例中为 TC59),它是通过左侧的“Test Cases”链接添加的。
这是获取 TestCases 集合的第一个查询:
https://rally1.rallydev.com/slm/webservice/v2.0/defect?workspace=https://rally1.rallydev.com/slm/webservice/v2.0/workspace/1111&query=(FormattedID%20%3D%20DE19)&fetch=TestCases
第一个查询返回的结果:
{
QueryResult: {
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
Errors: [ ],
Warnings: [ ],
TotalResultCount: 1,
StartIndex: 1,
PageSize: 20,
Results: [
{
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
_ref: "https://rally1.rallydev.com/slm/webservice/v2.0/defect/12655123753",
_refObjectUUID: "91f66a35-d860-41e0-a10d-db6dad460f28",
_objectVersion: "7",
_refObjectName: "Error found in US20: story C2",
TestCases: {
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
_ref: "https://rally1.rallydev.com/slm/webservice/v2.0/Defect/12655123753/TestCases",
_type: "TestCase",
Count: 1
},
_type: "Defect"
}
]
}
}
使用我们从第一个查询的结果中获得的 TestCases 集合的 URI,我们运行另一个查询来检查集合本身,为简洁起见仅获取 FormattedID 和 WorkProduct:
https://rally1.rallydev.com/slm/webservice/v2.0/Defect/12655123753/TestCases?fetch=FormattedID,WorkProduct
结果仅包括 TC59:
https://rally1.rallydev.com/slm/webservice/v2.0/Defect/12655123753/TestCases?fetch=FormattedID,WorkProduct
{
QueryResult: {
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
Errors: [ ],
Warnings: [ ],
TotalResultCount: 1,
StartIndex: 1,
PageSize: 20,
Results: [
{
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
_ref: "https://rally1.rallydev.com/slm/webservice/v2.0/testcase/17593081118",
_refObjectUUID: "dbdbd621-97f7-4c27-b24a-f0ca92be73ff",
_objectVersion: "1",
_refObjectName: "Error found in US20: story C2",
FormattedID: "TC59",
WorkProduct: {
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
_ref: "https://rally1.rallydev.com/slm/webservice/v2.0/defect/12655123753",
_refObjectUUID: "91f66a35-d860-41e0-a10d-db6dad460f28",
_objectVersion: "7",
_refObjectName: "Error found in US20: story C2",
FormattedID: "DE19",
_type: "Defect"
},
_type: "TestCase"
}
]
}
}
接下来,我们要通过 Web Services API 创建一个新的 TestCase 并将其与相同的 Defect DE19 关联。重要提示:通过左侧的“测试用例”链接将新的测试用例关联到缺陷的 UI 方法等效于 WS API 中的以下 POST 请求。
在此示例中,“WorkProduct”:“/defect/12655123753”引用了同一缺陷的 ObjectID。
请求网址:
https://rally1.rallydev.com/slm/webservice/v2.0/testcase/create?key=7b193d4b....
有效载荷:
{
"TestCase":{
"Name": "some tc",
"WorkProduct":"/defect/12655123753"
}
}
我们在 UI 中验证 WS API 创建请求是否成功。接下来,我们查询相同的 TestCases 集合并看到两个结果,正如预期的那样。为简洁起见,这次仅获取 FormattedID。TC59 和 TC60 被退回。
https://rally1.rallydev.com/slm/webservice/v2.0/Defect/12655123753/TestCases?fetch=FormattedID
如我们所见,此查询未返回通过缺陷详细信息页面上的“测试用例”字段在 UI 中创建的 TC7。在 Web 服务 API 中,Defect 对象有两个与此讨论相关的属性:TestCase 和 TestCases。
这个查询:
https://rally1.rallydev.com/slm/webservice/v2.0/defect?workspace=https://rally1.rallydev.com/slm/webservice/v2.0/workspace/1111&query=(FormattedID%20%3D%20DE19)&fetch=TestCase,FormattedID
返回 TC7:
{
QueryResult: {
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
Errors: [ ],
Warnings: [ ],
TotalResultCount: 1,
StartIndex: 1,
PageSize: 20,
Results: [
{
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
_ref: "https://rally1.rallydev.com/slm/webservice/v2.0/defect/12655123753",
_refObjectUUID: "91f66a35-d860-41e0-a10d-db6dad460f28",
_objectVersion: "9",
_refObjectName: "Error found in US20: story C2",
FormattedID: "DE19",
TestCase: {
_rallyAPIMajor: "2",
_rallyAPIMinor: "0",
_ref: "https://rally1.rallydev.com/slm/webservice/v2.0/testcase/12476557645",
_refObjectUUID: "a8d50053-e250-43c1-aebc-58472fec2988",
_objectVersion: "10",
_refObjectName: "myTS3",
FormattedID: "TC7",
_type: "TestCase"
},
_type: "Defect"
}
]
}
}
既然我们知道了如何在通过 UI 和 WS API 将 TestCase 添加到 Defect 的 TestCases 集合的场景中将 TestCase 关联到 Defect,我们希望找到一个 API 等效于将 TestCase 与带有 TestCase 字段的 Defect 关联。
我们将使用一个没有故事链接的缺陷,因为原始缺陷(在我的示例中为 DE19)已经链接了一个 US20。根据 WS API 文档中关于 Defect 的 TestCase 属性的注释,只需指定其中一个。
注意 此缺陷所涉及的测试用例。可以指定 Requirement 或 TestCase,但不能同时指定两者。
我们将添加一个由 ObjectID 14604252931 引用的预先存在的 TestCase 到另一个由 Object ID 14710889543 引用的缺陷 DE81:
请求网址:
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-....
有效载荷:
{"Defect":{
"TestCase":"/testcase/14604252931"
}
}
请注意,如果此时第二个 Defect DE81 与 UI 中的随机故事相关联,则与 TestCase 的关联将被删除,而不会出现任何错误或警告。
现在这变得更加混乱。我们看到第一个 Defect 的 DE19 详细信息页面同时关联了 US20 和 TC7。使用详细信息页面上的“测试用例”字段将 DE81 与测试用例相关联似乎是不可能的。当我们点击放大镜图标时,选择器对话框是空的。事实证明,将 DE81 关联到 UserStory 和 TestCase 的唯一方法是创建一个与 UserStory 关联的新 TestCase。
这两个步骤如下: a.将 UserStory 链接到 TestCase b. 返回缺陷并单击详细信息页面上的“测试用例”字段。这次选择器对话框将填充上面创建的新测试用例。现在 TestCase 和 UserStory 都与这个缺陷相关联。
如果此时尝试将 TC61 替换为与 UserStory 无关的其他 TestCase,它将失败。如果通过 API 进行此尝试,如下所示:
请求网址:
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-....
有效载荷:
{"Defect":{
"TestCase":"/testcase/14604252931"
}
}
这将导致此错误:
{"OperationResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Validation error: Defect.TestCase is an invalid relationship "], "Warnings": []}}
更新回复:Stella评论中描述的案例:
在 UI 中创建了一个 UserStory,命名为 StoryG /userstory/17824476422
通过详细信息页面左侧的 TestCases 链接将新的 TestCase 与其关联。/testcase/17824476889
现在这个 TestCase 通过用户故事上的 TestCases 集合与故事相关联。
接下来,通过 API 创建一个缺陷:
https://rally1.rallydev.com/slm/webservice/v2.0/defect/create?key=733c0893-0e5b-4c66-8204-9a2afa548d36
有效载荷:
{"Defect":{
"Name":"Bug with StoryG",
"Requirement":"/hierarchicalrequirement/17824476422",
"TestCase":"/testcase/17824476889"
}
}
这有效:新缺陷与 UserStory 和 TestCase 相关联。事实上,这与 UI 是一致的。使用 API 时Requirement
,TestCase
必须在有效负载中引用 the 和 。并且在 UI 中创建缺陷时,都必须指定:请参阅响应的第一段。选择测试柜时,测试柜选择器仅显示一个选项:已经与Userstory关联的测试柜。
下面是一个不起作用的场景,它在 API 和 UI 之间是一致的。让我们看看如果我尝试将不相关的 UserStory 和 TestCase 链接到缺陷会发生什么
创建了一个用户故事,StoryH /userstory/17824480704
通过详细信息页面左侧的 TestCases 链接将新的 TestCase 与其关联。/testcase/17824481042
现在这个 TestCase 通过用户故事上的 TestCases 集合与故事相关联。
接下来,我在创建缺陷时引用了不相关的TestCase:/testcase/17824638756
https://rally1.rallydev.com/slm/webservice/v2.0/defect/create?key=733c0893-0e5b-4c66-8204-9a2afa548d36
有效载荷:
{"Defect":{
"Name":"Bug with StoryH",
"Requirement":"/hierarchicalrequirement/17824480704",
"TestCase":"/testcase/17824638756"
}
}
这将返回错误,如预期的那样,并且与 UI 一致:
{"CreateResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Validation error: Defect.TestCase is an invalid relationship "], "Warnings": []}}
还有另一种方法可以关联这个缺陷-用户故事-测试用例三角形的所有成员。 在这里可以观察到 UI 和 API 之间的差异:
在用户界面中:
a) 使用故事详细信息页面左侧的 TestCases 链接将用户故事与测试用例相关联 b) 创建新缺陷,使用缺陷详细信息页面上的测试用例字段将其与测试用例相关联。
从测试用例选择器中选择测试用例后,故事会自动显示。
在 API 中:
a) 使用故事详细信息页面左侧的 TestCases 链接将用户故事与测试用例关联 b) 使用浏览器的 REST 客户端创建缺陷,同时设置其 TestCase 字段,并期望故事自动链接。
https://rally1.rallydev.com/slm/webservice/v2.0/defect/create?key=5e10c58...
有效载荷:
{"Defect":{
"Name":"Bug with TC77",
"TestCase":"/testcase/17866645137"
}
}
测试用例详细信息页面左侧的 Defects(1) 链接显示了新创建的缺陷。然而,缺陷的详细信息页面并没有显示故事。我已经提交了一个错误。
回顾一下这个三角形,它出现在 WS API 中:
缺陷 - 此工件可以通过 Requirement 属性引用 UserStory,并通过 TestCase 属性引用 TestCase。每个 WSAPI 文档说它可以有一个或另一个,但不能两者兼有。在链接这三个工件时,它们都必须是一致的。如果一个缺陷被定义为指向一个用户故事和一个测试用例,那么这两个也必须相互指向,这实际上是非此即彼规则的一个例外。Defect 上的 TestCase 属性与 Defect 上的 TestCase 集合完全分开。
UserStory - 这个工件有 TestCases 集合和 Defect 集合。
TestCase - 这个工件可以有一个通过 WorkProduct 属性指向 Requirement(它是一个 UserStory)的指针。