Web自动化测试预见·软件测试技术专业软件测试之道

预见自动化测试 | 基于 SELENIUM 的自动化测试架构

2018-01-21  本文已影响424人  厲铆兄

基于 SELENIUM 的自动化测试架构

非常感谢各位查阅本篇文章,笔者在此感谢各位。

目前市面上有分门别类的自动化测试工具,这篇文章将讨论开源自动化测试工具 Selenium的使用,以及围绕该工具进行自动化测试的理念、方案以及测试架构的构建。

1. 工具的使用

1.1 Selenium 介绍

Selenium是开源的自动化测试工具,它主要是用于Web 应用程序的自动化测试,不只局限于此,同时支持所有基于web 的管理任务自动化。

Selenium官网的介绍如下:

Selenium is a suite of tools to automate web browsers across many platforms.

  • runs in many browsers and operatingsystems
  • can be controlled by many programming languages and testing frameworks.

Selenium 是用于测试 Web 应用程序用户界面 (UI) 的常用框架。它是一款用于运行端到端功能测试的超强工具。您可以使用多个编程语言编写测试,并且 Selenium 能够在一个或多个浏览器中执行这些测试。

Selenium 经历了三个版本:Selenium 1,Selenium 2 和 Selenium 3。Selenium 也不是简单一个工具,而是由几个工具组成,每个工具都有其特点和应用场景。

Selenium 诞生于 2004 年,当在 ThoughtWorks 工作的 Jason Huggins 在测试一个内部应用时。作为一个聪明的家伙,他意识到相对于每次改动都需要手工进行测试,他的时间应该用得更有价值。他开发了一个可以驱动页面进行交互的 Javascript 库,能让多浏览器自动返回测试结果。那个库最终变成了 Selenium 的核心,它是 Selenium RC(远程控制)和 Selenium IDE 所有功能的基础。Selenium RC 是开拓性的,因为没有其他产品能让你使用自己喜欢的语言来控制浏览器。这就是 Selenium 1。

然而,由于它使用了基于 Javascript 的自动化引擎,而浏览器对 Javascript 又有很多安全限制,有些事情就难以实现。更糟糕的是,网站应用正变得越来越强大,它们使用了新浏览器提供的各种特性,都使得这些限制让人痛苦不堪。

在 2006 年,一名 Google 的工程师, Simon Stewart 开始基于这个项目进行开发,这个项目被命名为 WebDriver。此时,Google 早已是 Selenium 的重度用户,但是测试工程师们不得不绕过它的限制进行工具。Simon 需要一款能通过浏览器和操作系统的本地方法直接和浏览器进行通话的测试工具,来解决Javascript 环境沙箱的问题。WebDriver 项目的目标就是要解决 Selenium 的痛点。

到了 2008 年,Selenium 和 WebDriver 两个项目合并。Selenium 有着丰富的社区和商业支持,但 WebDriver 显然代表着未来的趋势。两者的合并为所有用户提供了一组通用功能,并且借鉴了一些测试自动化领域最闪光的思想。这就是 Selenium 2。

2016 年,Selenium 3 诞生。移除了不再使用的 Selenium 1 中的 Selenium RC,并且官方重写了所有的浏览器驱动。

1.2 Selenium 工具集

1.3 Selenium WebDriver 的使用

接下来的内容,我们将会主要讨论本文的核心重点, Selenium WebDriver 的使用。 Selenium WebDriver 是从 Selenium 2 开始使用并流行, 在 Selenium 3 中得到进一步发展的工具,是当前 Selenium 的最核心的工具。WebDriver 具有清晰面向对象 API,能以最佳的方式与浏览器进行交互。

Selenium WebDriver 就好比是一个懂浏览器的司机,它可以在浏览器的网页上行走,走到网页内容的任何地方,可以参观网页的任何地方,并且和网页进行交互。那么作为测试工程师,如果想和这样的一个司机打交道,就必须要掌握和这样的司机打交道的技能。

Selenium WebDriver 的使用主要分为两个场景:

1.4 Selenium 环境搭建

Selenium 的环境搭建基本上分为三个部分:

  1. 安装编程语言以及IDE(集成编程环境),用来操作 WebDriver
  2. 安装 Selenium WebDriver,实现浏览器的测试
  3. 安装浏览器,和指定的驱动,完成自动化测试的执行

接下来分别用目前市面上主流的 Java 和 Python 环境进行搭建。

1.5 Selenium 编程

通过前面的介绍,我们知道 Selenium 支持多种语言,并且推荐使用面向对象的方式进行编程。接下来我们将着重介绍如何使用面向对象的方式进行编程。

在面向对象的理念看来,任何的编码,都是由对象而来的,这里也不例外。和之前介绍 WebDriver 时候的描述对应,我们需要用到两种主要的类,并将其实例化。

具体的使用如下,以 Java 语言 和 火狐浏览器为例

// 声明 Web司机,司机是一个火狐类的对象
// 需要用 new 关键字来实例化对象, () 代表构造方法
WebDriver driver = new FirefoxDriver();

