2

我们决定将 Sencha ExtJS 用于我们新产品的客户端,并计划在客户端进行自动化功能测试。我们研究了几种工具,如 Ranorex、Selenium、Telerik Test Studio 等,到目前为止,我们比其他工具更喜欢 Test Studio。无论如何,无论使用哪种工具,我要问的问题都是相关的。

我很想知道获取 extjs 控件的内部元素的推荐方法是什么。为了清楚起见,我将举一个例子。

我有一个数字字段控件,我想测试一下,如果我单击“向上”按钮,字段中的值将增加一个单位。请注意,我确实为数字字段 (id="testDurationHourNumberField") 设置了唯一 ID。number 字段具有以下(简化的)DOM 结构:

<table id="testDurationHourNumberField">
<tbody>
    <tr id="testDurationHourNumberField-inputRow">
        <td id="testDurationHourNumberField-labelCell">
            <label id="testDurationHourNumberField-labelEl">Label:</label>
        </td>
        <td id="testDurationHourNumberField-bodyEl">
            <table id="testDurationHourNumberField-triggerWrap">
                <tbody>
                    <tr>
                        <td id="testDurationHourNumberField-inputCell">
                            <input id="testDurationHourNumberField-inputEl">
                        </td>
                        <td>
                            <div role="button" id="ext-gen1211"></div>
                            <div role="button" id="ext-gen1212"></div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>
</tbody>
</table>

为此,我必须访问输入元素 (id="testDurationHourNumberField-inputEl") 和按钮 (id="ext-gen1211")。访问这两个元素的推荐方式是什么?

到目前为止,我有以下选择:

  • 使用 ExtJS 内部 ID - 看起来不太好,因为:
    • 这些是内部 ID,它们不受我的控制,如果我稍后在页面上添加另一个控件,它们可能会改变
    • 似乎对于同一页面,我在不同的浏览器中获得了不同的 ID。例如,在 IE 10 中,我从 Google Chrome 中获得的 ID 中获得了不同的按钮 ID。
  • 通过唯一 ID 获取控件并通过了解其内部 DOM 结构或属性来获取内部元素 - 似乎不好,因为:
    • 我宁愿不使用这种方式,因为我不知道当升级到 ExtJS 的下一个版本时,内部 DOM 结构不会改变或某些属性名称会改变,我将不得不更新我创建的测试
    • 例如伪代码:getById('testDurationHourNumberField').getElementByAttributeAndIndex('role=button', 0)

你能告诉我推荐的方法是什么吗?

谢谢,
保罗

4

3 回答 3

2

这就是我在我的项目中的做法:

it("should increment the control value", function () {
    var ctrl = Ext.ComponentQuery.query('#age')[0],
        upBtn = Ext.ComponentQuery.query('#upButton')[0],
        curValue = ctrl.getValue();

    upBtn.fireEvent('click');

    expect(ctrl.getValue()).toEqual(curValue + 1);
});

我用茉莉花。

更新:

对于功能测试,您应该阅读以下内容:

  1. 在浏览器中测试 extjs 代码有什么建议,最好是使用 selenium? 还有这个:
  2. http://www.sencha.com/blog/testing-ext-js-ext-gwt-applications-with-selenium
于 2012-12-18T14:59:50.890 回答
1

我知道已经有一段时间了,但我会在这里写下我们决定如何解决这个问题。对于功能测试,我们使用 Telerik TestStudio,为了获取内部元素,我们使用 GetById 方法,其中每个组件的每个 ID 都必须是唯一的。这种方法的主要问题是自动生成的 ID:

  • 内部组件的 ID 会根据浏览器获得不同的值
  • 内部组件的 ID 可能会在 ExtJs 升级时发生变化
  • 在页面上添加其他组件时,内部组件的 ID 可能会发生变化(这种情况经常发生)

为了解决这个问题,我们实现了 ExtJS 类的补丁,以确保内部元素的 ID 是唯一的。

对于我的问题中的数字字段示例,我们已经实现了以下补丁,以确保数字字段的按钮具有在不同浏览器上不会更改的唯一 ID。

Ext.define('Waf.patch.extJS411.form.field.Spinner', {
    override: 'Ext.form.field.Spinner',

    getTriggerMarkup: function() {
        var me = this,
            hideTrigger = (me.readOnly || me.hideTrigger);

        me.triggerTpl = '<td style="{triggerStyle}">' +
            '<div class="' + Ext.baseCSSPrefix + 'trigger-index-0 ' + Ext.baseCSSPrefix + 'form-trigger ' + Ext.baseCSSPrefix + 'form-spinner-up"' + 'id="' + me.id + '-buttonUp"' + ' role="button"></div>' +
            '<div class="' + Ext.baseCSSPrefix + 'trigger-index-1 ' + Ext.baseCSSPrefix + 'form-trigger ' + Ext.baseCSSPrefix + 'form-spinner-down"' + 'id="' + me.id + '-buttonDown"' + ' role="button"></div>' +
            '</td>' +
            '</tr>';

        return me.getTpl('triggerTpl').apply({
            triggerStyle: 'width:' + me.triggerWidth + (hideTrigger ? 'px;display:none' : 'px')
        });
    }
});

我们还为遇到此问题的其他类实施了补丁,因此我们涵盖了大部分用例。补丁不多:

  • Ext.form.field.Spinner
  • Ext.form.field.Trigger
  • 扩展面板
  • Ext.view.BoundList
  • Ext.window.MessageBox

问候,保罗

于 2013-05-15T15:55:00.010 回答
0

您可能想查看自动化功能 GUI 测试工具RIATest

ExtJS UI 小部件是 RIATest 中的一等公民。这意味着,与其他 HTML 测试工具不同,当您实际需要使用 ExtJS 组件时,您不需要编写操作 HTML DOM 元素的测试。

RIATest 知道如何忽略 ExtJS 动态生成的 id,但是如果您手动为组件分配 id,该工具使用它们进行识别(参见下面示例中的 #tree2)。

RIATest 中的测试根据 ExtJS UI 小部件运行。

使用 ExtJS 小部件的 RIATest 脚本示例:

以下点击带有标签“下一页”的 ExtJS 按钮:

ExtButton("Next Page")=>click();

以下内容将一行从一个 ExtJS 树拖放到另一棵树:

ExtRow("Controller.js")=>dragAndDropTo(
    ExtTreePanel("#tree2")->ExtRow("Custom Ext JS"));

这会折叠 ExtJS 框的标题:

ExtBox("Feeds")->ExtHeader("FeedsВ")->ExtCollapser()=>click();

(以上所有示例代码均来自在 ExtJS 示例应用程序上运行的真实测试脚本)。

RIATest 还知道何时自动等待 ExtJS AJAX 完成,因此如果您的 UI 进行动态内容下载,测试将自动神奇地等待,直到从服务器接收到数据。

(免责声明:我是 RIATest 团队成员)。

于 2013-01-30T05:39:11.380 回答