文档帮助

术语、图标和标签

许多类都有在使用配置对象创建(实例化)类时使用的快捷名称。快捷名称称为别名(如果类扩展 Ext.Component,则称为xtype)。对于可应用的类,别名/xtype 会列在类名称旁边,以便快速参考。

访问级别

框架类或其成员可以指定为私有受保护。否则,类/成员为公共公共受保护私有是访问描述符,用于传达如何以及何时应该使用类或类成员。

成员类型

成员语法

下面是一个示例类成员,我们可以对其进行剖析以显示类成员的语法(在本例中,是从 Ext.button.Button 类查看的 lookupComponent 方法)。

lookupComponent ( item ) : Ext.Component
受保护

在将原始配置对象添加到此容器中时调用,这可能发生在初始化items配置期间,或在添加新项目时(added)或 {@link #insert inserted}。

此方法将传递的对象转换为实例化子组件。

在需要对子创建应用特殊处理时,可在子类中覆盖此方法。

参数

item :  对象

要添加的配置对象。

返回
Ext.Component

要添加的组件。

我们来看看成员行中的每一部分

成员标志

API 文档使用许多标志来进一步传达类成员的功能和意图。标签可以用文本标签、缩写或图标表示。

类图标

- 表示框架类

- 单例框架类。*有关详细信息,请参阅单例标志

- 组件类型框架类(Ext JS 框架中任何扩展 Ext.Component 的类)

- 表示类、成员或指南在当前查看的版本中是新的

成员图标

- 表示类型为 config 的类成员

- 表示类型为 property 的类成员

- 表示类型为 method 的类成员

- 表示类型为 event 的类成员

- 表示类型为 theme variable 的类成员

- 表示类型为 theme mixin 的类成员

- 表示类、成员或指南在当前查看的版本中是新的

类成员快速导航菜单

在 API 文档页面上类名称正下方是一行按钮,对应于当前类拥有的成员类型。每个按钮按类型显示成员数(此计数在应用筛选器时更新)。单击按钮将导航到该成员部分。将鼠标悬停在成员类型按钮上将显示一个弹出菜单,其中包含该类型的所有成员,以便快速导航。

Getter 和 Setter 方法

与类配置选项相关的 Getter 和 Setter 方法将显示在方法部分以及 API 文档和成员类型菜单的配置部分中,它们与之一起工作的配置正下方。Getter 和 Setter 方法文档将位于配置行中,以便于参考。

历史记录栏

您的页面历史记录保存在本地存储中,并显示在顶部标题栏正下方(使用可用空间)。默认情况下,仅显示与您当前正在查看的产品/版本匹配的搜索结果。您可以通过单击历史记录栏右侧的 按钮并选择“全部”单选选项来扩展显示内容。这将在历史记录栏中显示所有产品/版本的所有近期页面。

在历史记录配置菜单中,您还将看到最近访问的页面列表。结果按“当前产品/版本”和“全部”单选选项进行筛选。单击 按钮将清除历史记录栏以及本地存储中保存的历史记录。

如果在历史记录配置菜单中选择“全部”,则将启用“在历史记录栏中显示产品详细信息”复选框选项。选中后,每个历史页面的产品/版本将与历史记录栏中的页面名称一起显示。将光标悬停在历史记录栏中的页面名称上也将以工具提示的形式显示产品/版本。

搜索和筛选器

可以使用页面顶部的搜索字段搜索 API 文档和指南。

在 API 文档页面上,还有一个筛选器输入字段,它使用筛选器字符串筛选成员行。除了按字符串筛选外,您还可以按访问级别、继承和只读筛选类成员。这是使用页面顶部的复选框完成的。

API 类导航树底部的复选框筛选类列表以包括或排除私有类。

单击空搜索字段将显示您最近 10 次搜索,以便快速导航。

API 文档类元数据

每个 API 文档页面(Javascript 基本类型页面除外)都有一个与该类相关的元数据的菜单视图。此元数据视图将包含以下一个或多个

展开和折叠示例和类成员

可运行示例(Fiddle)默认在页面上展开。你可以使用代码块左上角的箭头单独折叠和展开示例代码块。你还可以使用页面右上角的切换按钮切换所有示例的折叠状态。切换所有状态将在页面加载之间记住。

类成员默认在页面上折叠。你可以使用成员行左侧的箭头图标展开和折叠成员,或全局使用右上角的展开/折叠所有切换按钮。

桌面 -vs- 移动视图

在较窄的屏幕或浏览器上查看文档将导致针对较小尺寸优化视图。桌面和“移动”视图之间的主要区别是

查看类源

可以通过单击 API 文档页面顶部的类名来查看类源。可以通过单击成员行右侧的“查看源”链接来查看类成员的源。

WebTestIt


顶部

快速入门:创建你的第一个测试

本教程帮助你使用 Sencha WebTestIt 创建你的第一个 UI 测试。你将逐步自动化我们的 Demoshop 示例的部分内容,并且你可以按照本教程创建所有源文件

本教程的资源以 TypeScript、Java 和 Python 提供。

项目结构

如果你尚未创建新项目,请按照以下说明进行操作

  1. 单击欢迎选项卡上的新建项目链接,或转到文件 > 新建项目

  2. 新建项目对话框中,为你的项目指定一个名称和位置,然后选择你想要使用的脚本语言。

  3. 单击保存后,Sencha WebTestIt 将创建你的项目并设置运行测试所需的组件。

注意

你选择的编程语言定义了为你设置的自动化框架。如果你选择 TypeScript,Sencha WebTestIt 将为你生成一个 Protractor 环境。如果你选择 Java,则会设置一个 TestNg 应用程序。如果你选择 Python,Sencha WebTestIt 将生成一个 unittest 环境。

你可以在项目选项卡中检查新生成项目的结构。Sencha WebTestIt 自动为你的测试套件和页面对象创建文件夹。你可以在项目的根目录中看到的用于配置你的测试和设置你的环境以运行它的文件。项目中值得注意的配置文件如下

文件名 说明
.editorconfig 包含 Sencha WebTestIt 代码编辑器的代码样式设置。 在此处了解有关 editorconfig 设置的更多信息
*.endpoints.json 存储有关将执行测试的端点的信息。 单击此处以阅读有关端点的更多信息
webtestit.json 包含 Sencha WebTestIt 测试项目的特定项目选项。
此处定义的所有设置都限定于单个项目,而不是全局设置,你可以通过主菜单文件 > 首选项 > 用户设置访问全局设置

分析待测网站 (SUT)

在本教程中,我们将自动化 Demoshop。你可以在 此处 找到它。继续,看看它。

Demoshop 的主页包含不同的部分

1 带有菜单和搜索字段的头区域

2 列出产品的正文区域

Demoshop 包含其他各种页面。对于本教程,搜索产品并将其添加到购物车。让我们创建一些测试用例,然后对其进行自动化

# 标题 说明
1 搜索项目 假设显示了 Demoshop
当用户输入“Super”作为搜索项目并按 Enter 键时
然后显示“Super Cool Goo”的详细信息页面
并且产品名称等于“Super Cool Goo”
并且价格等于 1,500.00 欧元
2 将项目添加到购物车 假设显示了“Super Cool Goo”的详细信息页面
当用户单击“添加到购物车”按钮时
然后显示确认消息
并且项目计数器显示 1
并且购物车区域中的小计等于产品的价格

提示

测试用例说明使用 Gherkin 语法. 这是定义测试用例的一种简单方法。每条语句都包含这三个关键词

  • GIVEN 描述当前状态,也称为前提条件
  • WHEN 描述用户的操作
  • THEN 描述这些操作的结果,也称为断言

这些关键词的组合称为场景。你可以使用逻辑运算符 (and/or) 将任何块中的多个语句链接起来以创建更复杂的场景。

在设计测试用例时,你只描述应用程序的预期行为。任何偏离此行为都是意外的,因此会被视为测试失败。

现在,让我们使用 Sencha WebTestIt 自动化这些测试用例!

创建页面对象

要访问测试用例所需的所有元素,你需要为它们创建选择器。选择器被组织到页面对象中。你可以 在此处 阅读有关选择器的更多信息。

由于你还没有任何页面对象文件,因此你需要创建一个

注意

页面对象不仅包含选择器,还包含模拟的用户输入。事实上,强烈建议仅向各个测试用例公开页面对象操作。 这称为页面对象模式,在此处进行了描述

  1. 单击项目树工具栏中的新建页面对象文件。Sencha WebTestIt 在项目的pageobjects 文件夹中创建一个新文件,并提示你对其进行命名。

  2. 或者,右键单击pageobjects 文件夹并通过上下文菜单创建文件。命名该文件,如果你使用 TypeScript,则使用HeaderPo.ts,如果你使用 Java,则使用HeaderPo.java,如果你使用 Python,则需要使用蛇形大小写(下划线字符,字符之间没有空格),因此页面对象名称应为header_po.py

  3. 新创建的文件带有两个默认函数opengetTitle。页面对象包含 Demoshop 头部中所需的所有选择器和操作。

参考

为了实现更好的可维护性测试,分析网站或应用程序的结构并将其划分到页面对象中至关重要。您可以在本指南第 3 章中阅读有关页面对象的更多信息

现在,按照以下步骤为详情页创建另一个页面对象

  1. 右键单击项目选项卡中的pageobjects文件夹,然后从上下文菜单中选择新建 > 页面对象文件
  2. 如果您使用 TypeScript,请将新的页面对象命名为DetailPagePo.ts,如果您使用 Java,请将其命名为DetailPagePo.java。同样,由于我们在 Python 中使用蛇形命名法,因此将新的页面对象命名为detail_page_po.py

创建页面对象操作

设置好所有选择器后,您现在可以编写自动化框架将执行的一些操作。

让我们从搜索我们的 T 恤开始。在现实世界中,用户会单击搜索输入并输入搜索词。请记住,测试自动化本质上是模拟用户。这就是您将执行完全相同操作的原因。

  • 从项目的pageobjects文件夹中选择HeaderPo (header_po) 文件。
  • searchInput (_search_input) 拖动代码选项卡中。
  • 单击弹出菜单中的在元素中输入选项。
  • 将函数命名为insertSearchText (在 Python 中为insert_search_text)。

生成的函数是一种简单的结构,可以快速入门并节省您必须编写的代码量。

发送文本后,单击 ENTER 键开始搜索。为此,Sencha WebTestIt 会自动将sendKeys (send_keys) 参数添加到该函数。您的代码应如下所示

public void insertSearchText(String text) { this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.searchInput)).sendKeys(text, Keys.RETURN); } 
def insert_search_text(self, text): self.wait.until(EC.visibility_of_element_located(self._search_input)).send_keys(text) return self 
public async insertSearchText(text: string): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.searchInput)), browser.allScriptsTimeout, this.searchInput.toString()); await element(this.searchInput).sendKeys(text, Key.ENTER); return this; }