// Web司机去打开网站
driver.get("http://demo.ranzhi.org");

// 线程停止 3000 毫秒,使得 Web司机有足够的时间打开网址
Thread.sleep(3000);

// 选择 用户名 密码 并依次输入 demo 和 demo (用户名和密码都是 demo)
weAccount = driver.findElement(By.cssSelector("#account"));
weAccount.clear();
weAccount.sendKeys("demo");

wePassword = driver.findElement(By.cssSelector("#password"));
wePassword.clear();
wePassword.sendKeys("demo");

// 选择 登录 按钮,并点击 click
driver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(5000);

上述代码中,使用了一个 WebDriver 类 的对象,即第3行,声明了该类的对象,并赋值给变量 driver,接着变量 driver 作为 WebDriver 类的对象,使用了多个 WebDriver 类的方法。

正是通过这样的面向对象的方式,产生 Web司机(WebDriver类的对象),并且通过 Web司机不懈的努力,寻找到各种 Web元素(WebElement类的对象)进行操作,这样便实现了 Selenium WebDriver 作为一款出色的浏览器测试工具,进行浏览器UI界面的自动化测试的代码编写和用例执行。

上述代码,也同样可是使用 Python 作为编程语言进行操作,如下所示:

# 声明一个司机,司机是个Firefox类的对象
driver = webdriver.Firefox()

# 让司机加载一个网页
driver.get("http://demo.ranzhi.org")

# 给司机3秒钟去打开
sleep(3)

# 开始登录
# 1. 让司机找用户名的输入框
we_account = driver.find_element_by_css_selector('#account')
we_account.clear()
we_account.send_keys("demo")

# 2. 让司机找密码的输入框
we_password = driver.find_element_by_css_selector('#password')
we_password.clear()
we_password.send_keys("demo")

# 3. 让司机找 登录按钮 并 单击
driver.find_element_by_css_selector('#submit').click()
sleep(3)

常用的重点编程对象有如下几种:

2. 理念与方案

在第一部分,工具的使用中,我们重点介绍了 Selenium 工具的编程,但是这样其实对于自动化测试来讲,还远远不够。自动化测试的重点,其实依旧是测试用例的编写和执行,要求代码中,具备测试用例的属性;同时要求测试的代码能够很好的组织起来,通过抽取和分离的理念,实现良好的测试。主要达到以下的几个目的:

接下来的描述,将会对上述的理念依次进行讲解,实现自动化测试的方案。

2.1 使用单元测试框架

在第一部分,我们对 Selenium WebDriver 的使用,仅仅停留在让网页自动的进行操作的阶段,并没有对任何一个步骤进行“检查”。当然,这样没有“检查”的操作,实际上是没有测试意义的。那么第一项,我们需要解决的便是“检查”的问题。

所谓“检查”,实际上就是断言。对需要检查的步骤操作,通过对预先设置的期望值,和执行结果的实际值之间的对比,得到测试的结果。在这里,我们并不需要单独的写 if 语句进行各种判定,而是可以使用编程语言中对应的单元测试框架,即可解决好此类问题。

目前 Java 语言主流的单元测试框架有 JUnit 和 TestNG。Python 语言主流的单元测试框架有 unittest 。本小节的内容,主要介绍 TestNG 和 unittest 的使用,探讨单元测试框架如何帮助自动化测试。

2.2 使用 Page Object 设计模式

Page Object设计模式是Selenium自动化测试项目的最佳设计模式之一,强调测试、逻辑、数据和驱动相互分离。

Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题等),这样在Selenium测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者位置变化时,需要改测试页面代码的情况。当页面元素id变化时,只需要更改测试页Class中页面的属性即可。

它的好处如下:

具体的做法如下:

  1. 创建一个页面的类
  2. 在类的构造方法中,传递 WebDriver 参数。
  3. 在测试用例的类中,实例化页面的类,并且传递在测试用例中已经实例化的WebDriver对象。
  4. 在页面的类中,编写该页面的所有操作的方法
  5. 在测试用例的类中,调用这些方法

实现的示例

2.3 使用数据驱动

主要的数据驱动方式有两种:

通过 CSV 文件 或者 MySQL 数据库,是主流的数据驱动方式。当然数据驱动也可以结合单元测试框架的参数化测试进行编写(此部分本文不做具体描述)。

无论使用了 哪一种(CSV 或者 MySQL),读取数据后都要进行遍历操作。

member.setDept(Integer.parseInt(row.get(3)));
member.setRole(Integer.parseInt(row.get(4)));
member.setPassword(row.get(5));
member.setEmail(row.get(6));
// TODO: 进行测试

}


​

- Python 代码

