Java 在UI和restApi之间创建缺陷时存在差异

Java 在UI和restApi之间创建缺陷时存在差异,java,rally,defects,Java,Rally,Defects,当我在UI上创建缺陷时,我不能只将其分配给测试用例,用户故事将自动分配。如果我试图删除用户故事,测试用例也会消失 但是通过restApi,我只能涉及到测试用例,而没有提到用户故事 我认为这是一个bug,因为无论如何创建缺陷,行为都应该相似 我没有提到这一点,但我们一直都有与用户故事相关的测试用例 可以通过API和UI将缺陷与用户故事和测试用例相关联。但是在一种特殊情况下,当您首先将一个故事关联到一个测试用例,然后将一个缺陷关联到这个故事,接下来,您单击缺陷的详细信息页面上的TestCase字段,

当我在UI上创建缺陷时,我不能只将其分配给测试用例,用户故事将自动分配。如果我试图删除用户故事,测试用例也会消失

但是通过restApi,我只能涉及到测试用例,而没有提到用户故事

我认为这是一个bug,因为无论如何创建缺陷,行为都应该相似


我没有提到这一点,但我们一直都有与用户故事相关的测试用例

可以通过API和UI将缺陷与用户故事和测试用例相关联。但是在一种特殊情况下,当您首先将一个故事关联到一个测试用例,然后将一个缺陷关联到这个故事,接下来,您单击缺陷的详细信息页面上的TestCase字段,它将显示选择器中的唯一选项-已经与故事关联的测试用例

接下来的内容令人困惑

有两种方法可以将测试用例与Rally UI中的缺陷关联起来:

使用详细信息页面上的“测试用例”字段

使用详细信息页面左侧的“测试用例”链接

这不仅允许在UI中使用不一致的实践,而且在用户检查WS-API请求的结果时也会造成混乱

假设一个现有的测试用例使用缺陷详细信息页面中的“测试用例”字段与一个缺陷相关联,然后一个新的测试用例使用左侧的“测试用例”链接与同一个缺陷相关联

此时,我们有两个与同一缺陷相关的独立测试用例:TC7和TC59

然而,当我们查询这个缺陷及其TestCases集合时,它只显示一个TestCase(在我的示例中为TC59),它是通过左侧的“TestCases”链接添加的

以下是获取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服务API创建一个新的测试用例,并将其与相同的缺陷DE19相关联。 重要提示:通过左侧的“测试用例”链接将新测试用例与缺陷关联的UI方法相当于WS-API中的以下POST请求

在本例中,“工作产品”:“/defect/12655123753”引用同一缺陷的ObjectID

请求URL:

https://rally1.rallydev.com/slm/webservice/v2.0/testcase/create?key=7b193d4b....
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-.... 
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-.... 
有效载荷:

{ 
"TestCase":{ 
"Name": "some tc", 
"WorkProduct":"/defect/12655123753" 
} 
}
{"Defect":{ 
"TestCase":"/testcase/14604252931" 
} 
} 
{"Defect":{ 
"TestCase":"/testcase/14604252931" 
} 
} 
我们在UI中验证WS-API创建请求是否成功。 接下来,我们查询相同的TestCases集合,并如预期的那样看到两个结果。为了简洁起见,这次只取FormattedID。返回TC59和TC60

https://rally1.rallydev.com/slm/webservice/v2.0/Defect/12655123753/TestCases?fetch=FormattedID 
正如我们所看到的,通过缺陷详细信息页面上的“测试用例”字段在UI中创建的TC7不会被此查询返回。在Web服务API中,缺陷对象有两个与本文讨论相关的属性:TestCase和TestCase

此查询:

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将测试用例添加到缺陷的测试用例集合时,如何将测试用例与场景中的缺陷关联起来,我们希望找到一个API,它等效于将测试用例与缺陷与TestCase字段关联起来

我们将使用一个没有故事链接的缺陷,因为原始缺陷(在我的示例中是DE19)已经链接了一个US20。根据WS-API文档中关于缺陷的TestCase属性的说明,只需指定其中一个

注意与此缺陷相关的测试用例。可以指定需求或测试用例,但不能同时指定两者

我们将把ObjectID 14604252931引用的一个预先存在的测试用例添加到另一个缺陷DE81中,该缺陷由对象ID 14710889543引用:

请求URL:

https://rally1.rallydev.com/slm/webservice/v2.0/testcase/create?key=7b193d4b....
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-.... 
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-.... 
有效载荷:

{ 
"TestCase":{ 
"Name": "some tc", 
"WorkProduct":"/defect/12655123753" 
} 
}
{"Defect":{ 
"TestCase":"/testcase/14604252931" 
} 
} 
{"Defect":{ 
"TestCase":"/testcase/14604252931" 
} 
} 
注意,如果此时第二个缺陷DE81与UI中的随机故事相关联,那么与TestCase的关联将被删除,而不会出现任何错误或警告

现在这变得更加令人困惑。第一个缺陷的DE19详细信息页面,我们看到它与US20和TC7都有关联。似乎不可能使用细节页面上的“TestCase”字段将DE81与测试用例关联起来。单击放大镜图标时,选择器对话框为空。事实证明,将DE81与UserStory和TestCase关联的唯一方法是创建一个与UserStory关联的新TestCase

这两个步骤如下: A.将UserStory链接到测试用例 B返回缺陷并单击详细信息页面上的“测试用例”字段。这一次,将使用上面创建的新测试用例填充选择器对话框。 现在TestCase和UserStory都与此缺陷相关联

如果此时尝试用与UserStory无关的其他测试用例替换TC61,则会失败。如果通过API进行此尝试,如下所示:

请求URL:

https://rally1.rallydev.com/slm/webservice/v2.0/testcase/create?key=7b193d4b....
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-.... 
https://rally1.rallydev.com/slm/webservice/v2.0/defect/14710889543?key=7b193d4b-.... 
有效载荷:

{ 
"TestCase":{ 
"Name": "some tc", 
"WorkProduct":"/defect/12655123753" 
} 
}
{"Defect":{ 
"TestCase":"/testcase/14604252931" 
} 
} 
{"Defect":{ 
"TestCase":"/testcase/14604252931" 
} 
} 
这将导致以下错误:

{"OperationResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Validation error: Defect.TestCase is an invalid relationship "], "Warnings": []}}
更新关于Stella评论中描述的案例:

在UI中创建了一个UserStory,称为StoryG /用户故事/17824476422

通过详细信息页面左侧的TestCases链接将新的TestCase与之关联。 /测试用例/17824476889

现在,这个测试用例通过用户故事上的TestCases集合与故事相关联

接下来,通过API创建一个缺陷:

https://rally1.rallydev.com/slm/webservice/v2.0/defect/create?key=733c0893-0e5b-4c66-8204-9a2afa548d36
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"
}
}
{"Defect":{ 
"Name":"Bug with StoryH",
"Requirement":"/hierarchicalrequirement/17824480704",
"TestCase":"/testcase/17824638756"
}
}
{"Defect":{ 
"Name":"Bug with TC77",
"TestCase":"/testcase/17866645137"
}
}
这是可行的:新缺陷与UserStory和TestCase都关联。 事实上,这与UI是一致的。当使用API时,负载中必须引用
需求
测试用例
。在UI中创建缺陷时,必须同时指定这两种缺陷:请参见响应的第一段。选择测试用例时,测试用例选择器只显示一个选项:已经与UserStory关联的测试用例

下面是一个场景