提示

生成的页面对象操作是从模板创建的。您可以根据网站或应用程序的要求自定义模板。阅读更多有关在本指南第 3 章中自定义模板的信息。

HeaderPo页面对象中剩余的元素中,您要获取文本。重复上述操作,但这次在弹出菜单中使用获取元素文本选项并返回文本字符串,或复制以下源代码以执行此操作。

public String getCartAmount() { return this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.cartAmount)).getText(); } public String getCartCount() { return this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.cartCount)).getText(); } 
def get_cart_amount(self): cart_count_count = self.wait.until(EC.visibility_of_element_located(self._cart_count)).text return cart_count_count def get_cart_count(self): cart_count_text = self.wait.until(EC.visibility_of_element_located(self._cart_count)).text return cart_count_text 
public async getCartAmount(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.cartAmount)), browser.allScriptsTimeout, this.cartAmount.toString()); return await element(this.cartAmount).getText(); } public async getCartCount(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.cartCount)), browser.allScriptsTimeout, this.cartCount.toString()); return await element(this.cartCount).getText(); } 

干得好!现在从项目的pageobjects文件夹中选择DetailPagePo,并实现以下函数

文件名 说明
getProductName 返回productName元素的文本。
getProductPrice 返回productPrice元素的文本。
addProductToCart 单击addToCartButton
getConfirmationMessage 返回cartConfirmationMessage元素的文本。