```python
is_header = True
for row in csv_data:
    if is_header:
        is_header = False
        continue
    # dict 类型的数据
    member_data = {
        "account": row[0],
        "real_name": row[1],
        "gender": row[2],
        "dept": row[3],
        "role": row[4],
        "password": row[5],
        "email": row[6]
    }
    # TODO: 进行测试
    

2.4 封装 Selenium WebDriver

封装是一个面向对象编程的概念,是面向对象编程的核心属性,通过将代码内部实现进行密封和包装,从而简化编程。对Selenium进行封装的好处主要有如下三个方面:

封装的具体示例:

以上的代码是封装了locateElement()的几种方法,在具体使用封装过的代码的时候,只需要简单的调用即可。接下来的重点,是介绍 locateElement(selector)的封装方式。

private WebElement locateElement(String selector) {
  WebElement we;
  // 如果定位符中 有 分隔符,那么就从分隔符处分成两段
  // 第一段是By
  // 第二段是真正的定位符
  // 如果没有分隔符,就默认用 id 定位
  if (!selector.contains(this.byChar)) {
    // 用 id 定位
    we = this.baseDriver.findElement(By.id(selector));
  } else {
    // 用 分隔符 分成两个部分
    String by = selector.split(this.byChar)[0];
    String value = selector.split(this.byChar)[1];
    we = findElementByChar(by, value);
  }
  return we;
}
private WebElement findElementByChar(String by, String value) {
  WebElement we = null;
  switch (by.toLowerCase()) {
    case "id":
    case "i":
      we = this.baseDriver.findElement(By.id(value));
      break;
    case "css_selector":
    case "css":
    case "cssselector":
    case "s":
      we = this.baseDriver.findElement(By.cssSelector(value));
      break;
    case "xpath":
    case "x":
      we = this.baseDriver.findElement(By.xpath(value));
      break;
    case "link_text":
    case "link":
    case "text":
    case "linktext":
    case "l":
      we = this.baseDriver.findElement(By.linkText(value));
      break;
      //TODO: other by type
  }
  return we;
}

使用上面的封装类,就需要指定特定的 selector

类型 示例(分隔符以逗号,为例) 描述
id "account" 或者 "i,account" 或者 "id,account" 分隔符左右两侧不可以空格
xpath "x,//*[@id="s-menu-dashboard"]/button/i"
css selector "s,#s-menu-dashboard > button > i"
link text "l,退出"
partial link text "p,退"
name "n,name1"
tag name "t,input"
class name "c,dock-bottom

调用的具体示例

void logIn(String account, String password) throws InterruptedException {
  BoxDriver driver = this.baseDriver;
  driver.type("account", account);
  driver.type("password", password);
  driver.click("submit");
  // 点击登录按钮后,需要等待浏览器刷新
  Thread.sleep(2000);
}

至此,自动化测试的方案如下图所示:

自动化测试模型.png
  1. 封装 Selenium 为 BoxDriver
  2. 在 测试用例中,实例化 BoxDriver,产生 bd 对象
  3. 使用 bd 对象,构造 业务模块的实例化对象,产生 common
  4. 使用 common 在测试用例中,构建测试步骤
  5. 使用数据驱动的外部数据,通过读取,进行测试
  6. 执行整个用例

2.5 使用 Git 进行源代码管理

Git 是目前主流的源代码管理工具,本文推荐的两个 IDE 工具: JetBrains IDEA 和 JetBrains Pycharm 都是默认支持 Git 的。只需要按照以下步骤进行配置,便可以通过 IDE 工具对代码进行提交,这样可以防止代码丢失,以及方便的查询代码的修改历史,同时很方便团队的编码。

使用编程工具提交代码(用IDEA 或者 PyCharm)

  1. 在本地的Git项目文件夹中创建项目
    • 比如:git\selenium_pro
    • 用IDEA 创建 Maven项目
      • 注意 project location务必在 git\selenium_pro
      • 比如 项目名字 HelloSelenium
      • 项目路径:git\selenium_pro\HelloSelenium
  2. 编写 代码
  3. 选择 IDEA 的 VCS | Enable Version Control Integration
  4. 弹出的窗口选择 Git
    • 所有的代码文件名字变成红色
  5. 右键 左侧的项目名字 HelloSelenium
    • 选择 Git | Add
    • 所有的代码文件名字变成绿色
  6. 右键 左侧的项目名字 HelloSelenium
    • 选择 Git | Commit Directory
    • 左侧填写 说明
    • 右侧勾选 Reformat Code
    • 选择右下角 Commit And Push
    • "XX文件已经committed"以后,点击 Push
    • 输入用户名 + 密码,勾选 remember password
    • push successful

3. 架构的构建

将第二部分的自动化测试方案付诸实践,再对自动化测试的结果生成测试报告,便基本上实现了自动化架构的构建。比较重要的地方是第三方工具 Selenium WebDriver 的封装工作。事实上,如果封装了别的工具,便可以实现其他方面的自动化测试。

3.1 代码的构建

在第二部分的基础上,我们添加上去测试组织和测试报告的功能,并且将不同作用的代码分开放入不同的文件夹中,实现代码的构建。

上一篇下一篇

猜你喜欢

热点阅读