我们希望从先前的迭代/测试集中获取一些测试用例,并将它们导入到新的测试集中。问题是我们无法将测试用例中的测试用例导出为CSV或任何其他数据格式,因为我们得到的只是一个可打印的报告。我们还尝试将可打印报告复制并粘贴到MS Excel中,但它没有提供数据格式。
可以使用的任何建议/ HTML表单。
答案 0 :(得分:1)
可以在Rally UI中复制TestSet,并且该功能允许重用成员测试用例从迭代到迭代或从发布到发布。复制测试集时,它们会保留成员测试用例,包括测试步骤。 Rally建议使用此方法来处理测试。如果重复使用相同的测试,请直接在Rally UI中将包含它们的测试集复制到新的迭代中。这会重置该迭代的结果,并使您不会复制测试用例。
Mark的Ruby工具提供了一种替代方案,允许选择性地复制成员测试用例 - 在UI中复制测试集时不会发生这种情况。
以下是使用AppSDK2的javascript示例。你当然可以进一步定制它。此示例的要点是说明如何使用AppSDK2更新集合。 用户可以选择"来源"从迭代组合框迭代,然后使用为此迭代计划的测试集填充测试组合框。接下来,用户可以从第三个组合框选择目标迭代,将迭代限制为当前和未来的迭代,并创建一个为"目的地"安排的新测试集。迭代。来自"来源"的测试用例testset被复制到新的testset。
如果应用程序在Rally之外运行,目前更新集合将无效,但此限制将很快得到纠正。只要使用rab run
命令,它将允许使用CORS在集会之外进行集合更新。下面的代码现在可以在Rally中使用。部署html可从this github repo获得。
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
fieldLabel: 'Select a source Iteration',
labelWidth: 150,
width: 350
},
onScopeChange: function() {
if (!this.down('#parentPanel')) {
this._panel = Ext.create('Ext.panel.Panel', {
layout: 'hbox',
itemId: 'parentPanel',
componentCls: 'panel',
items: [
{
xtype: 'container',
itemId: 'pickerContainer',
},
{
xtype: 'container',
itemId: 'iterationContainer',
}
]
});
this.add(this._panel);
}
if (this.down('#testSetComboxBox')) {
this.down('#testSetComboxBox').destroy();
}
var testSetComboxBox = Ext.create('Rally.ui.combobox.ComboBox',{
itemId: 'testSetComboxBox',
storeConfig: {
model: 'TestSet',
limit: Infinity,
pageSize: 100,
autoLoad: true,
filters: [this.getContext().getTimeboxScope().getQueryFilter()]
},
fieldLabel: 'Select a TestSet',
listeners:{
ready: function(combobox){
if (combobox.getRecord()) {
this._onTestSetSelected(combobox.getRecord());
}
else{
console.log('selected iteration has no testsets');
}
},
select: function(combobox){
if (combobox.getRecord()) {
this._onTestSetSelected(combobox.getRecord());
}
},
scope: this
}
});
this.down('#pickerContainer').add(testSetComboxBox);
},
_onTestSetSelected:function(testset){
var id = testset.get('ObjectID');
this._name = testset.get('Name');
testset.self.load(id, {
fetch: ['Name','TestCases'],
callback: this._onSourceRecordRead,
scope: this
});
},
_onSourceRecordRead: function(record) {
var that = this;
that._testcases = [];
var testcaseStore = record.getCollection('TestCases',{fetch:['Name','FormattedID']});
testcaseStore.load({
callback: function() {
_.each(testcaseStore.getRange(), function(tc){
that._testcases.push(tc.data._ref);
});
console.log(that._testcases);
that._selectFutureIteration();
}
});
},
_selectFutureIteration: function(){
if (!this.down('#iterationComboxBox')) {
var iterationComboxBox = Ext.create('Rally.ui.combobox.ComboBox',{
itemId: 'iterationComboxBox',
storeConfig: {
model: 'Iteration',
limit: Infinity,
pageSize: 100,
autoLoad: true,
filters: [
{
property: 'StartDate',
operator: '>=',
value: (new Date()).toISOString()
}
]
},
fieldLabel: 'Select a destination Iteration',
labelWidth: 150,
listeners:{
ready: function(combobox){
if (combobox.getRecord()) {
this._onFutureIterationSelected(combobox.getRecord());
}
else{
console.log('no current or future iterations');
}
},
select: function(combobox){
if (combobox.getRecord()) {
this._onFutureIterationSelected(combobox.getRecord());
}
},
scope: this
}
});
this.down('#iterationContainer').add(iterationComboxBox);
}
},
_onFutureIterationSelected:function(iteration){
var that = this;
that._iteration = iteration.data._ref;
if (!this.down('#create')) {
var createButton = Ext.create('Ext.Container', {
items: [
{
xtype : 'rallybutton',
text : 'create a testset',
itemId: 'create',
handler: function() {
that._createTestSet();
}
}
]
});
this.add(createButton);
}
},
_createTestSet: function(){
var that = this;
console.log('create testset scheduled for ', that._iteration);
Rally.data.ModelFactory.getModel({
type: 'TestSet',
success: function(model) {
that._model = model;
var ts = Ext.create(model, {
Name: that._name + 'Copy',
Iteration: that._iteration
});
ts.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log(result.get('Name'), ' ', result.get('Iteration')._refObjectName);
that._readRecord(result);
}
else{
console.log("?");
}
}
});
}
});
},
_readRecord: function(result) {
var id = result.get('ObjectID');
this._model.load(id, {
fetch: ['Name','TestCases'],
callback: this._onRecordRead(result),
scope: this
});
},
_onRecordRead: function(record, operation) {
console.log('There are ', record.get('TestCases').Count, ' in ', record.get('Name') );
var that = this;
var testcaseStore = record.getCollection('TestCases');
testcaseStore.load({
callback: function() {
testcaseStore.add(that._testcases);
testcaseStore.sync({
callback: function() {
console.log('success');
}
});
}
});
}
});
答案 1 :(得分:0)
有几个Ruby脚本可以帮到你:
这些确实需要一个有效的Ruby脚本环境,并且熟悉在命令行配置/运行脚本。但是,结合起来,这些应该足以实现您的目标。