在 Python 中,分别对函数名称使用蛇形命名法

最终,DetailPagePo中的函数应如下所示

public String getProductName() { return this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.productName)).getText(); } public String getProductPrice() { return this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.productPrice)).getText(); } public void addProductToCart() { this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.addToCartButton)).click(); } public String getConfirmationMessage() { return this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.cartConfirmationMessage)).getText(); } 
def get_product_name(self): product_name_text = self.wait.until(EC.visibility_of_element_located(self._product_name)).text return product_name_text def get_product_price(self): product_price_text = self.wait.until(EC.visibility_of_element_located(self._product_price)).text return product_price_text def add_product_to_cart(self): self.wait.until(EC.visibility_of_element_located(self._add_to_cart_button)).click() return self def get_confirmation_message(self): cart_confirmation_message_text = self.wait.until(EC.visibility_of_element_located(self._cart_confirmation_message)).text return cart_confirmation_message_text 
public async getProductName(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.productName)), browser.allScriptsTimeout, this.productName.toString()); return await element(this.productName).getText(); } public async getProductPrice(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.productPrice)), browser.allScriptsTimeout, this.productPrice.toString()); return await element(this.productPrice).getText(); } public async addProductToCart(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.addToCartButton)), browser.allScriptsTimeout, this.addToCartButton.toString()); await element(this.addToCartButton).click(); return this; } public async getConfirmationMessage(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.cartConfirmationMessage)), browser.allScriptsTimeout, this.cartConfirmationMessage.toString()); return await element(this.cartConfirmationMessage).getText(); } 

