Rally如何将为测试集运行的所有测试用例导出为CSV

时间:2014-07-08 04:36:00

标签: rally

我们希望从先前的迭代/测试集中获取一些测试用例,并将它们导入到新的测试集中。问题是我们无法将测试用例中的测试用例导出为CSV或任何其他数据格式,因为我们得到的只是一个可打印的报告。我们还尝试将可打印报告复制并粘贴到MS Excel中,但它没有提供数据格式。

可以使用的任何建议/ HTML表单。

2 个答案:

答案 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脚本环境,并且熟悉在命令行配置/运行脚本。但是,结合起来,这些应该足以实现您的目标。