现在,您已准备好自动化测试用例。

编写测试

要创建新的测试文件,请右键单击项目中的tests文件夹,然后从上下文菜单中选择新建 > 测试文件。Sencha WebTestIt 会为您生成一个新类,并等待您为其命名。使用 TypeScript 时,将文件命名为Test1.ts,使用 Java 时,将文件命名为Test1.java。这次,您不为 Python 使用蛇形命名法。您使用驼峰命名法,并将测试文件命名为test1.py

注意

实际的测试文件应编排针对您的网站或应用程序执行的操作。最好将操作本身留在页面对象中,以确保良好的测试可维护性。

每个测试用例中最重要的部分是块末尾的断言。您可以使用它来验证网站或应用程序的行为是否与您的预期行为匹配,因此可以定义测试是失败还是通过。对于元素的断言,有各种可用的断言框架

Sencha WebTestIt 根据您选择的脚本语言为您的项目捆绑了一个断言框架。如果您选择使用 Java 编写测试,则会提供 TestNG 框架。如果您使用 TypeScript,则 Protractor 与Jasmine一起是默认设置。对于 Python 用户,提供了 unittest 环境。但是,您可以切换各个组件。

根据使用的自动化框架和语言,您可以创建上表中描述的三个测试用例。

@Test public void SearchForItemTestCase() { // 1. 安排 // 右键单击并 // 选择底部的“实例化页面对象”来创建一个新的页面对象实例 HeaderPo header = new HeaderPo(driver); DetailPagePo detail = new DetailPagePo(driver); header.open("https://demoshop.webtestit.com"); // 2. 操作 // 从初始化的页面对象调用现有操作 header.insertSearchText("Super"); // 3. 断言 // 使用 TestNG 断言来验证结果。 // 例如: // Assert.assertEquals(title, "Test Automation for GUI Testing | Sencha"); Assert.assertEquals(detail.getProductName(), "Super Cool Goo"); Assert.assertEquals(detail.getProductPrice(), "€1,500.00"); } @Test public void AddItemToCartTestCase() { HeaderPo header = new HeaderPo(driver); DetailPagePo detail = new DetailPagePo(driver); detail.open("https://demoshop.webtestit.com/product/super-cool-goo/"); detail.addProductToCart(); Assert.assertTrue(detail.getConfirmationMessage().contains("“Super Cool Goo” has been added to your cart")); Assert.assertEquals(header.getCartCount(), "1 item"); Assert.assertEquals(header.getCartAmount(), "€1,500.00"); } 
def test_search_for_item(self): driver = self.get_driver() """ 1. 安排 通过右键单击代码编辑器并选择上下文菜单底部的“实例化页面对象”来创建一个新的页面对象实例 """ header = header_po(driver) detail = detail_page_po(driver) header.open("https://demoshop.webtestit.com") """ 2. 操作 从页面对象实例调用现有操作 """ header.insert_search_text("Super") """ 3. 断言 使用 unittest 断言来验证结果。例如: self.assertEqual(title, "Test Automation for GUI Testing | Sencha") """ self.assertEqual(detail.get_product_name(), "Super Cool Goo") self.assertEqual(detail.get_product_price(), "€1,500.00") def test_add_item_to_cart(self): driver = self.get_driver() header = header_po(driver) detail = detail_page_po(driver) detail.open("https://demoshop.webtestit.com/product/super-cool-goo/") detail.add_product_to_cart() self.assertTrue(detail.get_confirmation_message in "“Super Cool Goo” has been added to your cart") self.assertEqual(header.get_cart_count(), "1 item") self.assertEqual(header.get_cart_ammount(), "€1,500.00") 
public async getProductName(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.productName)), browser.allScriptsTimeout, this.productName.toString()); return await element(this.productName).getText(); } public async getProductPrice(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.productPrice)), browser.allScriptsTimeout, this.productPrice.toString()); return await element(this.productPrice).getText(); } public async addProductToCart(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.addToCartButton)), browser.allScriptsTimeout, this.addToCartButton.toString()); await element(this.addToCartButton).click(); return this; } public async getConfirmationMessage(): Promise { await browser.wait(ExpectedConditions.visibilityOf(element(this.cartConfirmationMessage)), browser.allScriptsTimeout, this.cartConfirmationMessage.toString()); return await element(this.cartConfirmationMessage).getText(); } 

您已准备好自动化测试用例。

执行您的测试

最后,是时候验证我们的实验是否有效了。为此,您必须首先创建一个端点。端点是一组有关测试运行时环境的配置。它定义要使用哪个浏览器或哪个操作系统,以及更多内容。

注意

由于 Selenium WebDriver 的JsonWireProtocol,运行时环境实际上可以位于世界任何地方,因为自动化命令通过 HTTP 发送。

我们将创建一个本地 Chrome 端点并在其上执行我们的测试。

  1. 找到执行选项卡

  2. 单击+按钮

  3. 端点对话框中输入以下信息

  4. 单击保存端点

您可以在本指南的第 4 章中了解有关端点的更多信息。

恭喜!

如果您按照本教程中的所有步骤进行操作,则您的测试用例应在没有错误的情况下执行。Sencha WebTestIt 在您的项目中创建了一个名为reports的新文件夹。单击其中的 XML 文件将打开报告选项卡,显示您的运行结果。

您还了解了

  • 如何在 Sencha WebTestIt 中创建页面对象
  • 如何手动创建元素
  • 如何使用拖放快速创建页面对象操作
  • 如何创建端点并执行您的测试

从这里继续

我们创建了一些建议供您阅读

WebTestIt